From 9f0bc0fdf1f6353e385b98064638e4c1528b0359 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Sat, 12 Jul 2014 22:34:46 -0700 Subject: [PATCH 01/93] Starting to implement the proposed PACF API. --- scripts/base/frameworks/pacf/__load__.bro | 3 + scripts/base/frameworks/pacf/main.bro | 477 ++++++++++++++++++ scripts/base/frameworks/pacf/plugin.bro | 91 ++++ .../base/frameworks/pacf/plugins/__load__.bro | 1 + .../base/frameworks/pacf/plugins/debug.bro | 119 +++++ scripts/base/frameworks/pacf/types.bro | 122 +++++ scripts/base/init-bare.bro | 12 + scripts/base/init-default.bro | 1 + src/bro.bif | 13 + 9 files changed, 839 insertions(+) create mode 100644 scripts/base/frameworks/pacf/__load__.bro create mode 100644 scripts/base/frameworks/pacf/main.bro create mode 100644 scripts/base/frameworks/pacf/plugin.bro create mode 100644 scripts/base/frameworks/pacf/plugins/__load__.bro create mode 100644 scripts/base/frameworks/pacf/plugins/debug.bro create mode 100644 scripts/base/frameworks/pacf/types.bro diff --git a/scripts/base/frameworks/pacf/__load__.bro b/scripts/base/frameworks/pacf/__load__.bro new file mode 100644 index 0000000000..e2c97f6959 --- /dev/null +++ b/scripts/base/frameworks/pacf/__load__.bro @@ -0,0 +1,3 @@ +@load ./types +@load ./main +@load ./plugins diff --git a/scripts/base/frameworks/pacf/main.bro b/scripts/base/frameworks/pacf/main.bro new file mode 100644 index 0000000000..0e0d930fce --- /dev/null +++ b/scripts/base/frameworks/pacf/main.bro @@ -0,0 +1,477 @@ +##! 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 evyerthing 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 API: a high-level and low-level. The high-levem API +##! provides convinience functions for a set of common operations. The +##! low-level API provides full flexibility. + +module Pacf; + +@load ./plugin +@load ./types + +export { + ## The framework's logging stream identifier. + redef enum Log::ID += { LOG }; + + # ### + # ### Generic functions. + # ### + + # Activates a plugin. + # + # plugin: 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); + + # ### + # ### High-level API. + # ### + + ## 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: True if a plugin accepted the rule for carrying it out. + global drop_address: function(a: addr, t: interval, location: string &default="") : bool; + + ## 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: True if a plugin accepted the rule for carrying it out. + global shunt_flow: function(f: flow_id, t: interval, location: string &default="") : bool; + + ## Removes all rules and notifications for an entity. + ## + ## e: The entity. Note that this will be directly to entities of existing + ## notifications and notifications, which must match exactly field by field. + global reset: function(e: Entity); + + ## 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 ity 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; + + ###### Asynchronous feedback on rules. + + ## Confirms that a rule was put in place. + ## + ## r: The rule now in place. + ## + ## plugin: The name of 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. + ## + ## plugin: The name of 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. + ## + ## plugin: The name of 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, p: PluginState); + + ## Reports an error when operating on a rule. + ## + ## r: The rule that encountered an error. + ## + ## plugin: The name of 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=""); + + ## Installs a notification. + ## + ## n: The notification to install. + ## + ## Returns: If succesful, returns an ID string unique to the notification 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 notification", 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_notification: function(n: Notification) : string; + + ## Removes a notification. + ## + ## id: The notification to remove, specified as the ID returned by :bro:id:`add_notification` . + ## + ## Returns: True if succesful, the relevant plugin indicated that ity 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_notification: function(id: string) : bool; + + ###### Asynchronous feedback on notifications. + + ## Confirms that a notification was put in place. + ## + ## n: The notification now in place. + ## + ## plugin: The name of the plugin that put it into place. + ## + ## msg: An optional informational message by the plugin. + global notification_added: event(n: Notification, p: PluginState, msg: string &default=""); + + ## Reports that a notification was removed due to a remove: function() call. + ## + ## n: The notification now removed. + ## + ## plugin: The name of the plugin that had the notification in place and now + ## removed it. + ## + ## msg: An optional informational message by the plugin. + global notification_removed: event(n: Notification, p: PluginState, msg: string &default=""); + + ## Reports that a notification was removed internally due to a timeout. + ## + ## n: The notification now removed. + ## + ## plugin: The name of the plugin that had the notification in place and now + ## removed it. + ## + ## msg: An optional informational message by the plugin. + global notification_timeout: event(n: Notification, p: PluginState); + + ## Reports an error when operating on a notification. + ## + ## n: The notification that encountered an error. + ## + ## plugin: The name of the plugin that reported the error. + ## + ## msg: An optional informational message by the plugin. + global notification_error: event(n: Notification, p: PluginState, msg: string &default=""); + + ## Type of an entry in the PACF 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, + ## A log entry about about a notification. + NOTIFICATION + }; + + ## State of an entry in the PACF log. + type InfoState: enum { + REQUESTED, + SUCCEEDED, + FAILED, + REMOVED, + TIMEOUT, + }; + + ## The record type which contains column fields of the PACF log. + type Info: record { + ## Time at which the recorded activity occurred. + ts: time &log; + ## 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 with an additional message. + msg: string &log &optional; + ## Logcation where the underlying action was triggered. + location: string &log &optional; + ## Plugin triggering the log entry. + plugin: string &log &optional; + }; +} + +redef record Rule += { + ##< Internally set to the plugin handling the rule. + _plugin: PluginState &optional; +}; + +global plugins: vector of PluginState; +global rule_counter: count = 0; +global rules: table[string] of Rule; + +event bro_init() &priority=5 + { + Log::create_stream(Pacf::LOG, [$columns=Info]); + } + +function entity_to_info(info: Info, e: Entity) + { + info$entity_type = fmt("%s", e$ty); + + switch ( e$ty ) { + case ADDRESS, ORIGINATOR, RESPONDER: + 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: + info$entity = fmt("%s/%d->%s/%d", + e$flow$src_h, e$flow$src_p, + e$flow$dst_h, e$flow$dst_p); + 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; + + if ( r?$location ) + info$location = r$location; + + 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_rule(r: Rule, cmd: string, state: InfoState, p: PluginState) + { + local info: Info = [$ts=network_time()]; + info$category = RULE; + info$cmd = cmd; + info$state = state; + info$plugin = p$plugin$name(p); + + 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 activate(p: PluginState, priority: int) + { + p$_priority = priority; + plugins[|plugins|] = p; + sort(plugins, function(p1: PluginState, p2: PluginState) : int { return p2$_priority - p1$_priority; }); + + log_msg(fmt("activated plugin with priority %d", priority), p); + } + +function drop_address(a: addr, t: interval, location: string &default="") : bool + { + 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); + return |id| > 0; + } + +function shunt_flow(f: flow_id, t: interval, location: string &default="") : bool + { + local e: Entity = [$ty=FLOW, $flow=f]; + local r: Rule = [$ty=DROP, $target=MONITOR, $entity=e, $expire=t, $location=location]; + + local id = add_rule(r); + return |id| > 0; + } + +function reset(e: Entity) + { + print "Pacf::reset not implemented yet"; + } + +function clear() + { + print "Pacf::clear not implemented yet"; + } + +function add_rule(r: Rule) : string + { + r$id = fmt("%d", ++rule_counter); + + for ( i in plugins ) + { + local p = plugins[i]; + + if ( p$plugin$add_rule(p, r) ) + { + r$_plugin = p; + log_rule(r, "ADD", REQUESTED, p); + return r$id; + } + } + + log_rule_no_plugin(r, FAILED, "not supported"); + } + +function remove_rule(id: string) : bool + { + local r = rules[id]; + local p = r$_plugin; + + if ( ! p$plugin$remove_rule(r$_plugin, r) ) + { + log_rule_error(r, "remove failed", p); + return F; + } + + log_rule(r, "REMOVE", REQUESTED, p); + return T; + } + +event rule_expire(r: Rule, p: PluginState) + { + if ( r$id !in rules ) + # Remove already. + return; + + event rule_timeout(r, p); + remove_rule(r$id); + } + +event rule_added(r: Rule, p: PluginState, msg: string &default="") + { + log_rule(r, "ADD", SUCCEEDED, p); + + rules[r$id] = r; + + if ( r?$expire && ! p$plugin$can_expire ) + schedule r$expire { rule_expire(r, p) }; + } + +event rule_removed(r: Rule, p: PluginState, msg: string &default="") + { + delete rules[r$id]; + log_rule(r, "REMOVE", SUCCEEDED, p); + } + +event rule_timeout(r: Rule, p: PluginState) + { + delete rules[r$id]; + log_rule(r, "EXPIRE", TIMEOUT, p); + } + +event rule_error(r: Rule, p: PluginState, msg: string &default="") + { + log_rule_error(r, msg, p); + } + +function add_notification(n: Notification) : string + { + print "Pacf::add_notification not implemented yet"; + } + +function remove_notification(id: string) : bool + { + print "Pacf::remove_notification not implemented yet"; + } + +event notification_added(n: Notification, p: PluginState, msg: string &default="") + { + } + +event notification_removed(n: Notification, p: PluginState, msg: string &default="") + { + } + +event notification_timeout(n: Notification, p: PluginState) + { + } + +event notification_error(n: Notification, p: PluginState, msg: string &default="") + { + } + + diff --git a/scripts/base/frameworks/pacf/plugin.bro b/scripts/base/frameworks/pacf/plugin.bro new file mode 100644 index 0000000000..944705605f --- /dev/null +++ b/scripts/base/frameworks/pacf/plugin.bro @@ -0,0 +1,91 @@ + +module Pacf; + +@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(); + + ## Set internally. + _priority: int &default=+0; + }; + + # Definitioan 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 informn 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. The same applies to notifications, + # with the corresponding ``notification_*`` events. + 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/notifications itself. If false, + ## framework will manage rule expiration. + can_expire: bool; + + # One-time initialization functionl called when plugin gets registered, and + # befire any ther methods are called. + 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; + + # Implements the add_notification() operation. If the plugin accepts the notification, + # it returns true, false otherwise. The notification will already have its + # ``id`` field set, which the plugin may use for identification + # purposes. + add_notification: function(state: PluginState, r: Notification) : bool &optional; + + # Implements the remove_notification() operation. This will only be called for + # notifications that the plugins has previously accepted with add_notification(). + # The ``id`` field will match that of the add_notification() call. Generally, + # a plugin that accepts an add_notification() should also accept the + # remove_notification(). + remove_notification: function(state: PluginState, r: Notification) : 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/pacf/plugins/__load__.bro b/scripts/base/frameworks/pacf/plugins/__load__.bro new file mode 100644 index 0000000000..0b76aa2b74 --- /dev/null +++ b/scripts/base/frameworks/pacf/plugins/__load__.bro @@ -0,0 +1 @@ +@load ./debug diff --git a/scripts/base/frameworks/pacf/plugins/debug.bro b/scripts/base/frameworks/pacf/plugins/debug.bro new file mode 100644 index 0000000000..09fb87ef3f --- /dev/null +++ b/scripts/base/frameworks/pacf/plugins/debug.bro @@ -0,0 +1,119 @@ + +@load ../plugin + +module Pacf; + +export { + ## Instantiates a debug plugin for the PACF 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("pacf debug (%s): %s", debug_name(p), msg); + } + +function debug_init(p: PluginState) + { + debug_log(p, "init"); + } + +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 Pacf::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 Pacf::rule_removed(r, p); + return T; + } + +function debug_add_notification(p: PluginState, r: Notification) : bool + { + local s = fmt("add_notification: %s", r); + debug_log(p, s); + + if ( do_something(p) ) + { + event Pacf::notification_added(r, p); + return T; + } + + return F; + } + +function debug_remove_notification(p: PluginState, r: Notification) : bool + { + local s = fmt("remove_notification: %s", r); + debug_log(p, s); + + return do_something(p); + } + +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, + $add_notification = debug_add_notification, + $remove_notification = debug_remove_notification, + $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/pacf/types.bro b/scripts/base/frameworks/pacf/types.bro new file mode 100644 index 0000000000..8e3a3b999d --- /dev/null +++ b/scripts/base/frameworks/pacf/types.bro @@ -0,0 +1,122 @@ + +module Pacf; + +export { + ## Type of a :bro:id:`Entity` for defining an action. + type EntityType: enum { + ADDRESS, ##< Activity involving a specific IP address. + ORIGINATOR, ##< Activity *from* a source IP address. + RESPONDER, ##< Activity *to* a destination IP address. + CONNECTION, ##< All of a bi-directional connection's activity. + FLOW, ##< All of a uni-directional flow's activity. + MAC, ##< Activity involving a 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_id &optional; ##< Used with :bro:id:`FLOW` . + ip: subnet &optional; ##< Used with :bro:id:`ORIGINATOR`/:bro:id:`RESPONDER`/: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 rate-limiting flows matching entity. + ## + ## d: Percent of available bandwidth. + LIMIT, + + ## Begin modifying all packets matching entity. + ## + ## .. todo:: + ## Define arguments. + MODIFY, + + ## Begin redirecting all packets matching entity. + ## + ## .. todo:: + ## Define arguments. + REDIRECT, + + ## Begin sampling all flows matching entity. + ## + ## d: Probability to include a flow between 0 and 1. + SAMPLE, + + ## 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, + }; + + ## 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 riles 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=+0; ##< Priority if multiple rules match an entity (larger value is higher priority). + location: string &optional; ##< Optional string describing where/what installed the rule. + + i: int &optional; ##< Argument for rule types requiring an integer argument. + d: double &optional; ##< Argument for rule types requiring a double argument. + s: string &optional; ##< Argument for rule types requiring a string argument. + + id: string &default=""; ##< Internally determined unique ID for this rule. Will be set when added. + }; + + ## Type of notifications that the framework supports. Each type lists the + ## :bro:id:`Notification` argument(s) it uses, if any. + ## + ## Plugins may extend this type to define their own. + type NotificationType: enum { + ## Notify if threshold of packets has been reached by entity. + ## + ## i: Number of packets. + NUM_PACKETS, + + ## Notify if threshold of bytes has been reached by entity. + ## + ## i: Number of bytes. + NUM_BYTES, + }; + + ## A notification for the framework to raise when a condition has been reached. + ## Different than with rules, all matching conditions will be reported, not only + ## the first match. + type Notification: record { + ty: NotificationType; ##< Type of notification. + entity: Entity; ##< Entity to apply notification to. + expire: interval &optional; ##< Timeout after which to expire the notification. + src: string &optional; ##< Optional string describing where/what installed the notification. + + i: int; ##< Argument for notification types requiring an integer argument. + d: double; ##< Argument for notification types requiring a double argument. + s: string; ##< Argument for notification types requiring a string argument. + + id: string &default=""; ##< Internally determined unique ID for this notification. Will be set when added. + }; +} + + + + diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 65d15dc2cf..a173277f56 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -113,6 +113,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. +}; + ## 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 610d205618..d999411944 100644 --- a/scripts/base/init-default.bro +++ b/scripts/base/init-default.bro @@ -37,6 +37,7 @@ @load base/frameworks/reporter @load base/frameworks/sumstats @load base/frameworks/tunnels +@load base/frameworks/pacf @load base/protocols/conn @load base/protocols/dhcp diff --git a/src/bro.bif b/src/bro.bif index 1029896295..fae364b331 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -2343,6 +2343,19 @@ 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 *sn* string 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:`string` to a :bro:type:`double`. ## ## str: The :bro:type:`string` to convert. From 5555757b2d5fd6d414d0079476bb3bcd03687432 Mon Sep 17 00:00:00 2001 From: Christian Struck Date: Mon, 20 Oct 2014 17:05:13 -0700 Subject: [PATCH 02/93] Simple test sciprt that uses a RYU controller with its restAPI and shunts a flow after a specified amount of traffic --- scripts/site/openflow-shunt.bro | 65 +++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 scripts/site/openflow-shunt.bro diff --git a/scripts/site/openflow-shunt.bro b/scripts/site/openflow-shunt.bro new file mode 100644 index 0000000000..ecb14815d3 --- /dev/null +++ b/scripts/site/openflow-shunt.bro @@ -0,0 +1,65 @@ +@load base/protocols/conn +@load base/frameworks/notice +@load base/frameworks/openflow + +module OpenflowShunt; + +# pox +# global param_dpid = "00-24-a8-5c-0c-00|15" &redef; +# global param_port = "\"OFPP_ALL\"" &redef; +# global of_ctrl_uri = "http://10.255.0.20:8080/OF/" &redef; +# const cmd = "curl -i -X POST -d '{\"method\":\"set_table\",\"params\":{\"dpid\":\"%s\",\"flows\":[{\"actions\":[{\"type\":\"OFPAT_OUTPUT\",\"port\":%s}],\"match\":{%s}}]}}' %s"; + + +# default constants which are not automatically gathered. +const dpid = 4222282094087168; +const cookie = 0; +const idle_timeout = 30; +const hard_timeout = 0; +const in_port = 3; +const out_port = 1; + +export { + ## Number of bytes transferred before shunting a flow. + const size_threshold = 1024000 &redef; + + ## Base amount of time between checking + const poll_interval = 1sec &redef; + + ## Raised when a shunt happened. + ## + ## c: The connection pertaining to the data channel. + global shunt_triggered: event(c: connection); +} + +function size_callback(c: connection, cnt: count): interval { + print fmt("%s:%s <-> %s:%s reached %s/%s", c$id$orig_h, port_to_count(c$id$orig_p), c$id$resp_h, port_to_count(c$id$resp_p), c$orig$num_bytes_ip + c$resp$num_bytes_ip, size_threshold); + if ( c$orig$num_bytes_ip + c$resp$num_bytes_ip >= size_threshold ) { + local actions: vector of Openflow::ofp_action_output; + actions[|actions|] = Openflow::ofp_action_output($_port=out_port); + + local nw_proto = Openflow::IP_TCP; + if(is_udp_port(c$id$orig_p)) { + nw_proto = Openflow::IP_UDP; + } else if(is_icmp_port(c$id$orig_p)) { + nw_proto = Openflow::IP_ICMP; + } + local match: Openflow::ofp_match = [$in_port=in_port, $nw_src=c$id$orig_h, $nw_dst=c$id$resp_h, $nw_proto=nw_proto, $tp_src=c$id$orig_p, $tp_dst=c$id$resp_p]; + + # print fmt(cmd, param_dpid, param_port, "",of_ctrl_uri); + when ( local result = Openflow::flow_mod(dpid, cookie, idle_timeout, hard_timeout, actions, match) ) { + if(result) { + event OpenflowShunt::shunt_triggered(c); + } + } + + return -1sec; + } + + return poll_interval; +} + +event connection_established(c: connection) { + print fmt("new connection"); + ConnPolling::watch(c, size_callback, 0, 0secs); +} \ No newline at end of file From d426f36ebe207d478ca1d23280248bed38c4ee7a Mon Sep 17 00:00:00 2001 From: Christian Struck Date: Mon, 20 Oct 2014 17:09:44 -0700 Subject: [PATCH 03/93] Small openflow api, that provides functionality to add flows. --- scripts/base/frameworks/openflow/__load__.bro | 2 + scripts/base/frameworks/openflow/main.bro | 182 ++++++++++++++++++ 2 files changed, 184 insertions(+) create mode 100644 scripts/base/frameworks/openflow/__load__.bro create mode 100644 scripts/base/frameworks/openflow/main.bro diff --git a/scripts/base/frameworks/openflow/__load__.bro b/scripts/base/frameworks/openflow/__load__.bro new file mode 100644 index 0000000000..c468d055ee --- /dev/null +++ b/scripts/base/frameworks/openflow/__load__.bro @@ -0,0 +1,2 @@ +@load ./main +@load ./plugins \ No newline at end of file diff --git a/scripts/base/frameworks/openflow/main.bro b/scripts/base/frameworks/openflow/main.bro new file mode 100644 index 0000000000..f1f69ce613 --- /dev/null +++ b/scripts/base/frameworks/openflow/main.bro @@ -0,0 +1,182 @@ +@load ./utils/const.bro + +module Openflow; + +export { +# ofp_port: enum { + # Maximum number of physical switch ports. + const OFPP_MAX = 0xff00; + ######################## + # Fake output "ports". # + ######################## + # 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 = 0xfff8; + # Perform actions in flow table. + # NB: This can only be the destination port + # for packet-out messages. + const OFPP_TABLE = 0xfff9; + # Process with normal L2/L3 switching. + const OFPP_NORMAL = 0xfffa; + # All pysical ports except input port and + # those disabled by STP. + const OFPP_FLOOD = 0xfffb; + # All pysical ports except input port. + const OFPP_ALL = 0xfffc; + # Send to controller. + const OFPP_CONTROLLER = 0xfffd; + # Local openflow "port". + const OFPP_LOCAL = 0xfffe; + # Not associated with a pysical port. + const OFPP_NONE = 0xffff; +# } + 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, + OFPAT_VENDOR = 0xffff, + }; + + type ofp_flow_mod_command: enum { + # New flow. + OFPFC_ADD, + # Modify all matching flows. + OFPFC_MODIFY, + # Modify entry strictly matching wildcards. + OFPFC_MODIFY_STRICT, + # Delete all matching flows. + OFPFC_DELETE, + # Strictly matching wildcards and priority. + OFPFC_DELETE_STRICT, + }; + + 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, + }; + + type ofp_match: record { + # Wildcard fields. + wildcards: count &optional; + # 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 &default=ETH_IPv4; + # IP ToS (actually DSCP field, 6bits). + nw_tos: count &optional; + # IP protocol or lower 8 bits of ARP opcode. + nw_proto: count &default=IP_TCP; + # IP source address. + nw_src: addr &optional; + # IP destination address. + nw_dst: addr &optional; + # TCP/UDP source port. + tp_src: port &optional; + # TCP/UDP destination port. + tp_dst: port &optional; + }; + + type ofp_action_output: record { + _type: ofp_action_type &default=OFPAT_OUTPUT; + _len: count &default=8; + _port: count &default=OFPP_FLOOD; + _max_len: count &optional; + }; + +# TODO: +# type ofp_flow_mod: record { +# header: ofp_header; +# # Fields to match +# match: ofp_match; +# # Opaque controller-issued identifier. +# cookie: count &optional; +# +# # Flow actions +# +# # One of OFPFC_*. +# command: #TBD +# # Idle time befor discarding (seconds). +# idle_timeout: count &optional; +# # Max time before discarding (seconds). +# hard_timeout: count &optional; +# # Priority level of flow entry. +# priority: count &optional; +# # Buffered packet to apply to (or -1). +# # Not meaningful for OFPFC_DELETE*. +# buffer_id: count &optional; +# # For OFPFC_DELETE* commands, require +# # matching entries to include this as an +# # output port. A value of OFPP_NONE +# # indicates no restrictions +# out_port: count &optional; +# # One of OFPFF_*. +# flags: count &optional; +# +# actions: vector of ofp_action_header; +# }; + + global flow_mod: function( + dpid: count, cookie: count, idle_timeout: count, hard_timeout: count, + actions: vector of ofp_action_output, match: ofp_match): bool; +} + +# Flow Modification function prototype +type FlowModFunc: function( + dpid: count, cookie: count, idle_timeout:count, hard_timeout: count, + actions: vector of ofp_action_output, match: ofp_match): bool; + +# Flow Modification function +global FlowMod: FlowModFunc; + +# Hook for registering openflow plugins +global register_openflow_plugin: hook(); + +function register_openflow_mod_func(func: FlowModFunc) { + FlowMod = func; +} + +function flow_mod( + dpid: count, cookie: count, idle_timeout:count, hard_timeout:count, + actions: vector of ofp_action_output, match: ofp_match): bool { + return FlowMod(dpid, cookie, idle_timeout, hard_timeout, actions, match); +} + +event bro_init() &priority=100000 { + # Call all of the plugin registration hooks + hook register_openflow_plugin(); +} From 676207e968b223ebf5913cd0741746bab44b2a22 Mon Sep 17 00:00:00 2001 From: Christian Struck Date: Mon, 20 Oct 2014 17:10:49 -0700 Subject: [PATCH 04/93] Small implementation of the RYU restAPI functionality to add flows. --- .../frameworks/openflow/plugins/__load__.bro | 1 + .../base/frameworks/openflow/plugins/ryu.bro | 83 +++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 scripts/base/frameworks/openflow/plugins/__load__.bro create mode 100644 scripts/base/frameworks/openflow/plugins/ryu.bro diff --git a/scripts/base/frameworks/openflow/plugins/__load__.bro b/scripts/base/frameworks/openflow/plugins/__load__.bro new file mode 100644 index 0000000000..c45aa9544e --- /dev/null +++ b/scripts/base/frameworks/openflow/plugins/__load__.bro @@ -0,0 +1 @@ +@load ./ryu \ No newline at end of file diff --git a/scripts/base/frameworks/openflow/plugins/ryu.bro b/scripts/base/frameworks/openflow/plugins/ryu.bro new file mode 100644 index 0000000000..745dcb4e04 --- /dev/null +++ b/scripts/base/frameworks/openflow/plugins/ryu.bro @@ -0,0 +1,83 @@ +@load ../main +@load ../utils/json +@load base/utils/exec +@load base/utils/active-http + +module Openflow; + +export { + const controller_uri = "http://10.255.0.20:8080/stats/flowentry/add" &redef; +} + +type ryu_flow_action_output: record { + # The type should be never changed... + # but constants are not possible in a record. + _type: string &default="OUTPUT"; + # The output port + _port: count; +}; + +# The restAPI documentation can be found at +# https://media.readthedocs.org/pdf/ryu/latest/ryu.pdf +# on page 278-299 +type ryu_flow_add: 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; + buffer_id: count &optional; + flags: count &optional; + match: Openflow::ofp_match; + actions: vector of ryu_flow_action_output; +}; + +# register the ryu openflow plugin flow_mod function +hook register_openflow_plugin() { + register_openflow_mod_func( + function( + dpid: count, cookie: count, idle_timeout: count, hard_timeout: count, + actions: vector of ofp_action_output, match: ofp_match): bool { + local ryu_flow_actions: vector of ryu_flow_action_output; + for(i in actions) { + if(actions[i]$_type == Openflow::OFPAT_OUTPUT) { + ryu_flow_actions[|ryu_flow_actions|] = ryu_flow_action_output($_port=actions[i]$_port); + } + } + # Generate our record for the restAPI. + local ryu_flow_mod: ryu_flow_add = ryu_flow_add($dpid=dpid, $cookie=cookie, $idle_timeout=idle_timeout, $hard_timeout=hard_timeout, $match=match, $actions=ryu_flow_actions); + # Create the ActiveHTTP request and convert the record to a JSON string + local request: ActiveHTTP::Request = ActiveHTTP::Request($url=controller_uri, $method="POST", $client_data=JSON::convert(ryu_flow_mod)); + # Execute call to RyuRestAPI + when(local result = ActiveHTTP::request(request)) { + if(result$code == 200) { + print fmt("Flow %s:%s -> %s:%s removed from monitor", match$nw_src, match$tp_src, match$nw_dst, match$tp_dst); + } else { + print fmt("Error: could no add shunt flow, restAPI returned:\n%s", result); + return F; + } + } + + # Add reverse flow because openflow only uses unidirectional flows. + if(|actions| == 1 && (match$dl_type == ETH_IPv4 || match$dl_type == ETH_IPv6)) { + local reverse_match: ofp_match; + local reverse_actions: vector of ryu_flow_action_output; + reverse_actions[|reverse_actions|] = ryu_flow_action_output($_port=match$in_port); + reverse_match = ofp_match($in_port=actions[0]$_port, $dl_type=match$dl_type, $nw_proto=match$nw_proto, $nw_src=match$nw_dst, $nw_dst=match$nw_src, $tp_src=match$tp_dst, $tp_dst=match$tp_src); + local reverse_flow_mod: ryu_flow_add = ryu_flow_add($dpid=dpid, $cookie=cookie, $idle_timeout=idle_timeout, $hard_timeout=hard_timeout, $match=reverse_match, $actions=reverse_actions); + local reverse_request: ActiveHTTP::Request = ActiveHTTP::Request($url=controller_uri, $method="POST", $addl_curl_args=fmt("-d '%s'", JSON::convert(reverse_flow_mod))); + when(local result2 = ActiveHTTP::request(reverse_request)) { + if(result2$code == 200) { + print fmt("Flow %s:%s -> %s:%s removed from monitor", reverse_match$nw_src, reverse_match$tp_src, reverse_match$nw_dst, reverse_match$tp_dst); + } else { + print fmt("Error: could no add shunt flow, restAPI returned:\n%s", result2); + return F; + } + } + } + return T; + } + ); +} From 6c2a8cdff43d862c3f23cd295782e67c743308ae Mon Sep 17 00:00:00 2001 From: Christian Struck Date: Mon, 20 Oct 2014 17:13:01 -0700 Subject: [PATCH 05/93] Seth's *any type* to JSON converter, slightly changed --- .../base/frameworks/openflow/utils/const.bro | 104 +++++++++++++++++ .../base/frameworks/openflow/utils/json.bro | 108 ++++++++++++++++++ 2 files changed, 212 insertions(+) create mode 100644 scripts/base/frameworks/openflow/utils/const.bro create mode 100644 scripts/base/frameworks/openflow/utils/json.bro diff --git a/scripts/base/frameworks/openflow/utils/const.bro b/scripts/base/frameworks/openflow/utils/const.bro new file mode 100644 index 0000000000..18c79eb28e --- /dev/null +++ b/scripts/base/frameworks/openflow/utils/const.bro @@ -0,0 +1,104 @@ +# All types/constants not specific to Openflow will be defined here +# unitl they somehow get into bro. + +module Openflow; + +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; +#}; +} \ No newline at end of file diff --git a/scripts/base/frameworks/openflow/utils/json.bro b/scripts/base/frameworks/openflow/utils/json.bro new file mode 100644 index 0000000000..c482314698 --- /dev/null +++ b/scripts/base/frameworks/openflow/utils/json.bro @@ -0,0 +1,108 @@ +@load base/utils/strings + +module JSON; + +export { + ## 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. + global convert: function(v: any, only_loggable: bool &default=F, field_escape_pattern: pattern &default=/^_/): string; +} + +function convert(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": + 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, "\": ", JSON::convert(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|] = JSON::convert(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 = JSON::convert(ti); + local if_quotes = (ts[0] == "\"") ? "" : "\""; + tab_parts[|tab_parts|] = cat(if_quotes, ts, if_quotes, ": ", JSON::convert(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|] = JSON::convert(va[vi], only_loggable); + } + return cat("[", join_string_vec(vec_parts, ", "), "]"); + } + + return "\"\""; + } \ No newline at end of file From bf6dc12be467b5d1d64d95b840c66dd5aa5e7f91 Mon Sep 17 00:00:00 2001 From: Christian Struck Date: Thu, 23 Oct 2014 18:20:40 -0700 Subject: [PATCH 06/93] [ADD] the possibility to remove flows and refactored the flow_mod function to fit the new capabilities. Also started to comment more of the code --- scripts/base/frameworks/openflow/main.bro | 96 ++++++++------- .../base/frameworks/openflow/plugins/ryu.bro | 115 ++++++++++++++---- scripts/site/openflow-shunt.bro | 49 +++++++- 3 files changed, 185 insertions(+), 75 deletions(-) diff --git a/scripts/base/frameworks/openflow/main.bro b/scripts/base/frameworks/openflow/main.bro index f1f69ce613..11152d2b67 100644 --- a/scripts/base/frameworks/openflow/main.bro +++ b/scripts/base/frameworks/openflow/main.bro @@ -84,7 +84,7 @@ export { type ofp_match: record { # Wildcard fields. - wildcards: count &optional; + #wildcards: count &optional; # Input switch port. in_port: count &optional; # Ethernet source address. @@ -112,53 +112,63 @@ export { }; type ofp_action_output: record { + # this should never change, but there are not + # constants available in records + # defaults to OFPAT_OUTPUT _type: ofp_action_type &default=OFPAT_OUTPUT; - _len: count &default=8; + #_len: count &default=8; + # Output port. _port: count &default=OFPP_FLOOD; - _max_len: count &optional; + #_max_len: count &optional; }; -# TODO: -# type ofp_flow_mod: record { -# header: ofp_header; -# # Fields to match -# match: ofp_match; -# # Opaque controller-issued identifier. -# cookie: count &optional; -# -# # Flow actions -# -# # One of OFPFC_*. -# command: #TBD -# # Idle time befor discarding (seconds). -# idle_timeout: count &optional; -# # Max time before discarding (seconds). -# hard_timeout: count &optional; -# # Priority level of flow entry. -# priority: count &optional; -# # Buffered packet to apply to (or -1). -# # Not meaningful for OFPFC_DELETE*. -# buffer_id: count &optional; -# # For OFPFC_DELETE* commands, require -# # matching entries to include this as an -# # output port. A value of OFPP_NONE -# # indicates no restrictions -# out_port: count &optional; -# # One of OFPFF_*. -# flags: count &optional; -# -# actions: vector of ofp_action_header; -# }; +#type ofp_flow_mod_flags: enum { + # 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; +#}; - global flow_mod: function( - dpid: count, cookie: count, idle_timeout: count, hard_timeout: count, - actions: vector of ofp_action_output, match: ofp_match): bool; + type ofp_flow_mod: record { + # header: ofp_header; + # Fields to match + match: ofp_match; + # Opaque controller-issued identifier. + cookie: count &optional; + + # Flow actions + + # One of OFPFC_*. + command: ofp_flow_mod_command &default=OFPFC_ADD; + # Idle time befor discarding (seconds). + idle_timeout: count &optional; + # Max time before discarding (seconds). + hard_timeout: count &optional; + # Priority level of flow entry. + priority: count &optional; + # Buffered packet to apply to (or -1). + # Not meaningful for OFPFC_DELETE*. + buffer_id: count &optional; + # For OFPFC_DELETE* commands, require + # matching entries to include this as an + # output port. A value of OFPP_NONE + # indicates no restrictions + out_port: count &optional; + # One of OFPFF_*. + flags: count &optional; + actions: vector of ofp_action_output; + }; + + global flow_mod: function(dpid: count, flow_mod: ofp_flow_mod): bool; } # Flow Modification function prototype -type FlowModFunc: function( - dpid: count, cookie: count, idle_timeout:count, hard_timeout: count, - actions: vector of ofp_action_output, match: ofp_match): bool; +type FlowModFunc: function(dpid: count, flow_mod: ofp_flow_mod): bool; # Flow Modification function global FlowMod: FlowModFunc; @@ -170,10 +180,8 @@ function register_openflow_mod_func(func: FlowModFunc) { FlowMod = func; } -function flow_mod( - dpid: count, cookie: count, idle_timeout:count, hard_timeout:count, - actions: vector of ofp_action_output, match: ofp_match): bool { - return FlowMod(dpid, cookie, idle_timeout, hard_timeout, actions, match); +function flow_mod(dpid: count, flow_mod: ofp_flow_mod): bool { + return FlowMod(dpid, flow_mod); } event bro_init() &priority=100000 { diff --git a/scripts/base/frameworks/openflow/plugins/ryu.bro b/scripts/base/frameworks/openflow/plugins/ryu.bro index 745dcb4e04..a0905ba1a1 100644 --- a/scripts/base/frameworks/openflow/plugins/ryu.bro +++ b/scripts/base/frameworks/openflow/plugins/ryu.bro @@ -6,9 +6,13 @@ module Openflow; export { - const controller_uri = "http://10.255.0.20:8080/stats/flowentry/add" &redef; + const controller_ip = "10.255.0.20" &redef; + const controller_port = "8080" &redef; } +const OFP_NO_BUFFER = 0xffffffff; +const RYU_FLOWENTRY_PATH = "/stats/flowentry/"; + type ryu_flow_action_output: record { # The type should be never changed... # but constants are not possible in a record. @@ -20,7 +24,7 @@ type ryu_flow_action_output: record { # The restAPI documentation can be found at # https://media.readthedocs.org/pdf/ryu/latest/ryu.pdf # on page 278-299 -type ryu_flow_add: record { +type ryu_flow_mod: record { dpid: count; cookie: count &optional; cookie_mask: count &optional; @@ -37,42 +41,103 @@ type ryu_flow_add: record { # register the ryu openflow plugin flow_mod function hook register_openflow_plugin() { register_openflow_mod_func( - function( - dpid: count, cookie: count, idle_timeout: count, hard_timeout: count, - actions: vector of ofp_action_output, match: ofp_match): bool { - local ryu_flow_actions: vector of ryu_flow_action_output; - for(i in actions) { - if(actions[i]$_type == Openflow::OFPAT_OUTPUT) { - ryu_flow_actions[|ryu_flow_actions|] = ryu_flow_action_output($_port=actions[i]$_port); + function(dpid: count, flow_mod: ofp_flow_mod): bool { + # Generate ryu_flow_actions because their type differs (using strings as type). + local _flow_actions: vector of ryu_flow_action_output; + for(i in flow_mod$actions) { + switch(flow_mod$actions[i]$_type) { + case OFPAT_OUTPUT: + _flow_actions[|_flow_actions|] = ryu_flow_action_output($_port=flow_mod$actions[i]$_port); + break; + default: + print fmt("Error: flow action '%s' not available", flow_mod$actions[i]$_type); + return F; } } - # Generate our record for the restAPI. - local ryu_flow_mod: ryu_flow_add = ryu_flow_add($dpid=dpid, $cookie=cookie, $idle_timeout=idle_timeout, $hard_timeout=hard_timeout, $match=match, $actions=ryu_flow_actions); - # Create the ActiveHTTP request and convert the record to a JSON string - local request: ActiveHTTP::Request = ActiveHTTP::Request($url=controller_uri, $method="POST", $client_data=JSON::convert(ryu_flow_mod)); - # Execute call to RyuRestAPI + # Generate our ryu_flow_mod record for the restAPI call. + local _flow_mod: ryu_flow_mod = ryu_flow_mod( + $dpid=dpid, + $cookie=flow_mod$cookie, + $idle_timeout=flow_mod$idle_timeout, + $hard_timeout=flow_mod$hard_timeout, + $match=flow_mod$match, + $actions=_flow_actions + ); + # Type of the command + local command_type: string; + switch(flow_mod$command) { + case OFPFC_ADD: + command_type = "add"; + break; + case OFPFC_DELETE: + command_type = "delete"; + break; + default: + print fmt("Error: command type '%s' not available", flow_mod$command); + return F; + } + # Create the ActiveHTTP request and convert the record to a ryu restAPI JSON string + local request: ActiveHTTP::Request = ActiveHTTP::Request( + $url=cat("http://", controller_ip, ":", controller_port, RYU_FLOWENTRY_PATH, command_type), + $method="POST", + $client_data=JSON::convert(_flow_mod) + ); + # Execute call to ryu's restAPI when(local result = ActiveHTTP::request(request)) { if(result$code == 200) { - print fmt("Flow %s:%s -> %s:%s removed from monitor", match$nw_src, match$tp_src, match$nw_dst, match$tp_dst); + print fmt( + "%sed flow %s:%s -> %s:%s", + command_type, + flow_mod$match$nw_src, + flow_mod$match$tp_src, + flow_mod$match$nw_dst, + flow_mod$match$tp_dst + ); } else { - print fmt("Error: could no add shunt flow, restAPI returned:\n%s", result); + print fmt("Error: could not %s flow, restAPI returned:\n%s", command_type, result); return F; } } # Add reverse flow because openflow only uses unidirectional flows. - if(|actions| == 1 && (match$dl_type == ETH_IPv4 || match$dl_type == ETH_IPv6)) { - local reverse_match: ofp_match; - local reverse_actions: vector of ryu_flow_action_output; - reverse_actions[|reverse_actions|] = ryu_flow_action_output($_port=match$in_port); - reverse_match = ofp_match($in_port=actions[0]$_port, $dl_type=match$dl_type, $nw_proto=match$nw_proto, $nw_src=match$nw_dst, $nw_dst=match$nw_src, $tp_src=match$tp_dst, $tp_dst=match$tp_src); - local reverse_flow_mod: ryu_flow_add = ryu_flow_add($dpid=dpid, $cookie=cookie, $idle_timeout=idle_timeout, $hard_timeout=hard_timeout, $match=reverse_match, $actions=reverse_actions); - local reverse_request: ActiveHTTP::Request = ActiveHTTP::Request($url=controller_uri, $method="POST", $addl_curl_args=fmt("-d '%s'", JSON::convert(reverse_flow_mod))); + if(|flow_mod$actions| == 1 && (flow_mod$match$dl_type == ETH_IPv4 || flow_mod$match$dl_type == ETH_IPv6)) { + local reverse_flow_match: ofp_match; + local reverse_flow_actions: vector of ryu_flow_action_output; + reverse_flow_actions[|reverse_flow_actions|] = ryu_flow_action_output($_port=flow_mod$match$in_port); + reverse_flow_match = ofp_match( + $in_port=flow_mod$actions[0]$_port, + $dl_type=flow_mod$match$dl_type, + $nw_proto=flow_mod$match$nw_proto, + $nw_src=flow_mod$match$nw_dst, + $nw_dst=flow_mod$match$nw_src, + $tp_src=flow_mod$match$tp_dst, + $tp_dst=flow_mod$match$tp_src + ); + local reverse_flow_mod: ryu_flow_mod = ryu_flow_mod( + $dpid=dpid, + $cookie=flow_mod$cookie, + $idle_timeout=flow_mod$idle_timeout, + $hard_timeout=flow_mod$hard_timeout, + $match=reverse_flow_match, + $actions=reverse_flow_actions + ); + local reverse_request: ActiveHTTP::Request = ActiveHTTP::Request( + $url=cat("http://", controller_ip, ":", controller_port, RYU_FLOWENTRY_PATH, command_type), + $method="POST", + $client_data=JSON::convert(reverse_flow_mod) + ); when(local result2 = ActiveHTTP::request(reverse_request)) { if(result2$code == 200) { - print fmt("Flow %s:%s -> %s:%s removed from monitor", reverse_match$nw_src, reverse_match$tp_src, reverse_match$nw_dst, reverse_match$tp_dst); + print fmt( + "%sed flow %s:%s -> %s:%s", + command_type, + reverse_flow_match$nw_src, + reverse_flow_match$tp_src, + reverse_flow_match$nw_dst, + reverse_flow_match$tp_dst + ); } else { - print fmt("Error: could no add shunt flow, restAPI returned:\n%s", result2); + print fmt("Error: could not %s flow, restAPI returned:\n%s", command_type, result2); return F; } } diff --git a/scripts/site/openflow-shunt.bro b/scripts/site/openflow-shunt.bro index ecb14815d3..92fab94e65 100644 --- a/scripts/site/openflow-shunt.bro +++ b/scripts/site/openflow-shunt.bro @@ -19,6 +19,8 @@ const hard_timeout = 0; const in_port = 3; const out_port = 1; +global delete_flow: bool = F; + export { ## Number of bytes transferred before shunting a flow. const size_threshold = 1024000 &redef; @@ -33,27 +35,62 @@ export { } function size_callback(c: connection, cnt: count): interval { - print fmt("%s:%s <-> %s:%s reached %s/%s", c$id$orig_h, port_to_count(c$id$orig_p), c$id$resp_h, port_to_count(c$id$resp_p), c$orig$num_bytes_ip + c$resp$num_bytes_ip, size_threshold); + # print flow traffic. + print fmt( + "%s:%s <-> %s:%s reached %s/%s", + c$id$orig_h, + port_to_count(c$id$orig_p), + c$id$resp_h, + port_to_count(c$id$resp_p), + c$orig$num_bytes_ip + c$resp$num_bytes_ip, + size_threshold + ); + # if traffic exceeds the given threshold, remove flow. if ( c$orig$num_bytes_ip + c$resp$num_bytes_ip >= size_threshold ) { + # create openflow flow_mod add records from connection data and given default constants local actions: vector of Openflow::ofp_action_output; actions[|actions|] = Openflow::ofp_action_output($_port=out_port); - + # flow layer 4 protocol local nw_proto = Openflow::IP_TCP; if(is_udp_port(c$id$orig_p)) { nw_proto = Openflow::IP_UDP; } else if(is_icmp_port(c$id$orig_p)) { nw_proto = Openflow::IP_ICMP; } - local match: Openflow::ofp_match = [$in_port=in_port, $nw_src=c$id$orig_h, $nw_dst=c$id$resp_h, $nw_proto=nw_proto, $tp_src=c$id$orig_p, $tp_dst=c$id$resp_p]; + local match: Openflow::ofp_match = [ + $in_port=in_port, + $nw_src=c$id$orig_h, + $nw_dst=c$id$resp_h, + $nw_proto=nw_proto, + $tp_src=c$id$orig_p, + $tp_dst=c$id$resp_p + ]; + local command = Openflow::OFPFC_ADD; + if(delete_flow) { + command = Openflow::OFPFC_DELETE; + } + local flow_mod: Openflow::ofp_flow_mod = [ + $match=match, + $cookie=cookie, + $command=command, + $idle_timeout=idle_timeout, + $hard_timeout=hard_timeout, + $actions=actions + ]; - # print fmt(cmd, param_dpid, param_port, "",of_ctrl_uri); - when ( local result = Openflow::flow_mod(dpid, cookie, idle_timeout, hard_timeout, actions, match) ) { + # call openflow framework + when ( local result = Openflow::flow_mod(dpid, flow_mod) ) { if(result) { event OpenflowShunt::shunt_triggered(c); } } - return -1sec; + if(delete_flow) { + return -1sec; + } else { + delete_flow = T; + return 15sec; + } } return poll_interval; From c705375537a17ed057b0a90dcde47d14548d0719 Mon Sep 17 00:00:00 2001 From: Christian Struck Date: Thu, 30 Oct 2014 18:12:55 -0700 Subject: [PATCH 07/93] [ADD] made code event based, changed code style the openflow framework does now use events to signal the success or failure of openflow commands, further the reporter framework is used to log errors. added bro unique cookie, so the framework can recognize which flows it installed and which not. documented all of the code. the code style should now me more like the rest of the bro code. --- scripts/base/frameworks/openflow/main.bro | 324 +++++++++++++----- .../base/frameworks/openflow/plugins/ryu.bro | 155 +++++---- scripts/site/openflow-shunt.bro | 81 +++-- 3 files changed, 381 insertions(+), 179 deletions(-) diff --git a/scripts/base/frameworks/openflow/main.bro b/scripts/base/frameworks/openflow/main.bro index 11152d2b67..e3cabcb939 100644 --- a/scripts/base/frameworks/openflow/main.bro +++ b/scripts/base/frameworks/openflow/main.bro @@ -1,87 +1,126 @@ @load ./utils/const.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 { -# ofp_port: enum { - # Maximum number of physical switch ports. + ## 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 + ## Maximum number of physical switch ports. const OFPP_MAX = 0xff00; - ######################## - # Fake output "ports". # - ######################## - # Send the packet out the input port. This - # virual port must be explicitly used in - # order to send back out of the input port. + ## 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 = 0xfff8; - # Perform actions in flow table. - # NB: This can only be the destination port - # for packet-out messages. + ## Perform actions in flow table. + ## NB: This can only be the destination port + ## for packet-out messages. const OFPP_TABLE = 0xfff9; - # Process with normal L2/L3 switching. + ## Process with normal L2/L3 switching. const OFPP_NORMAL = 0xfffa; - # All pysical ports except input port and - # those disabled by STP. + ## All pysical ports except input port and + ## those disabled by STP. const OFPP_FLOOD = 0xfffb; - # All pysical ports except input port. + ## All pysical ports except input port. const OFPP_ALL = 0xfffc; - # Send to controller. + ## Send to controller. const OFPP_CONTROLLER = 0xfffd; - # Local openflow "port". + ## Local openflow "port". const OFPP_LOCAL = 0xfffe; - # Not associated with a pysical port. + ## Not associated with a pysical port. const OFPP_NONE = 0xffff; -# } + + ## 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. + ## Output to switch port. OFPAT_OUTPUT = 0x0000, - # Set the 802.1q VLAN id. + ## Set the 802.1q VLAN id. OFPAT_SET_VLAN_VID = 0x0001, - # Set the 802.1q priority. + ## Set the 802.1q priority. OFPAT_SET_VLAN_PCP = 0x0002, - # Strip the 802.1q header. + ## Strip the 802.1q header. OFPAT_STRIP_VLAN = 0x0003, - # Ethernet source address. + ## Ethernet source address. OFPAT_SET_DL_SRC = 0x0004, - # Ethernet destination address. + ## Ethernet destination address. OFPAT_SET_DL_DST = 0x0005, - # IP source address + ## IP source address OFPAT_SET_NW_SRC = 0x0006, - # IP destination address. + ## IP destination address. OFPAT_SET_NW_DST = 0x0007, - # IP ToS (DSCP field, 6 bits). + ## IP ToS (DSCP field, 6 bits). OFPAT_SET_NW_TOS = 0x0008, - # TCP/UDP source port. + ## TCP/UDP source port. OFPAT_SET_TP_SRC = 0x0009, - # TCP/UDP destination port. + ## TCP/UDP destination port. OFPAT_SET_TP_DST = 0x000a, - # Output to queue. + ## 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, - # Modify all matching flows. - OFPFC_MODIFY, - # Modify entry strictly matching wildcards. - OFPFC_MODIFY_STRICT, - # Delete all matching flows. - OFPFC_DELETE, - # Strictly matching wildcards and priority. - OFPFC_DELETE_STRICT, + ## 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. + ## No special handling for fragments. OFPC_FRAG_NORMAL = 0, - # Drop fragments. + ## Drop fragments. OFPC_FRAG_DROP = 1, - # Reassemble (only if OFPC_IP_REASM set). + ## Reassemble (only if OFPC_IP_REASM set). OFPC_FRAG_REASM = 2, OFPC_FRAG_MASK = 3, }; - + + ## Openflow match definition. + ## + ## The openflow match record describes + ## which packets match to a specific + ## rule in a flow table. type ofp_match: record { # Wildcard fields. #wildcards: count &optional; @@ -111,80 +150,199 @@ export { tp_dst: port &optional; }; + ## Openflow actions definition. + ## + ## A action describes what should + ## happen with packets of the matching + ## flow. type ofp_action_output: record { - # this should never change, but there are not - # constants available in records - # defaults to OFPAT_OUTPUT + ## this should never change, but there are not + ## constants available in records + ## defaults to OFPAT_OUTPUT _type: ofp_action_type &default=OFPAT_OUTPUT; #_len: count &default=8; - # Output port. + ## Output port. _port: count &default=OFPP_FLOOD; #_max_len: count &optional; }; -#type ofp_flow_mod_flags: enum { - # Send flow removed message when flow - # expires or is deleted. + # Openflow flow_mod_flags definition + ## Send flow removed message when flow + ## expires or is deleted. const OFPFF_SEND_FLOW_REM = 0x1; - # Check for overlapping entries first. + ## 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. + ## Remark this is for emergency. + ## Flows added with this are only used + ## when the controller is disconnected. const OFPFF_EMERG = 0x4; -#}; + ## Openflow flow_mod definition. + ## It describes the flow to match and + ## how it should be modified. type ofp_flow_mod: record { # header: ofp_header; - # Fields to match + ## Fields to match match: ofp_match; - # Opaque controller-issued identifier. - cookie: count &optional; - + ## Opaque controller-issued identifier. + cookie: count &default=BRO_COOKIE_ID * COOKIE_BID_START; # Flow actions - - # One of OFPFC_*. + ## One of OFPFC_*. command: ofp_flow_mod_command &default=OFPFC_ADD; - # Idle time befor discarding (seconds). + ## Idle time befor discarding (seconds). idle_timeout: count &optional; - # Max time before discarding (seconds). + ## Max time before discarding (seconds). hard_timeout: count &optional; - # Priority level of flow entry. + ## Priority level of flow entry. priority: count &optional; - # Buffered packet to apply to (or -1). - # Not meaningful for OFPFC_DELETE*. + ## Buffered packet to apply to (or -1). + ## Not meaningful for OFPFC_DELETE*. buffer_id: count &optional; - # For OFPFC_DELETE* commands, require - # matching entries to include this as an - # output port. A value of OFPP_NONE - # indicates no restrictions + ## For OFPFC_DELETE* commands, require + ## matching entries to include this as an + ## output port. A value of OFPP_NONE + ## indicates no restrictions. out_port: count &optional; - # One of OFPFF_*. + ## One of OFPFF_*. flags: count &optional; + ## A list of actions to perform. actions: vector of ofp_action_output; }; + ## Body of reply to OFPST_FLOW request. + type ofp_flow_stats: record { + ## Length of this entry + length: count; + ## ID of table flow came from. + table_id: count; + ## Description of fields. + match: ofp_match; + ## Time flow has been alive in seconds. + duration_sec: count; + ## Time flow has been alive in nanoseconds beyond + ## duration_sec. + duration_nsec: count; + ## Priority of the entry. Only meaningful + ## when this is not an exact-match entry. + priority: count; + ## Number of seconds idle before expiration. + idle_timeout: count; + ## Number of seconds before expiration. + hard_timeout: count; + ## Opaque controller-issued identifier. + cookie: count; + ## Number of packets in flow. + packet_count: count; + ## Number of bytes in flow. + byte_count: count; + ## Actions + actions: vector of ofp_action_output; + }; + + ## Function to modify flows in a openflow flow table. + ## + ## dpid: The openflow controller datapath id. + ## + ## flow_mod: The openflow flow_mod record which describes + ## the flow to delete, modify or add. + ## + ## Returns: T, if successful, else F. global flow_mod: function(dpid: count, flow_mod: ofp_flow_mod): bool; + + ## 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; + + ## Event to signal that a flow has been successfully modified. + ## + ## flow_mod: The openflow flow_mod record which describes + ## the flow to delete, modify or add. + ## + ## msg: Message to describe the event. + global Openflow::flow_mod_success: event(flow_mod: ofp_flow_mod, msg: string &default = "Flow successfully modified"); + + ## Event to signal that a flow mod has failed. + ## + ## flow_mod: The openflow flow_mod record which describes + ## the flow to delete, modify ord add. + ## + ## msg: Message to describe the event. + global Openflow::flow_mod_failure: event(flow_mod: ofp_flow_mod, msg: string &default = "Could not modify flow"); } + # Flow Modification function prototype type FlowModFunc: function(dpid: count, flow_mod: ofp_flow_mod): bool; -# Flow Modification function -global FlowMod: FlowModFunc; # Hook for registering openflow plugins global register_openflow_plugin: hook(); -function register_openflow_mod_func(func: FlowModFunc) { - FlowMod = func; -} -function flow_mod(dpid: count, flow_mod: ofp_flow_mod): bool { - return FlowMod(dpid, flow_mod); -} +# Function for plugins to call when they +# register their flow_mod function. +function register_openflow_mod_func(func: FlowModFunc) + { + flow_mod = func; + } -event bro_init() &priority=100000 { + +# 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 a 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; + } + + +event bro_init() + { # Call all of the plugin registration hooks hook register_openflow_plugin(); -} + } diff --git a/scripts/base/frameworks/openflow/plugins/ryu.bro b/scripts/base/frameworks/openflow/plugins/ryu.bro index a0905ba1a1..6d30a0cf6d 100644 --- a/scripts/base/frameworks/openflow/plugins/ryu.bro +++ b/scripts/base/frameworks/openflow/plugins/ryu.bro @@ -3,17 +3,51 @@ @load base/utils/exec @load base/utils/active-http + module Openflow; + export { - const controller_ip = "10.255.0.20" &redef; + ## The Ryu openflow controller IP. + const controller_ip = "0.0.0.0" &redef; + ## The port where the ReST API listens on. const controller_port = "8080" &redef; + + ## Ryu error definitions. + type RyuError: enum { + ## The controller IP needs to be redefined. + CONTROLLER_IP_REDEF, + ## The openflow command type is not available + ## for this ryu openflow plugin. + COMMAND_TYPE_NOT_AVAILABLE, + ## The openflow action type is not available + ## for this ryu openflow plugin. + ACTION_TYPE_NOT_AVAILABLE, + }; + + ## Ryu error event. + ## + ## flow_mod: The openflow flow_mod record which describes + ## the flow to delete, modify or add. + ## + ## error: The error why the plugin aborted. + ## + ## msg: More detailed error description. + global Openflow::ryu_error: event(flow_mod: ofp_flow_mod, error: RyuError, msg: string &default=""); } + +# Openflow no buffer constant. const OFP_NO_BUFFER = 0xffffffff; + + +# Ryu ReST API flow_mod URL-path const RYU_FLOWENTRY_PATH = "/stats/flowentry/"; + +# Ryu ReST API action_output type. type ryu_flow_action_output: record { + # Ryu uses strings as its ReST API output action. # The type should be never changed... # but constants are not possible in a record. _type: string &default="OUTPUT"; @@ -21,9 +55,11 @@ type ryu_flow_action_output: record { _port: count; }; -# The restAPI documentation can be found at + +# The ReST API documentation can be found at # https://media.readthedocs.org/pdf/ryu/latest/ryu.pdf -# on page 278-299 +# on page 278-299 (30.10.2014) +# Ryu ReST API flow_mod type. type ryu_flow_mod: record { dpid: count; cookie: count &optional; @@ -38,26 +74,40 @@ type ryu_flow_mod: record { actions: vector of ryu_flow_action_output; }; -# register the ryu openflow plugin flow_mod function -hook register_openflow_plugin() { + +# Hook to register the Ryu openflow plugin's flow_mod function +# as the one the openflow framework should use. +hook register_openflow_plugin() + { register_openflow_mod_func( - function(dpid: count, flow_mod: ofp_flow_mod): bool { + function(dpid: count, flow_mod: ofp_flow_mod): bool + { + # Check if the controller_ip has been redefined. + if(controller_ip == "0.0.0.0") + { + Reporter::warning(fmt("The constant Openflow::controller_ip must be redefined")); + event Openflow::ryu_error(flow_mod, CONTROLLER_IP_REDEF, cat(controller_ip)); + return F; + } # Generate ryu_flow_actions because their type differs (using strings as type). local _flow_actions: vector of ryu_flow_action_output; - for(i in flow_mod$actions) { - switch(flow_mod$actions[i]$_type) { + for(i in flow_mod$actions) + { + switch(flow_mod$actions[i]$_type) + { case OFPAT_OUTPUT: _flow_actions[|_flow_actions|] = ryu_flow_action_output($_port=flow_mod$actions[i]$_port); break; default: - print fmt("Error: flow action '%s' not available", flow_mod$actions[i]$_type); + Reporter::warning(fmt("The given Openflow action type '%s' is not available", flow_mod$actions[i]$_type)); + event Openflow::ryu_error(flow_mod, ACTION_TYPE_NOT_AVAILABLE, cat(flow_mod$actions[i]$_type)); return F; + } } - } - # Generate our ryu_flow_mod record for the restAPI call. + # Generate our ryu_flow_mod record for the ReST API call. local _flow_mod: ryu_flow_mod = ryu_flow_mod( $dpid=dpid, - $cookie=flow_mod$cookie, + $cookie=generate_cookie(flow_mod$cookie), $idle_timeout=flow_mod$idle_timeout, $hard_timeout=flow_mod$hard_timeout, $match=flow_mod$match, @@ -65,7 +115,8 @@ hook register_openflow_plugin() { ); # Type of the command local command_type: string; - switch(flow_mod$command) { + switch(flow_mod$command) + { case OFPFC_ADD: command_type = "add"; break; @@ -73,76 +124,30 @@ hook register_openflow_plugin() { command_type = "delete"; break; default: - print fmt("Error: command type '%s' not available", flow_mod$command); + Reporter::warning(fmt("The given Openflow command type '%s' is not available", result$body)); + event Openflow::ryu_error(flow_mod, COMMAND_TYPE_NOT_AVAILABLE, cat(flow_mod$command)); return F; - } - # Create the ActiveHTTP request and convert the record to a ryu restAPI JSON string + } + # Create the ActiveHTTP request and convert the record to a Ryu ReST API JSON string local request: ActiveHTTP::Request = ActiveHTTP::Request( $url=cat("http://", controller_ip, ":", controller_port, RYU_FLOWENTRY_PATH, command_type), $method="POST", $client_data=JSON::convert(_flow_mod) ); - # Execute call to ryu's restAPI - when(local result = ActiveHTTP::request(request)) { - if(result$code == 200) { - print fmt( - "%sed flow %s:%s -> %s:%s", - command_type, - flow_mod$match$nw_src, - flow_mod$match$tp_src, - flow_mod$match$nw_dst, - flow_mod$match$tp_dst - ); - } else { - print fmt("Error: could not %s flow, restAPI returned:\n%s", command_type, result); + # Execute call to Ryu's ReST API + when(local result = ActiveHTTP::request(request)) + { + if(result$code == 200) + event Openflow::flow_mod_success(flow_mod, result$body); + else + { + Reporter::warning(fmt("Flow modification failed with error: %s", result$body)); + event Openflow::flow_mod_failure(flow_mod, result$body); return F; - } - } - - # Add reverse flow because openflow only uses unidirectional flows. - if(|flow_mod$actions| == 1 && (flow_mod$match$dl_type == ETH_IPv4 || flow_mod$match$dl_type == ETH_IPv6)) { - local reverse_flow_match: ofp_match; - local reverse_flow_actions: vector of ryu_flow_action_output; - reverse_flow_actions[|reverse_flow_actions|] = ryu_flow_action_output($_port=flow_mod$match$in_port); - reverse_flow_match = ofp_match( - $in_port=flow_mod$actions[0]$_port, - $dl_type=flow_mod$match$dl_type, - $nw_proto=flow_mod$match$nw_proto, - $nw_src=flow_mod$match$nw_dst, - $nw_dst=flow_mod$match$nw_src, - $tp_src=flow_mod$match$tp_dst, - $tp_dst=flow_mod$match$tp_src - ); - local reverse_flow_mod: ryu_flow_mod = ryu_flow_mod( - $dpid=dpid, - $cookie=flow_mod$cookie, - $idle_timeout=flow_mod$idle_timeout, - $hard_timeout=flow_mod$hard_timeout, - $match=reverse_flow_match, - $actions=reverse_flow_actions - ); - local reverse_request: ActiveHTTP::Request = ActiveHTTP::Request( - $url=cat("http://", controller_ip, ":", controller_port, RYU_FLOWENTRY_PATH, command_type), - $method="POST", - $client_data=JSON::convert(reverse_flow_mod) - ); - when(local result2 = ActiveHTTP::request(reverse_request)) { - if(result2$code == 200) { - print fmt( - "%sed flow %s:%s -> %s:%s", - command_type, - reverse_flow_match$nw_src, - reverse_flow_match$tp_src, - reverse_flow_match$nw_dst, - reverse_flow_match$tp_dst - ); - } else { - print fmt("Error: could not %s flow, restAPI returned:\n%s", command_type, result2); - return F; } } - } + return T; - } + } ); -} + } diff --git a/scripts/site/openflow-shunt.bro b/scripts/site/openflow-shunt.bro index 92fab94e65..d10ce853e8 100644 --- a/scripts/site/openflow-shunt.bro +++ b/scripts/site/openflow-shunt.bro @@ -12,6 +12,7 @@ module OpenflowShunt; # default constants which are not automatically gathered. +redef Openflow::controller_ip = "10.255.0.20"; const dpid = 4222282094087168; const cookie = 0; const idle_timeout = 30; @@ -34,7 +35,8 @@ export { global shunt_triggered: event(c: connection); } -function size_callback(c: connection, cnt: count): interval { +function size_callback(c: connection, cnt: count): interval + { # print flow traffic. print fmt( "%s:%s <-> %s:%s reached %s/%s", @@ -46,17 +48,20 @@ function size_callback(c: connection, cnt: count): interval { size_threshold ); # if traffic exceeds the given threshold, remove flow. - if ( c$orig$num_bytes_ip + c$resp$num_bytes_ip >= size_threshold ) { + if ( c$orig$num_bytes_ip + c$resp$num_bytes_ip >= size_threshold ) + { # create openflow flow_mod add records from connection data and given default constants local actions: vector of Openflow::ofp_action_output; + local reverse_actions: vector of Openflow::ofp_action_output; actions[|actions|] = Openflow::ofp_action_output($_port=out_port); + reverse_actions[|reverse_actions|] = Openflow::ofp_action_output($_port=in_port); # flow layer 4 protocol local nw_proto = Openflow::IP_TCP; - if(is_udp_port(c$id$orig_p)) { + if(is_udp_port(c$id$orig_p)) nw_proto = Openflow::IP_UDP; - } else if(is_icmp_port(c$id$orig_p)) { + else if(is_icmp_port(c$id$orig_p)) nw_proto = Openflow::IP_ICMP; - } + local match: Openflow::ofp_match = [ $in_port=in_port, $nw_src=c$id$orig_h, @@ -65,10 +70,19 @@ function size_callback(c: connection, cnt: count): interval { $tp_src=c$id$orig_p, $tp_dst=c$id$resp_p ]; + + local reverse_match: Openflow::ofp_match = [ + $in_port=out_port, + $nw_src=c$id$resp_h, + $nw_dst=c$id$orig_h, + $nw_proto=nw_proto, + $tp_src=c$id$resp_p, + $tp_dst=c$id$orig_p + ]; + local command = Openflow::OFPFC_ADD; - if(delete_flow) { + if(delete_flow) command = Openflow::OFPFC_DELETE; - } local flow_mod: Openflow::ofp_flow_mod = [ $match=match, $cookie=cookie, @@ -77,26 +91,51 @@ function size_callback(c: connection, cnt: count): interval { $hard_timeout=hard_timeout, $actions=actions ]; + local reverse_flow_mod: Openflow::ofp_flow_mod = [ + $match=reverse_match, + $cookie=cookie, + $command=command, + $idle_timeout=idle_timeout, + $hard_timeout=hard_timeout, + $actions=reverse_actions + ]; # call openflow framework - when ( local result = Openflow::flow_mod(dpid, flow_mod) ) { - if(result) { - event OpenflowShunt::shunt_triggered(c); + if(Openflow::flow_mod(dpid, flow_mod) && Openflow::flow_mod(dpid, reverse_flow_mod)) { + event shunt_triggered(c); + } + + if(delete_flow) + { + delete_flow = F; + return -1sec; + } + else + { + delete_flow = T; + return 15sec; } } - if(delete_flow) { - return -1sec; - } else { - delete_flow = T; - return 15sec; - } + return poll_interval; } - return poll_interval; -} - -event connection_established(c: connection) { +event connection_established(c: connection) + { print fmt("new connection"); ConnPolling::watch(c, size_callback, 0, 0secs); -} \ No newline at end of file + } + +event Openflow::flow_mod_success(flow_mod: Openflow::ofp_flow_mod, msg: string) + { + print fmt("succsess, %s", cat(flow_mod)); + } + +event Openflow::flow_mod_failure(flow_mod: Openflow::ofp_flow_mod, msg: string) + { + print fmt("failed, %s", cat(flow_mod)); + } +event Openflow::ryu_error(flow_mod: Openflow::ofp_flow_mod, error: Openflow::RyuError, msg: string) + { + print fmt("ERROR: %s, msg: %s\n%s", error, msg, flow_mod); + } From 8e2c269c2e59a702ea18ac19e8037ce7a4d35cfe Mon Sep 17 00:00:00 2001 From: Christian Struck Date: Thu, 6 Nov 2014 15:53:09 -0800 Subject: [PATCH 08/93] [ADD] status function to get flows from switch, error handling. Added a function to receive status from the switch through the openflow controller. (not yet implemented anywhere) The flow_mod and flow_stats function now have default values which report that the function is not implemented when they're called but no plugin has registered its functions for them. --- scripts/base/frameworks/openflow/main.bro | 37 ++++++++++++++++--- .../base/frameworks/openflow/plugins/ryu.bro | 9 ++++- .../base/frameworks/openflow/utils/json.bro | 11 ++++++ scripts/site/openflow-shunt.bro | 21 +++++------ 4 files changed, 59 insertions(+), 19 deletions(-) diff --git a/scripts/base/frameworks/openflow/main.bro b/scripts/base/frameworks/openflow/main.bro index e3cabcb939..a55e32a063 100644 --- a/scripts/base/frameworks/openflow/main.bro +++ b/scripts/base/frameworks/openflow/main.bro @@ -212,7 +212,7 @@ export { ## Body of reply to OFPST_FLOW request. type ofp_flow_stats: record { ## Length of this entry - length: count; + _length: count; ## ID of table flow came from. table_id: count; ## Description of fields. @@ -247,7 +247,24 @@ export { ## the flow to delete, modify or add. ## ## Returns: T, if successful, else F. - global flow_mod: function(dpid: count, flow_mod: ofp_flow_mod): bool; + global flow_mod: function(dpid: count, flow_mod: ofp_flow_mod): bool + &default=function(dpid: count, flow_mod:ofp_flow_mod): bool + { + Reporter::warning("Openflow::flow_mod function not implemented. Please load the right Openflow plugin"); + return F; + }; + + ## Function to get flow stats from the openflow switch/router + ## + ## dpid: The openflow controller datapath id. + ## + ## Returns: list with the installed flows and their statistics + global flow_stats: function(dpid: count): vector of ofp_flow_stats + &default=function(dpid: count): vector of ofp_flow_stats + { + Reporter::warning("Openflow::flow_stats function not implemented. Please load the right Openflow plugin"); + return vector(); + }; ## Function to get the unique id out of a given cookie ## @@ -285,18 +302,28 @@ export { type FlowModFunc: function(dpid: count, flow_mod: ofp_flow_mod): bool; +# Flow Statistics function prototype +type FlowStatsFunc: function(dpid: count): vector of ofp_flow_stats; + + # Hook for registering openflow plugins global register_openflow_plugin: hook(); -# Function for plugins to call when they -# register their flow_mod function. +# Function for plugins to call when they register their flow_mod function. function register_openflow_mod_func(func: FlowModFunc) { flow_mod = func; } +# Function for plugins to call when they register their flow_stats function. +function register_openflow_stats_func(func: FlowStatsFunc) + { + flow_stats = func; + } + + # 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. @@ -316,7 +343,7 @@ 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 a valid", cookie)); + Reporter::warning(fmt("The given Openflow cookie '%d' is not valid", cookie)); return F; } diff --git a/scripts/base/frameworks/openflow/plugins/ryu.bro b/scripts/base/frameworks/openflow/plugins/ryu.bro index 6d30a0cf6d..a3360c3098 100644 --- a/scripts/base/frameworks/openflow/plugins/ryu.bro +++ b/scripts/base/frameworks/openflow/plugins/ryu.bro @@ -43,6 +43,8 @@ const OFP_NO_BUFFER = 0xffffffff; # 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. @@ -85,7 +87,7 @@ hook register_openflow_plugin() # Check if the controller_ip has been redefined. if(controller_ip == "0.0.0.0") { - Reporter::warning(fmt("The constant Openflow::controller_ip must be redefined")); + Reporter::warning("The constant Openflow::controller_ip must be redefined"); event Openflow::ryu_error(flow_mod, CONTROLLER_IP_REDEF, cat(controller_ip)); return F; } @@ -124,7 +126,7 @@ hook register_openflow_plugin() command_type = "delete"; break; default: - Reporter::warning(fmt("The given Openflow command type '%s' is not available", result$body)); + Reporter::warning(fmt("The given Openflow command type '%s' is not available", cat(flow_mod$command))); event Openflow::ryu_error(flow_mod, COMMAND_TYPE_NOT_AVAILABLE, cat(flow_mod$command)); return F; } @@ -150,4 +152,7 @@ hook register_openflow_plugin() return T; } ); + + # TODO: implement when a JSON -> record converter exists + # register_openflow_stats_func(); } diff --git a/scripts/base/frameworks/openflow/utils/json.bro b/scripts/base/frameworks/openflow/utils/json.bro index c482314698..44b722b190 100644 --- a/scripts/base/frameworks/openflow/utils/json.bro +++ b/scripts/base/frameworks/openflow/utils/json.bro @@ -12,8 +12,19 @@ export { ## ## returns: a JSON formatted string. global convert: function(v: any, only_loggable: bool &default=F, field_escape_pattern: pattern &default=/^_/): string; + + global jsonToRecord: function(input: string): any; } +function jsonToRecord(input: string): any + { + local lhs: table[count] of string; + lhs = split1(input, / /); + for (i in lhs) + print lhs[i]; + return lhs; + } + function convert(v: any, only_loggable: bool &default=F, field_escape_pattern: pattern &default=/^_/): string { local tn = type_name(v); diff --git a/scripts/site/openflow-shunt.bro b/scripts/site/openflow-shunt.bro index d10ce853e8..0a46b14a4d 100644 --- a/scripts/site/openflow-shunt.bro +++ b/scripts/site/openflow-shunt.bro @@ -19,9 +19,9 @@ const idle_timeout = 30; const hard_timeout = 0; const in_port = 3; const out_port = 1; - global delete_flow: bool = F; + export { ## Number of bytes transferred before shunting a flow. const size_threshold = 1024000 &redef; @@ -35,22 +35,14 @@ export { global shunt_triggered: event(c: connection); } + function size_callback(c: connection, cnt: count): interval { - # print flow traffic. - print fmt( - "%s:%s <-> %s:%s reached %s/%s", - c$id$orig_h, - port_to_count(c$id$orig_p), - c$id$resp_h, - port_to_count(c$id$resp_p), - c$orig$num_bytes_ip + c$resp$num_bytes_ip, - size_threshold - ); + # print Openflow::flow_stats(dpid); # if traffic exceeds the given threshold, remove flow. if ( c$orig$num_bytes_ip + c$resp$num_bytes_ip >= size_threshold ) { - # create openflow flow_mod add records from connection data and given default constants + # create openflow flow_mod add records from connection data and give default constants local actions: vector of Openflow::ofp_action_output; local reverse_actions: vector of Openflow::ofp_action_output; actions[|actions|] = Openflow::ofp_action_output($_port=out_port); @@ -120,21 +112,26 @@ function size_callback(c: connection, cnt: count): interval return poll_interval; } + event connection_established(c: connection) { print fmt("new connection"); ConnPolling::watch(c, size_callback, 0, 0secs); } + event Openflow::flow_mod_success(flow_mod: Openflow::ofp_flow_mod, msg: string) { print fmt("succsess, %s", cat(flow_mod)); } + event Openflow::flow_mod_failure(flow_mod: Openflow::ofp_flow_mod, msg: string) { print fmt("failed, %s", cat(flow_mod)); } + + event Openflow::ryu_error(flow_mod: Openflow::ofp_flow_mod, error: Openflow::RyuError, msg: string) { print fmt("ERROR: %s, msg: %s\n%s", error, msg, flow_mod); From fef847669060a63c004c03dd55e790fce2e2317c Mon Sep 17 00:00:00 2001 From: Christian Struck Date: Mon, 10 Nov 2014 16:49:20 -0800 Subject: [PATCH 09/93] [FIX] small codestyle changes --- scripts/base/frameworks/openflow/main.bro | 2 +- scripts/base/frameworks/openflow/utils/json.bro | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/scripts/base/frameworks/openflow/main.bro b/scripts/base/frameworks/openflow/main.bro index a55e32a063..3f17b65753 100644 --- a/scripts/base/frameworks/openflow/main.bro +++ b/scripts/base/frameworks/openflow/main.bro @@ -248,7 +248,7 @@ export { ## ## Returns: T, if successful, else F. global flow_mod: function(dpid: count, flow_mod: ofp_flow_mod): bool - &default=function(dpid: count, flow_mod:ofp_flow_mod): bool + &default=function(dpid: count, flow_mod: ofp_flow_mod): bool { Reporter::warning("Openflow::flow_mod function not implemented. Please load the right Openflow plugin"); return F; diff --git a/scripts/base/frameworks/openflow/utils/json.bro b/scripts/base/frameworks/openflow/utils/json.bro index 44b722b190..7ec77fdb60 100644 --- a/scripts/base/frameworks/openflow/utils/json.bro +++ b/scripts/base/frameworks/openflow/utils/json.bro @@ -69,9 +69,7 @@ function convert(v: any, only_loggable: bool &default=F, field_escape_pattern: p 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, "\": ", JSON::convert(field_desc$value, only_loggable)); @@ -116,4 +114,4 @@ function convert(v: any, only_loggable: bool &default=F, field_escape_pattern: p } return "\"\""; - } \ No newline at end of file + } From d80cc9ea1013daff3a752c922d957f90bfa473cd Mon Sep 17 00:00:00 2001 From: Christian Struck Date: Thu, 13 Nov 2014 16:49:50 -0800 Subject: [PATCH 10/93] [ADD] reworked code to new design suggested by seth. The openflow framework now supports multiple controllers. The design now looks a bit object oriented and a new() function creates a controller record. Moved the JSON script from the JSON namespace into a openflow specific OpenflowJSON namespace --- scripts/base/frameworks/openflow/main.bro | 136 +++++++-------- .../base/frameworks/openflow/plugins/ryu.bro | 163 +++++++++--------- .../base/frameworks/openflow/utils/json.bro | 12 +- scripts/site/openflow-shunt.bro | 13 +- 4 files changed, 158 insertions(+), 166 deletions(-) diff --git a/scripts/base/frameworks/openflow/main.bro b/scripts/base/frameworks/openflow/main.bro index 3f17b65753..198374a3bb 100644 --- a/scripts/base/frameworks/openflow/main.bro +++ b/scripts/base/frameworks/openflow/main.bro @@ -159,10 +159,10 @@ export { ## this should never change, but there are not ## constants available in records ## defaults to OFPAT_OUTPUT - _type: ofp_action_type &default=OFPAT_OUTPUT; + type_: ofp_action_type &default=OFPAT_OUTPUT; #_len: count &default=8; ## Output port. - _port: count &default=OFPP_FLOOD; + port_: count &default=OFPP_FLOOD; #_max_len: count &optional; }; @@ -239,95 +239,94 @@ export { actions: vector of ofp_action_output; }; - ## Function to modify flows in a openflow flow table. - ## - ## dpid: The openflow controller datapath id. - ## - ## flow_mod: The openflow flow_mod record which describes - ## the flow to delete, modify or add. - ## - ## Returns: T, if successful, else F. - global flow_mod: function(dpid: count, flow_mod: ofp_flow_mod): bool - &default=function(dpid: count, flow_mod: ofp_flow_mod): bool - { - Reporter::warning("Openflow::flow_mod function not implemented. Please load the right Openflow plugin"); - return F; - }; - - ## Function to get flow stats from the openflow switch/router - ## - ## dpid: The openflow controller datapath id. - ## - ## Returns: list with the installed flows and their statistics - global flow_stats: function(dpid: count): vector of ofp_flow_stats - &default=function(dpid: count): vector of ofp_flow_stats - { - Reporter::warning("Openflow::flow_stats function not implemented. Please load the right Openflow plugin"); - return vector(); - }; - - ## 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 + ## Function to get the unique id out of a given cookie. ## ## cookie: The openflow match cookie. ## - ## Returns: The cookie group id + ## 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 get the group id out of a given cookie. + ## + ## cookie: The openflow match cookie. + ## + ## Returns: The cookie group id. + global generate_cookie: function(cookie: count &default=0): count; + ## Event to signal that a flow has been successfully modified. ## ## flow_mod: The openflow flow_mod record which describes ## the flow to delete, modify or add. ## ## msg: Message to describe the event. - global Openflow::flow_mod_success: event(flow_mod: ofp_flow_mod, msg: string &default = "Flow successfully modified"); + global Openflow::flow_mod_success: event(flow_mod: ofp_flow_mod, msg: string &default="Flow successfully modified"); ## Event to signal that a flow mod has failed. ## ## flow_mod: The openflow flow_mod record which describes - ## the flow to delete, modify ord add. + ## the flow to delete, modify or add. ## ## msg: Message to describe the event. - global Openflow::flow_mod_failure: event(flow_mod: ofp_flow_mod, msg: string &default = "Could not modify flow"); + global Openflow::flow_mod_failure: event(flow_mod: ofp_flow_mod, msg: string &default="Could not modify flow"); + + ## Available openflow plugins + type Plugin: enum { + PLACEHOLDER, + }; + + ## Controller related state. + ## Can be redefined by plugins to + ## add state. + type ControllerState: record { + ## Controller ip. + ip: addr &optional; + ## Controller listen port. + port_: count &optional; + ## Openflow switch datapath id. + dpid: count &optional; + ## Type of the openflow plugin. + type_: Plugin; + } &redef; + + ## Controller record representing an openflow controller + type Controller: record { + ## Controller related state. + state: ControllerState; + ## flow_mod function the plugin implements + flow_mod: function(state: ControllerState, flow_mod: ofp_flow_mod): bool; + ## flow_stats function the plugin implements if existing + flow_stats: function(state: ControllerState): vector of ofp_flow_stats &optional; + }; + + ## Global flow_mod function wrapper + ## + ## controller: The controller which should execute the flow modification + ## + ## flow_mod: The openflow flow_mod record which describes + ## the flow to delete, modify or add + ## + ## Returns: T if successfull, else F + global flow_mod: function(controller: Controller, flow_mod: ofp_flow_mod): bool; } - -# Flow Modification function prototype -type FlowModFunc: function(dpid: count, flow_mod: ofp_flow_mod): bool; - - -# Flow Statistics function prototype -type FlowStatsFunc: function(dpid: count): vector of ofp_flow_stats; - - -# Hook for registering openflow plugins -global register_openflow_plugin: hook(); - - -# Function for plugins to call when they register their flow_mod function. -function register_openflow_mod_func(func: FlowModFunc) +# the flow_mod function wrapper +function flow_mod(controller: Controller, flow_mod: ofp_flow_mod): bool { - flow_mod = func; - } - - -# Function for plugins to call when they register their flow_stats function. -function register_openflow_stats_func(func: FlowStatsFunc) - { - flow_stats = func; + return controller$flow_mod(controller$state, flow_mod); } # 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 +function generate_cookie(cookie: count &default=0): count { local c = BRO_COOKIE_ID * COOKIE_BID_START; if(cookie >= COOKIE_UID_SIZE) @@ -366,10 +365,3 @@ function get_cookie_gid(cookie: count): count ); return INVALID_COOKIE; } - - -event bro_init() - { - # Call all of the plugin registration hooks - hook register_openflow_plugin(); - } diff --git a/scripts/base/frameworks/openflow/plugins/ryu.bro b/scripts/base/frameworks/openflow/plugins/ryu.bro index a3360c3098..156168782e 100644 --- a/scripts/base/frameworks/openflow/plugins/ryu.bro +++ b/scripts/base/frameworks/openflow/plugins/ryu.bro @@ -4,19 +4,16 @@ @load base/utils/active-http -module Openflow; +module OpenflowRyu; export { - ## The Ryu openflow controller IP. - const controller_ip = "0.0.0.0" &redef; - ## The port where the ReST API listens on. - const controller_port = "8080" &redef; + redef enum Openflow::Plugin += { + Openflow::RYU, + }; ## Ryu error definitions. - type RyuError: enum { - ## The controller IP needs to be redefined. - CONTROLLER_IP_REDEF, + type Error: enum { ## The openflow command type is not available ## for this ryu openflow plugin. COMMAND_TYPE_NOT_AVAILABLE, @@ -33,7 +30,18 @@ export { ## error: The error why the plugin aborted. ## ## msg: More detailed error description. - global Openflow::ryu_error: event(flow_mod: ofp_flow_mod, error: RyuError, msg: string &default=""); + global OpenflowRyu::error: event(flow_mod: Openflow::ofp_flow_mod, error: Error, msg: string &default=""); + + ## Ryu controller constructor. + ## + ## ip: Controller ip. + ## + ## port_: Controller listen port. + ## + ## dpid: Openflow switch datapath id. + ## + ## Returns: Openflow::Controller record + global new: function(ip: addr, port_: count, dpid: count): Openflow::Controller; } @@ -62,7 +70,7 @@ type ryu_flow_action_output: record { # https://media.readthedocs.org/pdf/ryu/latest/ryu.pdf # on page 278-299 (30.10.2014) # Ryu ReST API flow_mod type. -type ryu_flow_mod: record { +type ryu_ofp_flow_mod: record { dpid: count; cookie: count &optional; cookie_mask: count &optional; @@ -77,82 +85,73 @@ type ryu_flow_mod: record { }; -# Hook to register the Ryu openflow plugin's flow_mod function -# as the one the openflow framework should use. -hook register_openflow_plugin() +# Ryu flow_mod function +function flow_mod(state: Openflow::ControllerState, flow_mod: Openflow::ofp_flow_mod): bool { - register_openflow_mod_func( - function(dpid: count, flow_mod: ofp_flow_mod): bool + # Generate ryu_flow_actions because their type differs (using strings as type). + local _flow_actions: vector of ryu_flow_action_output; + for(i in flow_mod$actions) + { + switch(flow_mod$actions[i]$type_) { - # Check if the controller_ip has been redefined. - if(controller_ip == "0.0.0.0") - { - Reporter::warning("The constant Openflow::controller_ip must be redefined"); - event Openflow::ryu_error(flow_mod, CONTROLLER_IP_REDEF, cat(controller_ip)); + case Openflow::OFPAT_OUTPUT: + _flow_actions[|_flow_actions|] = ryu_flow_action_output($_port=flow_mod$actions[i]$port_); + break; + default: + Reporter::warning(fmt("The given Openflow action type '%s' is not available", flow_mod$actions[i]$type_)); + event OpenflowRyu::error(flow_mod, ACTION_TYPE_NOT_AVAILABLE, cat(flow_mod$actions[i]$type_)); return F; - } - # Generate ryu_flow_actions because their type differs (using strings as type). - local _flow_actions: vector of ryu_flow_action_output; - for(i in flow_mod$actions) - { - switch(flow_mod$actions[i]$_type) - { - case OFPAT_OUTPUT: - _flow_actions[|_flow_actions|] = ryu_flow_action_output($_port=flow_mod$actions[i]$_port); - break; - default: - Reporter::warning(fmt("The given Openflow action type '%s' is not available", flow_mod$actions[i]$_type)); - event Openflow::ryu_error(flow_mod, ACTION_TYPE_NOT_AVAILABLE, cat(flow_mod$actions[i]$_type)); - return F; - } - } - # Generate our ryu_flow_mod record for the ReST API call. - local _flow_mod: ryu_flow_mod = ryu_flow_mod( - $dpid=dpid, - $cookie=generate_cookie(flow_mod$cookie), - $idle_timeout=flow_mod$idle_timeout, - $hard_timeout=flow_mod$hard_timeout, - $match=flow_mod$match, - $actions=_flow_actions - ); - # Type of the command - local command_type: string; - switch(flow_mod$command) - { - case OFPFC_ADD: - command_type = "add"; - break; - case OFPFC_DELETE: - command_type = "delete"; - break; - default: - Reporter::warning(fmt("The given Openflow command type '%s' is not available", cat(flow_mod$command))); - event Openflow::ryu_error(flow_mod, COMMAND_TYPE_NOT_AVAILABLE, cat(flow_mod$command)); - return F; - } - # Create the ActiveHTTP request and convert the record to a Ryu ReST API JSON string - local request: ActiveHTTP::Request = ActiveHTTP::Request( - $url=cat("http://", controller_ip, ":", controller_port, RYU_FLOWENTRY_PATH, command_type), - $method="POST", - $client_data=JSON::convert(_flow_mod) - ); - # Execute call to Ryu's ReST API - when(local result = ActiveHTTP::request(request)) - { - if(result$code == 200) - event Openflow::flow_mod_success(flow_mod, result$body); - else - { - Reporter::warning(fmt("Flow modification failed with error: %s", result$body)); - event Openflow::flow_mod_failure(flow_mod, result$body); - return F; - } - } - - return T; } + } + # Generate our ryu_flow_mod record for the ReST API call. + local _flow_mod: ryu_ofp_flow_mod = ryu_ofp_flow_mod( + $dpid=state$dpid, + $cookie=Openflow::generate_cookie(flow_mod$cookie), + $idle_timeout=flow_mod$idle_timeout, + $hard_timeout=flow_mod$hard_timeout, + $match=flow_mod$match, + $actions=_flow_actions ); + # Type of the command + local command_type: string; + switch(flow_mod$command) + { + case Openflow::OFPFC_ADD: + command_type = "add"; + break; + case Openflow::OFPFC_DELETE: + command_type = "delete"; + break; + default: + Reporter::warning(fmt("The given Openflow command type '%s' is not available", cat(flow_mod$command))); + event OpenflowRyu::error(flow_mod, COMMAND_TYPE_NOT_AVAILABLE, cat(flow_mod$command)); + return F; + } + # Create the ActiveHTTP request and convert the record to a Ryu ReST API JSON string + local request: ActiveHTTP::Request = ActiveHTTP::Request( + $url=cat("http://", cat(state$ip), ":", cat(state$port_), RYU_FLOWENTRY_PATH, command_type), + $method="POST", + $client_data=OpenflowJSON::convert(_flow_mod) + ); + # Execute call to Ryu's ReST API + when(local result = ActiveHTTP::request(request)) + { + if(result$code == 200) + event Openflow::flow_mod_success(flow_mod, result$body); + else + { + Reporter::warning(fmt("Flow modification failed with error: %s", result$body)); + event Openflow::flow_mod_failure(flow_mod, result$body); + return F; + } + } - # TODO: implement when a JSON -> record converter exists - # register_openflow_stats_func(); + return T; } + + +# Ryu controller constructor +function new(ip: addr, port_: count, dpid: count): Openflow::Controller + { + return [$state=[$ip=ip, $port_=port_, $type_=Openflow::RYU, $dpid=dpid], $flow_mod=flow_mod]; + } \ No newline at end of file diff --git a/scripts/base/frameworks/openflow/utils/json.bro b/scripts/base/frameworks/openflow/utils/json.bro index 7ec77fdb60..b29619afc3 100644 --- a/scripts/base/frameworks/openflow/utils/json.bro +++ b/scripts/base/frameworks/openflow/utils/json.bro @@ -1,6 +1,6 @@ @load base/utils/strings -module JSON; +module OpenflowJSON; export { ## A function to convert arbitrary Bro data into a JSON string. @@ -72,7 +72,7 @@ function convert(v: any, only_loggable: bool &default=F, field_escape_pattern: p field = cat(sub(field, field_escape_pattern, "")); if ( field_desc?$value && (!only_loggable || field_desc$log) ) { - local onepart = cat("\"", field, "\": ", JSON::convert(field_desc$value, only_loggable)); + local onepart = cat("\"", field, "\": ", OpenflowJSON::convert(field_desc$value, only_loggable)); rec_parts[|rec_parts|] = onepart; } } @@ -86,7 +86,7 @@ function convert(v: any, only_loggable: bool &default=F, field_escape_pattern: p local sa: set[bool] = v; for ( sv in sa ) { - set_parts[|set_parts|] = JSON::convert(sv, only_loggable); + set_parts[|set_parts|] = OpenflowJSON::convert(sv, only_loggable); } return cat("[", join_string_vec(set_parts, ", "), "]"); } @@ -96,9 +96,9 @@ function convert(v: any, only_loggable: bool &default=F, field_escape_pattern: p local ta: table[bool] of any = v; for ( ti in ta ) { - local ts = JSON::convert(ti); + local ts = OpenflowJSON::convert(ti); local if_quotes = (ts[0] == "\"") ? "" : "\""; - tab_parts[|tab_parts|] = cat(if_quotes, ts, if_quotes, ": ", JSON::convert(ta[ti], only_loggable)); + tab_parts[|tab_parts|] = cat(if_quotes, ts, if_quotes, ": ", OpenflowJSON::convert(ta[ti], only_loggable)); } return cat("{", join_string_vec(tab_parts, ", "), "}"); } @@ -108,7 +108,7 @@ function convert(v: any, only_loggable: bool &default=F, field_escape_pattern: p local va: vector of any = v; for ( vi in va ) { - vec_parts[|vec_parts|] = JSON::convert(va[vi], only_loggable); + vec_parts[|vec_parts|] = OpenflowJSON::convert(va[vi], only_loggable); } return cat("[", join_string_vec(vec_parts, ", "), "]"); } diff --git a/scripts/site/openflow-shunt.bro b/scripts/site/openflow-shunt.bro index 0a46b14a4d..193f80e4f2 100644 --- a/scripts/site/openflow-shunt.bro +++ b/scripts/site/openflow-shunt.bro @@ -2,8 +2,10 @@ @load base/frameworks/notice @load base/frameworks/openflow + module OpenflowShunt; + # pox # global param_dpid = "00-24-a8-5c-0c-00|15" &redef; # global param_port = "\"OFPP_ALL\"" &redef; @@ -12,7 +14,6 @@ module OpenflowShunt; # default constants which are not automatically gathered. -redef Openflow::controller_ip = "10.255.0.20"; const dpid = 4222282094087168; const cookie = 0; const idle_timeout = 30; @@ -38,6 +39,7 @@ export { function size_callback(c: connection, cnt: count): interval { + local controller = OpenflowRyu::new(10.255.0.20, 8080, dpid); # print Openflow::flow_stats(dpid); # if traffic exceeds the given threshold, remove flow. if ( c$orig$num_bytes_ip + c$resp$num_bytes_ip >= size_threshold ) @@ -45,8 +47,8 @@ function size_callback(c: connection, cnt: count): interval # create openflow flow_mod add records from connection data and give default constants local actions: vector of Openflow::ofp_action_output; local reverse_actions: vector of Openflow::ofp_action_output; - actions[|actions|] = Openflow::ofp_action_output($_port=out_port); - reverse_actions[|reverse_actions|] = Openflow::ofp_action_output($_port=in_port); + actions[|actions|] = Openflow::ofp_action_output($port_=out_port); + reverse_actions[|reverse_actions|] = Openflow::ofp_action_output($port_=in_port); # flow layer 4 protocol local nw_proto = Openflow::IP_TCP; if(is_udp_port(c$id$orig_p)) @@ -93,9 +95,8 @@ function size_callback(c: connection, cnt: count): interval ]; # call openflow framework - if(Openflow::flow_mod(dpid, flow_mod) && Openflow::flow_mod(dpid, reverse_flow_mod)) { + if(Openflow::flow_mod(controller, flow_mod) && Openflow::flow_mod(controller, reverse_flow_mod)) event shunt_triggered(c); - } if(delete_flow) { @@ -132,7 +133,7 @@ event Openflow::flow_mod_failure(flow_mod: Openflow::ofp_flow_mod, msg: string) } -event Openflow::ryu_error(flow_mod: Openflow::ofp_flow_mod, error: Openflow::RyuError, msg: string) +event OpenflowRyu::error(flow_mod: Openflow::ofp_flow_mod, error: OpenflowRyu::Error, msg: string) { print fmt("ERROR: %s, msg: %s\n%s", error, msg, flow_mod); } From df12384758814394fd51c3bc000b502c3e608f29 Mon Sep 17 00:00:00 2001 From: Christian Struck Date: Mon, 1 Dec 2014 10:16:38 -0800 Subject: [PATCH 11/93] [ADD] base pacf framework and shunt script. It seems that there is a bug where things are loaded in the wrong way. --- scripts/base/frameworks/pacf/__load__.bro | 1 + scripts/base/frameworks/pacf/main.bro | 111 ++++++++++++++++++ .../base/frameworks/pacf/plugins/__load__.bro | 1 + .../base/frameworks/pacf/plugins/openflow.bro | 111 ++++++++++++++++++ scripts/site/pacf-openflow-shunt.bro | 109 +++++++++++++++++ 5 files changed, 333 insertions(+) create mode 100644 scripts/base/frameworks/pacf/__load__.bro create mode 100644 scripts/base/frameworks/pacf/main.bro create mode 100644 scripts/base/frameworks/pacf/plugins/__load__.bro create mode 100644 scripts/base/frameworks/pacf/plugins/openflow.bro create mode 100644 scripts/site/pacf-openflow-shunt.bro diff --git a/scripts/base/frameworks/pacf/__load__.bro b/scripts/base/frameworks/pacf/__load__.bro new file mode 100644 index 0000000000..d551be57d3 --- /dev/null +++ b/scripts/base/frameworks/pacf/__load__.bro @@ -0,0 +1 @@ +@load ./main \ No newline at end of file diff --git a/scripts/base/frameworks/pacf/main.bro b/scripts/base/frameworks/pacf/main.bro new file mode 100644 index 0000000000..8500f89772 --- /dev/null +++ b/scripts/base/frameworks/pacf/main.bro @@ -0,0 +1,111 @@ +@load ./plugins + + +module PACF; + + +# Internal id counter for rule ids. +global LAST_ID:count = 0; + + +export { + + ## Type of the action. + ## + type RuleActionType: enum { + ## Drop packets matching a given RuleMatch record. + DROP, + ## Modify packets matching a given RuleMatch record + ## according to the ModifyArgs record. + MODIFY, + } &redef; + + + type RuleActionTarget: enum { + FORWARD, + MONITOR, + } &redef; + + ## Uni or bidriectional flow. + ## + type FlowType: enum { + ## Unidirectional flow. + PACF::UNIDIRECTIONAL, + ## Bidirectional flow. + PACF::BIDIRECTIONAL, + }; + + ## Properties which descibes a matching flow / connection + ## + type RuleMatch: record { + ## Ethernet protocol (ipv4, ipv6, ipip ... aso). + # eth_proto: ethernet_proto &optional; # Here should mb IPPROTO_* be used. + ## VLAN id. + vlan: count &optional; + ## Source MAC address. + src_mac: string &optional; + ## Source IP address (IPv4 | IPv6). + src_ip: addr &optional; + ## Source Port. + src_port: port &optional; + ## Destination MAC address. + dst_mac: string &optional; + ## Destination IP address. + dst_ip: addr &optional; + ## Destination Port. + dst_port: port &optional; + ## IP transport protocol. + ip_proto: transport_proto &optional; # Here should mb IPPROTO_* be used. + }; + + ## Action to be done on flows / connections that match. + ## + type RuleAction: record { + type_: RuleActionType; + target: RuleActionTarget &default=FORWARD; + ## Timeout n seconds after the last packet. + soft_timeout: count &optional; + ## Timeout after n seconds. + hard_timeout: count &optional; + ## Priority of the action. + priority: int &default=-0; + }; + + ## Rule which descibes the actions to take on a matching + ## flow / connection. + type Rule: record { + ## Rule id. + id: count &default=LAST_ID; + ## Flows / Connections which the rule should match. + match: RuleMatch; + ## Actions which will be taken when a flow / connection matches. + action: vector of RuleAction; + ## Should it be matched uni or bidriectional. + direction: FlowType; + }; + + ## Registered plugins + type Plugin: enum { + }; + + + type BackendState: record { + + } &redef; + + + ## A PACF backend which implements a subset of the PACF + ## features for a specific implementation + type Backend: record { + ## The type of the plugin (more then one of the same type can exist). + type_: Plugin; + ## Insert function to apply a specific rule + insert: function(state: PACF::BackendState, rule: PACF::Rule): bool &optional; + ## Remove function to remove a specific rule + remove: function(id: count): bool &optional; + state: BackendState &optional; + } &redef; + + global PACF::drop: event(); + global PACF::undrop: event(); +} diff --git a/scripts/base/frameworks/pacf/plugins/__load__.bro b/scripts/base/frameworks/pacf/plugins/__load__.bro new file mode 100644 index 0000000000..2b1a02132c --- /dev/null +++ b/scripts/base/frameworks/pacf/plugins/__load__.bro @@ -0,0 +1 @@ +@load ./openflow \ No newline at end of file diff --git a/scripts/base/frameworks/pacf/plugins/openflow.bro b/scripts/base/frameworks/pacf/plugins/openflow.bro new file mode 100644 index 0000000000..a3aa6414d8 --- /dev/null +++ b/scripts/base/frameworks/pacf/plugins/openflow.bro @@ -0,0 +1,111 @@ +@load ../main +@load base/frameworks/openflow + + +module PACFOpenflow; + + +export { + redef enum PACF::Plugin += { + PACF::OPENFLOW, + }; + + redef record PACF::BackendState += { + openflow_controller: Openflow::Controller &optional; + }; + + global new: function(controller: Openflow::Controller): PACF::Backend; +} + + +function insert(state: PACF::BackendState, rule: PACF::Rule): bool + { + for(i in rule$action) + { + switch(rule$action[i]$type_) + { + case PACF::DROP: + if(!state?$openflow_controller) + { + Reporter::warning(fmt("The given PACF::Backend %s is not an PACFOpenflow backend", cat(state))); + return F; + } + + # Create openflow records + local nw_proto = Openflow::IP_TCP; + if(rule$match$ip_proto == udp) + nw_proto = Openflow::IP_UDP; + else if(rule$match$ip_proto == icmp) + nw_proto = Openflow::IP_ICMP; + + local match: Openflow::ofp_match = [ + $in_port=state$openflow_controller$state$port_state[rule$match$src_ip], + $nw_src=rule$match$src_ip, + $nw_dst=rule$match$dst_ip, + $nw_proto=nw_proto, + $tp_src=rule$match$src_port, + $tp_dst=rule$match$dst_port + ]; + + local flow_mod: Openflow::ofp_flow_mod = [ + $match=match, + #$cookie=cookie, + $idle_timeout=30, + $hard_timeout=0, + # No action means drop. + $actions=vector() + ]; + + if(rule$direction == PACF::BIDIRECTIONAL) + { + local reverse_match: Openflow::ofp_match = [ + $in_port=state$openflow_controller$state$port_state[rule$match$dst_ip], + $nw_src=rule$match$dst_ip, + $nw_dst=rule$match$src_ip, + $nw_proto=nw_proto, + $tp_src=rule$match$dst_port, + $tp_dst=rule$match$src_port + ]; + + local reverse_flow_mod: Openflow::ofp_flow_mod = [ + $match=reverse_match, + #$cookie=cookie, + $idle_timeout=30, + $hard_timeout=0, + # No action means drop. + $actions=vector() + ]; + } + + if(rule$action[i]$target == PACF::MONITOR) + { + local action: vector of Openflow::ofp_action_output; + action[|action|] = Openflow::ofp_action_output($port_=state$openflow_controller$state$port_state[rule$match$dst_ip]); + flow_mod$actions=action; + + if(rule$direction == PACF::BIDIRECTIONAL) + { + local reverse_action: vector of Openflow::ofp_action_output; + reverse_action[|reverse_action|] = Openflow::ofp_action_output($port_=state$openflow_controller$state$port_state[rule$match$src_ip]); + reverse_flow_mod$actions=reverse_action; + } + } + + if(rule$direction == PACF::BIDIRECTIONAL) + return Openflow::flow_mod(state$openflow_controller, flow_mod) && Openflow::flow_mod(state$openflow_controller, reverse_flow_mod); + else + return Openflow::flow_mod(state$openflow_controller, flow_mod); + break; + default: + Reporter::warning(fmt("The PACF ActionType %s is not supported by this plugin", cat(rule$action[i]$type_))); + break; + } + } + return F; + } + + +function new(controller: Openflow::Controller): PACF::Backend + { + return [$type_=PACF::OPENFLOW, $state=[$openflow_controller=controller], $insert=insert]; + } diff --git a/scripts/site/pacf-openflow-shunt.bro b/scripts/site/pacf-openflow-shunt.bro new file mode 100644 index 0000000000..52f8eed8c1 --- /dev/null +++ b/scripts/site/pacf-openflow-shunt.bro @@ -0,0 +1,109 @@ +@load base/protocols/conn +@load base/frameworks/notice +@load base/frameworks/pacf/main +@load base/frameworks/openflow + + +module PACFOpenflowShunt; + + +# pox +# global param_dpid = "00-24-a8-5c-0c-00|15" &redef; +# global param_port = "\"OFPP_ALL\"" &redef; +# global of_ctrl_uri = "http://10.255.0.20:8080/OF/" &redef; +# const cmd = "curl -i -X POST -d '{\"method\":\"set_table\",\"params\":{\"dpid\":\"%s\",\"flows\":[{\"actions\":[{\"type\":\"OFPAT_OUTPUT\",\"port\":%s}],\"match\":{%s}}]}}' %s"; + + +# default constants which are not automatically gathered. +const dpid = 4222282094087168; +const cookie = 0; +const idle_timeout = 30; +const hard_timeout = 0; +const in_port = 3; +const out_port = 1; +global delete_flow: bool = F; + + +export { + ## Number of bytes transferred before shunting a flow. + const size_threshold = 1024000 &redef; + + ## Base amount of time between checking + const poll_interval = 1sec &redef; + + ## Raised when a shunt happened. + ## + ## c: The connection pertaining to the data channel. + global shunt_triggered: event(c: connection); +} + + +function size_callback(c: connection, cnt: count): interval + { + local controller = OpenflowRyu::new(10.255.0.20, 8080, dpid); + controller$state$port_state[10.15.0.30/32] = 3; + controller$state$port_state[10.15.0.31/32] = 1; + local pacf_backend = PACFOpenflow::new(controller); + # print Openflow::flow_stats(dpid); + # if traffic exceeds the given threshold, remove flow. + if ( c$orig$num_bytes_ip + c$resp$num_bytes_ip >= size_threshold ) + { + # create openflow flow_mod add records from connection data and give default constants + local action: vector of PACF::RuleAction; + action[|action|] = [ + $type_=DROP, + $target=MONITOR + ]; + + local ip_proto = tcp; + if(is_udp_port(c$id$orig_p)) + ip_proto = udp; + else if(is_icmp_port(c$id$orig_p)) + ip_proto = icmp; + + local match: PACF::RuleMatch = [ + $src_ip=c$id$resp_h, + $dst_ip=c$id$orig_h, + $ip_proto=ip_proto, + $src_port=c$id$resp_p, + $dst_port=c$id$orig_p + ]; + + local rule: PACF::Rule = [ + $match=match, + $action=action, + $direction=PACF::BIDIRECITONAL + ]; + + if(pacf_backend$insert(pacf_backend, rule) + event shunt_triggered(c); + + return -1sec; + } + return poll_interval; + } + + +event connection_established(c: connection) + { + print fmt("new connection"); + ConnPolling::watch(c, size_callback, 0, 0secs); + } + + +event Openflow::flow_mod_success(flow_mod: Openflow::ofp_flow_mod, msg: string) + { + print fmt("succsess, %s", cat(flow_mod)); + } + + +event Openflow::flow_mod_failure(flow_mod: Openflow::ofp_flow_mod, msg: string) + { + print fmt("failed, %s", cat(flow_mod)); + } + + +event OpenflowRyu::error(flow_mod: Openflow::ofp_flow_mod, error: OpenflowRyu::Error, msg: string) + { + print fmt("ERROR: %s, msg: %s\n%s", error, msg, flow_mod); + } From fe5408e676fd3db035b793047477f91975be4ae1 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Mon, 6 Apr 2015 15:03:26 -0700 Subject: [PATCH 12/93] as a first step, restructure things a bit and remove the site scripts users have to suply --- scripts/base/frameworks/openflow/__load__.bro | 3 +- scripts/base/frameworks/openflow/consts.bro | 337 ++++++++++++++++++ scripts/base/frameworks/openflow/main.bro | 246 +------------ .../base/frameworks/openflow/plugins/ryu.bro | 21 +- .../base/frameworks/openflow/utils/const.bro | 104 ------ scripts/site/openflow-shunt.bro | 139 -------- scripts/site/pacf-openflow-shunt.bro | 109 ------ 7 files changed, 353 insertions(+), 606 deletions(-) create mode 100644 scripts/base/frameworks/openflow/consts.bro delete mode 100644 scripts/base/frameworks/openflow/utils/const.bro delete mode 100644 scripts/site/openflow-shunt.bro delete mode 100644 scripts/site/pacf-openflow-shunt.bro diff --git a/scripts/base/frameworks/openflow/__load__.bro b/scripts/base/frameworks/openflow/__load__.bro index c468d055ee..377ed8fa48 100644 --- a/scripts/base/frameworks/openflow/__load__.bro +++ b/scripts/base/frameworks/openflow/__load__.bro @@ -1,2 +1,3 @@ +@load ./consts @load ./main -@load ./plugins \ No newline at end of file +@load ./plugins diff --git a/scripts/base/frameworks/openflow/consts.bro b/scripts/base/frameworks/openflow/consts.bro new file mode 100644 index 0000000000..0e08e11a47 --- /dev/null +++ b/scripts/base/frameworks/openflow/consts.bro @@ -0,0 +1,337 @@ +# 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 + ## Maximum number of physical switch ports. + const OFPP_MAX = 0xff00; + ## 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 = 0xfff8; + ## Perform actions in flow table. + ## NB: This can only be the destination port + ## for packet-out messages. + const OFPP_TABLE = 0xfff9; + ## Process with normal L2/L3 switching. + const OFPP_NORMAL = 0xfffa; + ## All pysical ports except input port and + ## those disabled by STP. + const OFPP_FLOOD = 0xfffb; + ## All pysical ports except input port. + const OFPP_ALL = 0xfffc; + ## Send to controller. + const OFPP_CONTROLLER = 0xfffd; + ## Local openflow "port". + const OFPP_LOCAL = 0xfffe; + ## Not associated with a pysical port. + const OFPP_NONE = 0xffff; + + ## 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, + }; + + ## Openflow match definition. + ## + ## The openflow match record describes + ## which packets match to a specific + ## rule in a flow table. + type ofp_match: record { + # Wildcard fields. + #wildcards: count &optional; + # 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 &default=ETH_IPv4; + # IP ToS (actually DSCP field, 6bits). + nw_tos: count &optional; + # IP protocol or lower 8 bits of ARP opcode. + nw_proto: count &default=IP_TCP; + # IP source address. + nw_src: addr &optional; + # IP destination address. + nw_dst: addr &optional; + # TCP/UDP source port. + tp_src: port &optional; + # TCP/UDP destination port. + tp_dst: port &optional; + }; + + ## Openflow actions definition. + ## + ## A action describes what should + ## happen with packets of the matching + ## flow. + type ofp_action_output: record { + ## this should never change, but there are not + ## constants available in records + ## defaults to OFPAT_OUTPUT + type_: ofp_action_type &default=OFPAT_OUTPUT; + #_len: count &default=8; + ## Output port. + port_: count &default=OFPP_FLOOD; + #_max_len: count &optional; + }; + + # Openflow flow_mod_flags definition + ## 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; + + ## Openflow flow_mod definition. + ## It describes the flow to match and + ## how it should be modified. + type ofp_flow_mod: record { + # header: ofp_header; + ## Fields to match + match: ofp_match; + ## Opaque controller-issued identifier. + cookie: count &default=BRO_COOKIE_ID * COOKIE_BID_START; + # Flow actions + ## One of OFPFC_*. + command: ofp_flow_mod_command &default=OFPFC_ADD; + ## Idle time before discarding (seconds). + idle_timeout: count &optional; + ## Max time before discarding (seconds). + hard_timeout: count &optional; + ## Priority level of flow entry. + priority: count &optional; + ## Buffered packet to apply to (or -1). + ## Not meaningful for OFPFC_DELETE*. + buffer_id: count &optional; + ## For OFPFC_DELETE* commands, require + ## matching entries to include this as an + ## output port. A value of OFPP_NONE + ## indicates no restrictions. + out_port: count &optional; + ## One of OFPFF_*. + flags: count &optional; + ## A list of actions to perform. + actions: vector of ofp_action_output; + }; + + ## Body of reply to OFPST_FLOW request. + type ofp_flow_stats: record { + ## Length of this entry + _length: count; + ## ID of table flow came from. + table_id: count; + ## Description of fields. + match: ofp_match; + ## Time flow has been alive in seconds. + duration_sec: count; + ## Time flow has been alive in nanoseconds beyond + ## duration_sec. + duration_nsec: count; + ## Priority of the entry. Only meaningful + ## when this is not an exact-match entry. + priority: count; + ## Number of seconds idle before expiration. + idle_timeout: count; + ## Number of seconds before expiration. + hard_timeout: count; + ## Opaque controller-issued identifier. + cookie: count; + ## Number of packets in flow. + packet_count: count; + ## Number of bytes in flow. + byte_count: count; + ## Actions + actions: vector of ofp_action_output; + }; +} diff --git a/scripts/base/frameworks/openflow/main.bro b/scripts/base/frameworks/openflow/main.bro index 198374a3bb..6681229419 100644 --- a/scripts/base/frameworks/openflow/main.bro +++ b/scripts/base/frameworks/openflow/main.bro @@ -1,244 +1,8 @@ -@load ./utils/const.bro - +@load ./consts 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 { - ## 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 - ## Maximum number of physical switch ports. - const OFPP_MAX = 0xff00; - ## 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 = 0xfff8; - ## Perform actions in flow table. - ## NB: This can only be the destination port - ## for packet-out messages. - const OFPP_TABLE = 0xfff9; - ## Process with normal L2/L3 switching. - const OFPP_NORMAL = 0xfffa; - ## All pysical ports except input port and - ## those disabled by STP. - const OFPP_FLOOD = 0xfffb; - ## All pysical ports except input port. - const OFPP_ALL = 0xfffc; - ## Send to controller. - const OFPP_CONTROLLER = 0xfffd; - ## Local openflow "port". - const OFPP_LOCAL = 0xfffe; - ## Not associated with a pysical port. - const OFPP_NONE = 0xffff; - - ## 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, - }; - - ## Openflow match definition. - ## - ## The openflow match record describes - ## which packets match to a specific - ## rule in a flow table. - type ofp_match: record { - # Wildcard fields. - #wildcards: count &optional; - # 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 &default=ETH_IPv4; - # IP ToS (actually DSCP field, 6bits). - nw_tos: count &optional; - # IP protocol or lower 8 bits of ARP opcode. - nw_proto: count &default=IP_TCP; - # IP source address. - nw_src: addr &optional; - # IP destination address. - nw_dst: addr &optional; - # TCP/UDP source port. - tp_src: port &optional; - # TCP/UDP destination port. - tp_dst: port &optional; - }; - - ## Openflow actions definition. - ## - ## A action describes what should - ## happen with packets of the matching - ## flow. - type ofp_action_output: record { - ## this should never change, but there are not - ## constants available in records - ## defaults to OFPAT_OUTPUT - type_: ofp_action_type &default=OFPAT_OUTPUT; - #_len: count &default=8; - ## Output port. - port_: count &default=OFPP_FLOOD; - #_max_len: count &optional; - }; - - # Openflow flow_mod_flags definition - ## 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; - - ## Openflow flow_mod definition. - ## It describes the flow to match and - ## how it should be modified. - type ofp_flow_mod: record { - # header: ofp_header; - ## Fields to match - match: ofp_match; - ## Opaque controller-issued identifier. - cookie: count &default=BRO_COOKIE_ID * COOKIE_BID_START; - # Flow actions - ## One of OFPFC_*. - command: ofp_flow_mod_command &default=OFPFC_ADD; - ## Idle time befor discarding (seconds). - idle_timeout: count &optional; - ## Max time before discarding (seconds). - hard_timeout: count &optional; - ## Priority level of flow entry. - priority: count &optional; - ## Buffered packet to apply to (or -1). - ## Not meaningful for OFPFC_DELETE*. - buffer_id: count &optional; - ## For OFPFC_DELETE* commands, require - ## matching entries to include this as an - ## output port. A value of OFPP_NONE - ## indicates no restrictions. - out_port: count &optional; - ## One of OFPFF_*. - flags: count &optional; - ## A list of actions to perform. - actions: vector of ofp_action_output; - }; - - ## Body of reply to OFPST_FLOW request. - type ofp_flow_stats: record { - ## Length of this entry - _length: count; - ## ID of table flow came from. - table_id: count; - ## Description of fields. - match: ofp_match; - ## Time flow has been alive in seconds. - duration_sec: count; - ## Time flow has been alive in nanoseconds beyond - ## duration_sec. - duration_nsec: count; - ## Priority of the entry. Only meaningful - ## when this is not an exact-match entry. - priority: count; - ## Number of seconds idle before expiration. - idle_timeout: count; - ## Number of seconds before expiration. - hard_timeout: count; - ## Opaque controller-issued identifier. - cookie: count; - ## Number of packets in flow. - packet_count: count; - ## Number of bytes in flow. - byte_count: count; - ## Actions - actions: vector of ofp_action_output; - }; - ## Function to get the unique id out of a given cookie. ## ## cookie: The openflow match cookie. @@ -253,7 +17,7 @@ export { ## Returns: The cookie group id. global get_cookie_gid: function(cookie: count): count; - ## Function to get the group id out of a given cookie. + ## Function to generate a new cookie using our group id. ## ## cookie: The openflow match cookie. ## @@ -286,9 +50,9 @@ export { ## add state. type ControllerState: record { ## Controller ip. - ip: addr &optional; + host: addr &optional; ## Controller listen port. - port_: count &optional; + host_port: count &optional; ## Openflow switch datapath id. dpid: count &optional; ## Type of the openflow plugin. @@ -302,7 +66,7 @@ export { ## flow_mod function the plugin implements flow_mod: function(state: ControllerState, flow_mod: ofp_flow_mod): bool; ## flow_stats function the plugin implements if existing - flow_stats: function(state: ControllerState): vector of ofp_flow_stats &optional; + ## flow_stats: function(state: ControllerState): vector of ofp_flow_stats &optional; }; ## Global flow_mod function wrapper diff --git a/scripts/base/frameworks/openflow/plugins/ryu.bro b/scripts/base/frameworks/openflow/plugins/ryu.bro index 156168782e..acf44d37da 100644 --- a/scripts/base/frameworks/openflow/plugins/ryu.bro +++ b/scripts/base/frameworks/openflow/plugins/ryu.bro @@ -1,12 +1,10 @@ -@load ../main -@load ../utils/json +@load base/frameworks/openflow +@load base/frameworks/openflow/utils/json @load base/utils/exec @load base/utils/active-http - module OpenflowRyu; - export { redef enum Openflow::Plugin += { Openflow::RYU, @@ -34,14 +32,14 @@ export { ## Ryu controller constructor. ## - ## ip: Controller ip. + ## host: Controller ip. ## - ## port_: Controller listen port. + ## host_port: Controller listen port. ## ## dpid: Openflow switch datapath id. ## ## Returns: Openflow::Controller record - global new: function(ip: addr, port_: count, dpid: count): Openflow::Controller; + global new: function(host: addr, host_port: count, dpid: count): Openflow::Controller; } @@ -129,7 +127,7 @@ function flow_mod(state: Openflow::ControllerState, flow_mod: Openflow::ofp_flow } # Create the ActiveHTTP request and convert the record to a Ryu ReST API JSON string local request: ActiveHTTP::Request = ActiveHTTP::Request( - $url=cat("http://", cat(state$ip), ":", cat(state$port_), RYU_FLOWENTRY_PATH, command_type), + $url=cat("http://", cat(state$host), ":", cat(state$host_port), RYU_FLOWENTRY_PATH, command_type), $method="POST", $client_data=OpenflowJSON::convert(_flow_mod) ); @@ -149,9 +147,8 @@ function flow_mod(state: Openflow::ControllerState, flow_mod: Openflow::ofp_flow return T; } - # Ryu controller constructor -function new(ip: addr, port_: count, dpid: count): Openflow::Controller +function new(host: addr, host_port: count, dpid: count): Openflow::Controller { - return [$state=[$ip=ip, $port_=port_, $type_=Openflow::RYU, $dpid=dpid], $flow_mod=flow_mod]; - } \ No newline at end of file + return [$state=[$host=host, $host_port=host_port, $type_=Openflow::RYU, $dpid=dpid], $flow_mod=flow_mod]; + } diff --git a/scripts/base/frameworks/openflow/utils/const.bro b/scripts/base/frameworks/openflow/utils/const.bro deleted file mode 100644 index 18c79eb28e..0000000000 --- a/scripts/base/frameworks/openflow/utils/const.bro +++ /dev/null @@ -1,104 +0,0 @@ -# All types/constants not specific to Openflow will be defined here -# unitl they somehow get into bro. - -module Openflow; - -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; -#}; -} \ No newline at end of file diff --git a/scripts/site/openflow-shunt.bro b/scripts/site/openflow-shunt.bro deleted file mode 100644 index 193f80e4f2..0000000000 --- a/scripts/site/openflow-shunt.bro +++ /dev/null @@ -1,139 +0,0 @@ -@load base/protocols/conn -@load base/frameworks/notice -@load base/frameworks/openflow - - -module OpenflowShunt; - - -# pox -# global param_dpid = "00-24-a8-5c-0c-00|15" &redef; -# global param_port = "\"OFPP_ALL\"" &redef; -# global of_ctrl_uri = "http://10.255.0.20:8080/OF/" &redef; -# const cmd = "curl -i -X POST -d '{\"method\":\"set_table\",\"params\":{\"dpid\":\"%s\",\"flows\":[{\"actions\":[{\"type\":\"OFPAT_OUTPUT\",\"port\":%s}],\"match\":{%s}}]}}' %s"; - - -# default constants which are not automatically gathered. -const dpid = 4222282094087168; -const cookie = 0; -const idle_timeout = 30; -const hard_timeout = 0; -const in_port = 3; -const out_port = 1; -global delete_flow: bool = F; - - -export { - ## Number of bytes transferred before shunting a flow. - const size_threshold = 1024000 &redef; - - ## Base amount of time between checking - const poll_interval = 1sec &redef; - - ## Raised when a shunt happened. - ## - ## c: The connection pertaining to the data channel. - global shunt_triggered: event(c: connection); -} - - -function size_callback(c: connection, cnt: count): interval - { - local controller = OpenflowRyu::new(10.255.0.20, 8080, dpid); - # print Openflow::flow_stats(dpid); - # if traffic exceeds the given threshold, remove flow. - if ( c$orig$num_bytes_ip + c$resp$num_bytes_ip >= size_threshold ) - { - # create openflow flow_mod add records from connection data and give default constants - local actions: vector of Openflow::ofp_action_output; - local reverse_actions: vector of Openflow::ofp_action_output; - actions[|actions|] = Openflow::ofp_action_output($port_=out_port); - reverse_actions[|reverse_actions|] = Openflow::ofp_action_output($port_=in_port); - # flow layer 4 protocol - local nw_proto = Openflow::IP_TCP; - if(is_udp_port(c$id$orig_p)) - nw_proto = Openflow::IP_UDP; - else if(is_icmp_port(c$id$orig_p)) - nw_proto = Openflow::IP_ICMP; - - local match: Openflow::ofp_match = [ - $in_port=in_port, - $nw_src=c$id$orig_h, - $nw_dst=c$id$resp_h, - $nw_proto=nw_proto, - $tp_src=c$id$orig_p, - $tp_dst=c$id$resp_p - ]; - - local reverse_match: Openflow::ofp_match = [ - $in_port=out_port, - $nw_src=c$id$resp_h, - $nw_dst=c$id$orig_h, - $nw_proto=nw_proto, - $tp_src=c$id$resp_p, - $tp_dst=c$id$orig_p - ]; - - local command = Openflow::OFPFC_ADD; - if(delete_flow) - command = Openflow::OFPFC_DELETE; - local flow_mod: Openflow::ofp_flow_mod = [ - $match=match, - $cookie=cookie, - $command=command, - $idle_timeout=idle_timeout, - $hard_timeout=hard_timeout, - $actions=actions - ]; - local reverse_flow_mod: Openflow::ofp_flow_mod = [ - $match=reverse_match, - $cookie=cookie, - $command=command, - $idle_timeout=idle_timeout, - $hard_timeout=hard_timeout, - $actions=reverse_actions - ]; - - # call openflow framework - if(Openflow::flow_mod(controller, flow_mod) && Openflow::flow_mod(controller, reverse_flow_mod)) - event shunt_triggered(c); - - if(delete_flow) - { - delete_flow = F; - return -1sec; - } - else - { - delete_flow = T; - return 15sec; - } - } - - return poll_interval; - } - - -event connection_established(c: connection) - { - print fmt("new connection"); - ConnPolling::watch(c, size_callback, 0, 0secs); - } - - -event Openflow::flow_mod_success(flow_mod: Openflow::ofp_flow_mod, msg: string) - { - print fmt("succsess, %s", cat(flow_mod)); - } - - -event Openflow::flow_mod_failure(flow_mod: Openflow::ofp_flow_mod, msg: string) - { - print fmt("failed, %s", cat(flow_mod)); - } - - -event OpenflowRyu::error(flow_mod: Openflow::ofp_flow_mod, error: OpenflowRyu::Error, msg: string) - { - print fmt("ERROR: %s, msg: %s\n%s", error, msg, flow_mod); - } diff --git a/scripts/site/pacf-openflow-shunt.bro b/scripts/site/pacf-openflow-shunt.bro deleted file mode 100644 index 52f8eed8c1..0000000000 --- a/scripts/site/pacf-openflow-shunt.bro +++ /dev/null @@ -1,109 +0,0 @@ -@load base/protocols/conn -@load base/frameworks/notice -@load base/frameworks/pacf/main -@load base/frameworks/openflow - - -module PACFOpenflowShunt; - - -# pox -# global param_dpid = "00-24-a8-5c-0c-00|15" &redef; -# global param_port = "\"OFPP_ALL\"" &redef; -# global of_ctrl_uri = "http://10.255.0.20:8080/OF/" &redef; -# const cmd = "curl -i -X POST -d '{\"method\":\"set_table\",\"params\":{\"dpid\":\"%s\",\"flows\":[{\"actions\":[{\"type\":\"OFPAT_OUTPUT\",\"port\":%s}],\"match\":{%s}}]}}' %s"; - - -# default constants which are not automatically gathered. -const dpid = 4222282094087168; -const cookie = 0; -const idle_timeout = 30; -const hard_timeout = 0; -const in_port = 3; -const out_port = 1; -global delete_flow: bool = F; - - -export { - ## Number of bytes transferred before shunting a flow. - const size_threshold = 1024000 &redef; - - ## Base amount of time between checking - const poll_interval = 1sec &redef; - - ## Raised when a shunt happened. - ## - ## c: The connection pertaining to the data channel. - global shunt_triggered: event(c: connection); -} - - -function size_callback(c: connection, cnt: count): interval - { - local controller = OpenflowRyu::new(10.255.0.20, 8080, dpid); - controller$state$port_state[10.15.0.30/32] = 3; - controller$state$port_state[10.15.0.31/32] = 1; - local pacf_backend = PACFOpenflow::new(controller); - # print Openflow::flow_stats(dpid); - # if traffic exceeds the given threshold, remove flow. - if ( c$orig$num_bytes_ip + c$resp$num_bytes_ip >= size_threshold ) - { - # create openflow flow_mod add records from connection data and give default constants - local action: vector of PACF::RuleAction; - action[|action|] = [ - $type_=DROP, - $target=MONITOR - ]; - - local ip_proto = tcp; - if(is_udp_port(c$id$orig_p)) - ip_proto = udp; - else if(is_icmp_port(c$id$orig_p)) - ip_proto = icmp; - - local match: PACF::RuleMatch = [ - $src_ip=c$id$resp_h, - $dst_ip=c$id$orig_h, - $ip_proto=ip_proto, - $src_port=c$id$resp_p, - $dst_port=c$id$orig_p - ]; - - local rule: PACF::Rule = [ - $match=match, - $action=action, - $direction=PACF::BIDIRECITONAL - ]; - - if(pacf_backend$insert(pacf_backend, rule) - event shunt_triggered(c); - - return -1sec; - } - return poll_interval; - } - - -event connection_established(c: connection) - { - print fmt("new connection"); - ConnPolling::watch(c, size_callback, 0, 0secs); - } - - -event Openflow::flow_mod_success(flow_mod: Openflow::ofp_flow_mod, msg: string) - { - print fmt("succsess, %s", cat(flow_mod)); - } - - -event Openflow::flow_mod_failure(flow_mod: Openflow::ofp_flow_mod, msg: string) - { - print fmt("failed, %s", cat(flow_mod)); - } - - -event OpenflowRyu::error(flow_mod: Openflow::ofp_flow_mod, error: OpenflowRyu::Error, msg: string) - { - print fmt("ERROR: %s, msg: %s\n%s", error, msg, flow_mod); - } From 4195a0066ab437d9b82cbab7771bd6827e4d7fde Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 7 Apr 2015 10:43:36 -0700 Subject: [PATCH 13/93] move the json stuff into utils - I guess we will need functionality like this not just for openflow at some point of time. --- .../base/frameworks/openflow/plugins/ryu.bro | 6 +-- .../{frameworks/openflow => }/utils/json.bro | 39 +++++++------------ 2 files changed, 18 insertions(+), 27 deletions(-) rename scripts/base/{frameworks/openflow => }/utils/json.bro (76%) diff --git a/scripts/base/frameworks/openflow/plugins/ryu.bro b/scripts/base/frameworks/openflow/plugins/ryu.bro index acf44d37da..3721126754 100644 --- a/scripts/base/frameworks/openflow/plugins/ryu.bro +++ b/scripts/base/frameworks/openflow/plugins/ryu.bro @@ -1,7 +1,7 @@ @load base/frameworks/openflow -@load base/frameworks/openflow/utils/json -@load base/utils/exec @load base/utils/active-http +@load base/utils/exec +@load base/utils/json module OpenflowRyu; @@ -129,7 +129,7 @@ function flow_mod(state: Openflow::ControllerState, flow_mod: Openflow::ofp_flow local request: ActiveHTTP::Request = ActiveHTTP::Request( $url=cat("http://", cat(state$host), ":", cat(state$host_port), RYU_FLOWENTRY_PATH, command_type), $method="POST", - $client_data=OpenflowJSON::convert(_flow_mod) + $client_data=to_json(_flow_mod) ); # Execute call to Ryu's ReST API when(local result = ActiveHTTP::request(request)) diff --git a/scripts/base/frameworks/openflow/utils/json.bro b/scripts/base/utils/json.bro similarity index 76% rename from scripts/base/frameworks/openflow/utils/json.bro rename to scripts/base/utils/json.bro index b29619afc3..f872ecac44 100644 --- a/scripts/base/frameworks/openflow/utils/json.bro +++ b/scripts/base/utils/json.bro @@ -1,6 +1,8 @@ -@load base/utils/strings +##! Functions to assist with generating JSON data from Bro data scructures. -module OpenflowJSON; +# We might want to implement this in core somtime, this looks... hacky at best. + +@load base/utils/strings export { ## A function to convert arbitrary Bro data into a JSON string. @@ -11,20 +13,9 @@ export { ## fields with the &log attribute to be included in the JSON. ## ## returns: a JSON formatted string. - global convert: function(v: any, only_loggable: bool &default=F, field_escape_pattern: pattern &default=/^_/): string; - - global jsonToRecord: function(input: string): any; + global to_json: function(v: any, only_loggable: bool &default=F, field_escape_pattern: pattern &default=/^_/): string; } -function jsonToRecord(input: string): any - { - local lhs: table[count] of string; - lhs = split1(input, / /); - for (i in lhs) - print lhs[i]; - return lhs; - } - function convert(v: any, only_loggable: bool &default=F, field_escape_pattern: pattern &default=/^_/): string { local tn = type_name(v); @@ -39,7 +30,7 @@ function convert(v: any, only_loggable: bool &default=F, field_escape_pattern: p case "port": return cat(port_to_count(to_port(cat(v)))); - case "addr": + case "addr": return cat("\"", v, "\""); case "int": @@ -72,21 +63,21 @@ function convert(v: any, only_loggable: bool &default=F, field_escape_pattern: p field = cat(sub(field, field_escape_pattern, "")); if ( field_desc?$value && (!only_loggable || field_desc$log) ) { - local onepart = cat("\"", field, "\": ", OpenflowJSON::convert(field_desc$value, only_loggable)); + 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 ) + for ( sv in sa ) { - set_parts[|set_parts|] = OpenflowJSON::convert(sv, only_loggable); + set_parts[|set_parts|] = to_json(sv, only_loggable); } return cat("[", join_string_vec(set_parts, ", "), "]"); } @@ -94,11 +85,11 @@ function convert(v: any, only_loggable: bool &default=F, field_escape_pattern: p { local tab_parts: vector of string = vector(); local ta: table[bool] of any = v; - for ( ti in ta ) + for ( ti in ta ) { - local ts = OpenflowJSON::convert(ti); + local ts = to_json(ti); local if_quotes = (ts[0] == "\"") ? "" : "\""; - tab_parts[|tab_parts|] = cat(if_quotes, ts, if_quotes, ": ", OpenflowJSON::convert(ta[ti], only_loggable)); + tab_parts[|tab_parts|] = cat(if_quotes, ts, if_quotes, ": ", to_json(ta[ti], only_loggable)); } return cat("{", join_string_vec(tab_parts, ", "), "}"); } @@ -108,10 +99,10 @@ function convert(v: any, only_loggable: bool &default=F, field_escape_pattern: p local va: vector of any = v; for ( vi in va ) { - vec_parts[|vec_parts|] = OpenflowJSON::convert(va[vi], only_loggable); + vec_parts[|vec_parts|] = to_json(va[vi], only_loggable); } return cat("[", join_string_vec(vec_parts, ", "), "]"); } - + return "\"\""; } From dbc51371cbd7d3e0a602352d94f34bacc0908bf9 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 7 Apr 2015 15:37:46 -0700 Subject: [PATCH 14/93] Rewrite big parts of the Openflow framework. The API now does not follow the openflow specification quite as closely, however I think it is much more usable. Furthermore, the Ryu plugin was basically completely rewritten and is now more usable for general flow manipulation. This also adds a debug mode that just outputs the json fragments that would be sent to ryu. At the moment, Ryu still assumes that every request that it receives succeeds - it is not possible to get an error message from the controller. Instead, one has to check if a flow was added by doing a second REST request. Which seems unnecessary, and also requires complete json parsing functionality. Hence we are not doing that at the moment. The alternative would be to use an external script for the actual add-and-check-operation. --- scripts/base/frameworks/openflow/__load__.bro | 1 + scripts/base/frameworks/openflow/consts.bro | 134 ++------------ scripts/base/frameworks/openflow/main.bro | 141 +++++++------- .../base/frameworks/openflow/plugins/ryu.bro | 172 ++++++++++-------- scripts/base/frameworks/openflow/types.bro | 111 +++++++++++ scripts/base/utils/json.bro | 23 +-- 6 files changed, 302 insertions(+), 280 deletions(-) create mode 100644 scripts/base/frameworks/openflow/types.bro diff --git a/scripts/base/frameworks/openflow/__load__.bro b/scripts/base/frameworks/openflow/__load__.bro index 377ed8fa48..64d6840c4d 100644 --- a/scripts/base/frameworks/openflow/__load__.bro +++ b/scripts/base/frameworks/openflow/__load__.bro @@ -1,3 +1,4 @@ @load ./consts +@load ./types @load ./main @load ./plugins diff --git a/scripts/base/frameworks/openflow/consts.bro b/scripts/base/frameworks/openflow/consts.bro index 0e08e11a47..776af5ad46 100644 --- a/scripts/base/frameworks/openflow/consts.bro +++ b/scripts/base/frameworks/openflow/consts.bro @@ -122,7 +122,6 @@ export { ## which is not added, modified or deleted ## from the bro openflow framework const INVALID_COOKIE = 0xffffffffffffffff; - # Openflow pysical port definitions ## Maximum number of physical switch ports. const OFPP_MAX = 0xff00; @@ -147,6 +146,17 @@ export { const OFPP_LOCAL = 0xfffe; ## Not associated with a pysical port. const OFPP_NONE = 0xffff; + # 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; ## Openflow action_type definitions ## @@ -212,126 +222,4 @@ export { OFPC_FRAG_MASK = 3, }; - ## Openflow match definition. - ## - ## The openflow match record describes - ## which packets match to a specific - ## rule in a flow table. - type ofp_match: record { - # Wildcard fields. - #wildcards: count &optional; - # 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 &default=ETH_IPv4; - # IP ToS (actually DSCP field, 6bits). - nw_tos: count &optional; - # IP protocol or lower 8 bits of ARP opcode. - nw_proto: count &default=IP_TCP; - # IP source address. - nw_src: addr &optional; - # IP destination address. - nw_dst: addr &optional; - # TCP/UDP source port. - tp_src: port &optional; - # TCP/UDP destination port. - tp_dst: port &optional; - }; - - ## Openflow actions definition. - ## - ## A action describes what should - ## happen with packets of the matching - ## flow. - type ofp_action_output: record { - ## this should never change, but there are not - ## constants available in records - ## defaults to OFPAT_OUTPUT - type_: ofp_action_type &default=OFPAT_OUTPUT; - #_len: count &default=8; - ## Output port. - port_: count &default=OFPP_FLOOD; - #_max_len: count &optional; - }; - - # Openflow flow_mod_flags definition - ## 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; - - ## Openflow flow_mod definition. - ## It describes the flow to match and - ## how it should be modified. - type ofp_flow_mod: record { - # header: ofp_header; - ## Fields to match - match: ofp_match; - ## Opaque controller-issued identifier. - cookie: count &default=BRO_COOKIE_ID * COOKIE_BID_START; - # Flow actions - ## One of OFPFC_*. - command: ofp_flow_mod_command &default=OFPFC_ADD; - ## Idle time before discarding (seconds). - idle_timeout: count &optional; - ## Max time before discarding (seconds). - hard_timeout: count &optional; - ## Priority level of flow entry. - priority: count &optional; - ## Buffered packet to apply to (or -1). - ## Not meaningful for OFPFC_DELETE*. - buffer_id: count &optional; - ## For OFPFC_DELETE* commands, require - ## matching entries to include this as an - ## output port. A value of OFPP_NONE - ## indicates no restrictions. - out_port: count &optional; - ## One of OFPFF_*. - flags: count &optional; - ## A list of actions to perform. - actions: vector of ofp_action_output; - }; - - ## Body of reply to OFPST_FLOW request. - type ofp_flow_stats: record { - ## Length of this entry - _length: count; - ## ID of table flow came from. - table_id: count; - ## Description of fields. - match: ofp_match; - ## Time flow has been alive in seconds. - duration_sec: count; - ## Time flow has been alive in nanoseconds beyond - ## duration_sec. - duration_nsec: count; - ## Priority of the entry. Only meaningful - ## when this is not an exact-match entry. - priority: count; - ## Number of seconds idle before expiration. - idle_timeout: count; - ## Number of seconds before expiration. - hard_timeout: count; - ## Opaque controller-issued identifier. - cookie: count; - ## Number of packets in flow. - packet_count: count; - ## Number of bytes in flow. - byte_count: count; - ## Actions - actions: vector of ofp_action_output; - }; } diff --git a/scripts/base/frameworks/openflow/main.bro b/scripts/base/frameworks/openflow/main.bro index 6681229419..6132731f03 100644 --- a/scripts/base/frameworks/openflow/main.bro +++ b/scripts/base/frameworks/openflow/main.bro @@ -1,8 +1,59 @@ -@load ./consts +##! 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. + ## + ## 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(match: ofp_match, flow_mod: ofp_flow_mod, msg: string &default=""); + + ## Reports an error while installing a flow Rule. + ## + ## 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(match: ofp_match, flow_mod: ofp_flow_mod, msg: string &default=""); + + # ### + # ### Low-level functions for cookie handling. + # ### + ## Function to get the unique id out of a given cookie. ## ## cookie: The openflow match cookie. @@ -23,69 +74,24 @@ export { ## ## Returns: The cookie group id. global generate_cookie: function(cookie: count &default=0): count; - - ## Event to signal that a flow has been successfully modified. - ## - ## flow_mod: The openflow flow_mod record which describes - ## the flow to delete, modify or add. - ## - ## msg: Message to describe the event. - global Openflow::flow_mod_success: event(flow_mod: ofp_flow_mod, msg: string &default="Flow successfully modified"); - - ## Event to signal that a flow mod has failed. - ## - ## flow_mod: The openflow flow_mod record which describes - ## the flow to delete, modify or add. - ## - ## msg: Message to describe the event. - global Openflow::flow_mod_failure: event(flow_mod: ofp_flow_mod, msg: string &default="Could not modify flow"); - - ## Available openflow plugins - type Plugin: enum { - PLACEHOLDER, - }; - - ## Controller related state. - ## Can be redefined by plugins to - ## add state. - type ControllerState: record { - ## Controller ip. - host: addr &optional; - ## Controller listen port. - host_port: count &optional; - ## Openflow switch datapath id. - dpid: count &optional; - ## Type of the openflow plugin. - type_: Plugin; - } &redef; - - ## Controller record representing an openflow controller - type Controller: record { - ## Controller related state. - state: ControllerState; - ## flow_mod function the plugin implements - flow_mod: function(state: ControllerState, flow_mod: ofp_flow_mod): bool; - ## flow_stats function the plugin implements if existing - ## flow_stats: function(state: ControllerState): vector of ofp_flow_stats &optional; - }; - - ## Global flow_mod function wrapper - ## - ## controller: The controller which should execute the flow modification - ## - ## flow_mod: The openflow flow_mod record which describes - ## the flow to delete, modify or add - ## - ## Returns: T if successfull, else F - global flow_mod: function(controller: Controller, flow_mod: ofp_flow_mod): bool; } # the flow_mod function wrapper -function flow_mod(controller: Controller, flow_mod: ofp_flow_mod): bool +function flow_mod(controller: Controller, match: ofp_match, flow_mod: ofp_flow_mod): bool { - return controller$flow_mod(controller$state, flow_mod); + if ( controller?$flow_mod ) + return controller$flow_mod(controller$state, match, flow_mod); + else + return F; } +function flow_clear(controller: Controller): bool + { + if ( controller?$flow_clear ) + return controller$flow_clear(controller$state); + else + return F; + } # local function to forge a flow_mod cookie for this framework. # all flow entries from the openflow framework should have the @@ -93,39 +99,42 @@ function flow_mod(controller: Controller, flow_mod: ofp_flow_mod): bool function generate_cookie(cookie: count &default=0): count { local c = BRO_COOKIE_ID * COOKIE_BID_START; - if(cookie >= COOKIE_UID_SIZE) + + 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 +function is_valid_cookie(cookie: count): bool { - if (cookie / COOKIE_BID_START == BRO_COOKIE_ID) + 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)) + 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)) + 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; } diff --git a/scripts/base/frameworks/openflow/plugins/ryu.bro b/scripts/base/frameworks/openflow/plugins/ryu.bro index 3721126754..feab410c86 100644 --- a/scripts/base/frameworks/openflow/plugins/ryu.bro +++ b/scripts/base/frameworks/openflow/plugins/ryu.bro @@ -3,33 +3,13 @@ @load base/utils/exec @load base/utils/json -module OpenflowRyu; +module Openflow; export { - redef enum Openflow::Plugin += { - Openflow::RYU, + redef enum Plugin += { + RYU, }; - ## Ryu error definitions. - type Error: enum { - ## The openflow command type is not available - ## for this ryu openflow plugin. - COMMAND_TYPE_NOT_AVAILABLE, - ## The openflow action type is not available - ## for this ryu openflow plugin. - ACTION_TYPE_NOT_AVAILABLE, - }; - - ## Ryu error event. - ## - ## flow_mod: The openflow flow_mod record which describes - ## the flow to delete, modify or add. - ## - ## error: The error why the plugin aborted. - ## - ## msg: More detailed error description. - global OpenflowRyu::error: event(flow_mod: Openflow::ofp_flow_mod, error: Error, msg: string &default=""); - ## Ryu controller constructor. ## ## host: Controller ip. @@ -39,34 +19,35 @@ export { ## dpid: Openflow switch datapath id. ## ## Returns: Openflow::Controller record - global new: function(host: addr, host_port: count, dpid: count): Openflow::Controller; + 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; + }; } - -# Openflow no buffer constant. -const OFP_NO_BUFFER = 0xffffffff; - - # 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/"; - +#const RYU_FLOWSTATS_PATH = "/stats/flow/"; # Ryu ReST API action_output type. -type ryu_flow_action_output: record { +type ryu_flow_action: record { # Ryu uses strings as its ReST API output action. - # The type should be never changed... - # but constants are not possible in a record. - _type: string &default="OUTPUT"; - # The output port - _port: count; + _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 -# on page 278-299 (30.10.2014) # Ryu ReST API flow_mod type. type ryu_ofp_flow_mod: record { dpid: count; @@ -76,70 +57,84 @@ type ryu_ofp_flow_mod: record { idle_timeout: count &optional; hard_timeout: count &optional; priority: count &optional; - buffer_id: count &optional; flags: count &optional; match: Openflow::ofp_match; - actions: vector of ryu_flow_action_output; + actions: vector of ryu_flow_action; }; +# 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 flow_mod(state: Openflow::ControllerState, flow_mod: Openflow::ofp_flow_mod): bool +function ryu_flow_mod(state: Openflow::ControllerState, match: ofp_match, flow_mod: Openflow::ofp_flow_mod): bool { - # Generate ryu_flow_actions because their type differs (using strings as type). - local _flow_actions: vector of ryu_flow_action_output; - for(i in flow_mod$actions) + if ( state$_plugin != RYU ) { - switch(flow_mod$actions[i]$type_) - { - case Openflow::OFPAT_OUTPUT: - _flow_actions[|_flow_actions|] = ryu_flow_action_output($_port=flow_mod$actions[i]$port_); - break; - default: - Reporter::warning(fmt("The given Openflow action type '%s' is not available", flow_mod$actions[i]$type_)); - event OpenflowRyu::error(flow_mod, ACTION_TYPE_NOT_AVAILABLE, cat(flow_mod$actions[i]$type_)); - return F; - } + 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$out_ports ) + flow_actions[|flow_actions|] = ryu_flow_action($_type="OUTPUT", $_port=flow_mod$out_ports[i]); + # Generate our ryu_flow_mod record for the ReST API call. - local _flow_mod: ryu_ofp_flow_mod = ryu_ofp_flow_mod( - $dpid=state$dpid, + local mod: ryu_ofp_flow_mod = ryu_ofp_flow_mod( + $dpid=state$ryu_dpid, $cookie=Openflow::generate_cookie(flow_mod$cookie), $idle_timeout=flow_mod$idle_timeout, $hard_timeout=flow_mod$hard_timeout, - $match=flow_mod$match, - $actions=_flow_actions + $priority=flow_mod$priority, + $flags=flow_mod$flags, + $match=match, + $actions=flow_actions ); + # Type of the command local command_type: string; - switch(flow_mod$command) - { - case Openflow::OFPFC_ADD: - command_type = "add"; - break; - case Openflow::OFPFC_DELETE: - command_type = "delete"; - break; - default: + + 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))); - event OpenflowRyu::error(flow_mod, COMMAND_TYPE_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(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=cat("http://", cat(state$host), ":", cat(state$host_port), RYU_FLOWENTRY_PATH, command_type), + $url=url, $method="POST", - $client_data=to_json(_flow_mod) + $client_data=to_json(mod) ); + # Execute call to Ryu's ReST API - when(local result = ActiveHTTP::request(request)) + when ( local result = ActiveHTTP::request(request) ) { if(result$code == 200) - event Openflow::flow_mod_success(flow_mod, result$body); + event Openflow::flow_mod_success(match, flow_mod, result$body); else { Reporter::warning(fmt("Flow modification failed with error: %s", result$body)); - event Openflow::flow_mod_failure(flow_mod, result$body); + event Openflow::flow_mod_failure(match, flow_mod, result$body); return F; } } @@ -147,8 +142,31 @@ function flow_mod(state: Openflow::ControllerState, flow_mod: Openflow::ofp_flow return T; } -# Ryu controller constructor -function new(host: addr, host_port: count, dpid: count): Openflow::Controller +function ryu_flow_clear(state: Openflow::ControllerState): bool { - return [$state=[$host=host, $host_port=host_port, $type_=Openflow::RYU, $dpid=dpid], $flow_mod=flow_mod]; + 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; + } + +# Ryu controller constructor +function ryu_new(host: addr, host_port: count, dpid: count): Openflow::Controller + { + return [$state=[$ryu_host=host, $ryu_port=host_port, $ryu_dpid=dpid, $_plugin=Openflow::RYU], + $flow_mod=ryu_flow_mod, $flow_clear=ryu_flow_clear]; } diff --git a/scripts/base/frameworks/openflow/types.bro b/scripts/base/frameworks/openflow/types.bro new file mode 100644 index 0000000000..24f4e49562 --- /dev/null +++ b/scripts/base/frameworks/openflow/types.bro @@ -0,0 +1,111 @@ +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 plugin used. + _plugin: Plugin; + } &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; + # IP source address. + nw_src: addr &optional; + # IP destination address. + nw_dst: addr &optional; + # TCP/UDP source port. + tp_src: port &optional; + # TCP/UDP destination port. + tp_dst: port &optional; + }; + + ## 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 + ## 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; + ## Bitmap of the OFPFF_* flags + flags: count &default=0; + ## Output ports to send data to. + out_ports: vector of count &default=vector(); + }; + +# Functionality using this is currently not implemented. At all. +# ## Body of reply to OFPST_FLOW request. +# type ofp_flow_stats: record { +# ## ID of table flow came from. +# table_id: count; +# ## Description of fields. +# match: ofp_match; +# ## Time flow has been alive in seconds. +# duration_sec: count; +# ## Time flow has been alive in nanoseconds beyond +# ## duration_sec. +# duration_nsec: count; +# ## Priority of the entry. Only meaningful +# ## when this is not an exact-match entry. +# priority: count; +# ## Number of seconds idle before expiration. +# idle_timeout: count; +# ## Number of seconds before expiration. +# hard_timeout: count; +# ## Opaque controller-issued identifier. +# cookie: count; +# ## Number of packets in flow. +# packet_count: count; +# ## Number of bytes in flow. +# byte_count: count; +# ## Actions +# actions: vector of ofp_action_output; +# }; + + ## Controller record representing an openflow controller + type Controller: record { + ## Controller related state. + state: ControllerState; + ## 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/utils/json.bro b/scripts/base/utils/json.bro index f872ecac44..8ac25e3283 100644 --- a/scripts/base/utils/json.bro +++ b/scripts/base/utils/json.bro @@ -1,22 +1,17 @@ ##! 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 -export { - ## 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. - global to_json: function(v: any, only_loggable: bool &default=F, field_escape_pattern: pattern &default=/^_/): string; -} - -function convert(v: any, only_loggable: bool &default=F, field_escape_pattern: pattern &default=/^_/): string +## 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 ) From 883da516ee5a83cf9b8fce14585f144517102dda Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 7 Apr 2015 17:27:50 -0700 Subject: [PATCH 15/93] move pacf skeleton away to be able to replace it with old proposal of Robin. --- scripts/base/frameworks/{pacf => pacf-proto}/__load__.bro | 0 scripts/base/frameworks/{pacf => pacf-proto}/main.bro | 0 scripts/base/frameworks/{pacf => pacf-proto}/plugins/__load__.bro | 0 scripts/base/frameworks/{pacf => pacf-proto}/plugins/openflow.bro | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename scripts/base/frameworks/{pacf => pacf-proto}/__load__.bro (100%) rename scripts/base/frameworks/{pacf => pacf-proto}/main.bro (100%) rename scripts/base/frameworks/{pacf => pacf-proto}/plugins/__load__.bro (100%) rename scripts/base/frameworks/{pacf => pacf-proto}/plugins/openflow.bro (100%) diff --git a/scripts/base/frameworks/pacf/__load__.bro b/scripts/base/frameworks/pacf-proto/__load__.bro similarity index 100% rename from scripts/base/frameworks/pacf/__load__.bro rename to scripts/base/frameworks/pacf-proto/__load__.bro diff --git a/scripts/base/frameworks/pacf/main.bro b/scripts/base/frameworks/pacf-proto/main.bro similarity index 100% rename from scripts/base/frameworks/pacf/main.bro rename to scripts/base/frameworks/pacf-proto/main.bro diff --git a/scripts/base/frameworks/pacf/plugins/__load__.bro b/scripts/base/frameworks/pacf-proto/plugins/__load__.bro similarity index 100% rename from scripts/base/frameworks/pacf/plugins/__load__.bro rename to scripts/base/frameworks/pacf-proto/plugins/__load__.bro diff --git a/scripts/base/frameworks/pacf/plugins/openflow.bro b/scripts/base/frameworks/pacf-proto/plugins/openflow.bro similarity index 100% rename from scripts/base/frameworks/pacf/plugins/openflow.bro rename to scripts/base/frameworks/pacf-proto/plugins/openflow.bro From 70f6635cb16308ef054845b97dfe4a0a846f750a Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Fri, 10 Apr 2015 11:19:09 -0700 Subject: [PATCH 16/93] do not load pacf by default. There is some recursive record definition in there Bro does not like too much... --- scripts/base/init-default.bro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/base/init-default.bro b/scripts/base/init-default.bro index c3e868e48f..0615ce36ef 100644 --- a/scripts/base/init-default.bro +++ b/scripts/base/init-default.bro @@ -37,7 +37,7 @@ @load base/frameworks/reporter @load base/frameworks/sumstats @load base/frameworks/tunnels -@load base/frameworks/pacf +#@load base/frameworks/pacf @load base/protocols/conn @load base/protocols/dhcp From 46058d0b02ca2b17e6fd88657998ad1ae5d413d7 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Fri, 10 Apr 2015 11:20:36 -0700 Subject: [PATCH 17/93] a few small fixes to openflow *rename module from Openflow to OpenFlow *add match_conn function to convert conn_id to openflow match *add a few things back into the openflow records like... table_id *and - a test --- scripts/base/frameworks/openflow/consts.bro | 2 +- scripts/base/frameworks/openflow/main.bro | 58 ++++++++++++++++++- .../base/frameworks/openflow/plugins/ryu.bro | 30 +++++----- scripts/base/frameworks/openflow/types.bro | 10 +++- .../.stdout | 7 +++ .../base/frameworks/openflow/ryu-basic.bro | 32 ++++++++++ 6 files changed, 120 insertions(+), 19 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.frameworks.openflow.ryu-basic/.stdout create mode 100644 testing/btest/scripts/base/frameworks/openflow/ryu-basic.bro diff --git a/scripts/base/frameworks/openflow/consts.bro b/scripts/base/frameworks/openflow/consts.bro index 776af5ad46..c2e890ea48 100644 --- a/scripts/base/frameworks/openflow/consts.bro +++ b/scripts/base/frameworks/openflow/consts.bro @@ -1,7 +1,7 @@ # All types/constants not specific to Openflow will be defined here # unitl they somehow get into bro. -module Openflow; +module OpenFlow; # Some cookie specific constants. # first 24 bits diff --git a/scripts/base/frameworks/openflow/main.bro b/scripts/base/frameworks/openflow/main.bro index 6132731f03..3e2f3eca36 100644 --- a/scripts/base/frameworks/openflow/main.bro +++ b/scripts/base/frameworks/openflow/main.bro @@ -8,7 +8,7 @@ ##! for shunting, please look at the PACF framework, which provides higher ##! level functions and can use the OpenFlow framework as a backend. -module Openflow; +module OpenFlow; @load ./consts @load ./types @@ -50,6 +50,16 @@ export { ## msg: Message to describe the event. global flow_mod_failure: event(match: ofp_match, flow_mod: ofp_flow_mod, msg: string &default=""); + ## 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. # ### @@ -76,6 +86,7 @@ export { global generate_cookie: function(cookie: count &default=0): count; } + # the flow_mod function wrapper function flow_mod(controller: Controller, match: ofp_match, flow_mod: ofp_flow_mod): bool { @@ -93,6 +104,49 @@ function flow_clear(controller: Controller): bool return F; } +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$resp_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=orig_h, + $tp_src=orig_p, + $nw_dst=resp_h, + $tp_dst=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. @@ -131,7 +185,7 @@ function get_cookie_gid(cookie: count): count { if( is_valid_cookie(cookie) ) return ( - (cookie - (COOKIE_BID_START * BRO_COOKIE_ID) - + (cookie - (COOKIE_BID_START * BRO_COOKIE_ID) - (cookie - ((cookie / COOKIE_GID_START) * COOKIE_GID_START))) / COOKIE_GID_START ); diff --git a/scripts/base/frameworks/openflow/plugins/ryu.bro b/scripts/base/frameworks/openflow/plugins/ryu.bro index feab410c86..181c9d89be 100644 --- a/scripts/base/frameworks/openflow/plugins/ryu.bro +++ b/scripts/base/frameworks/openflow/plugins/ryu.bro @@ -3,7 +3,7 @@ @load base/utils/exec @load base/utils/json -module Openflow; +module OpenFlow; export { redef enum Plugin += { @@ -16,17 +16,17 @@ export { ## ## host_port: Controller listen port. ## - ## dpid: Openflow switch datapath id. + ## dpid: OpenFlow switch datapath id. ## - ## Returns: Openflow::Controller record - global ryu_new: function(host: addr, host_port: count, dpid: count): Openflow::Controller; + ## 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. + ## OpenFlow switch datapath id. ryu_dpid: count &optional; ## Enable debug mode - output JSON to stdout; do not perform actions ryu_debug: bool &default=F; @@ -58,7 +58,7 @@ type ryu_ofp_flow_mod: record { hard_timeout: count &optional; priority: count &optional; flags: count &optional; - match: Openflow::ofp_match; + match: OpenFlow::ofp_match; actions: vector of ryu_flow_action; }; @@ -72,7 +72,7 @@ const ryu_url: table[ofp_flow_mod_command] of string = { }; # Ryu flow_mod function -function ryu_flow_mod(state: Openflow::ControllerState, match: ofp_match, flow_mod: Openflow::ofp_flow_mod): bool +function ryu_flow_mod(state: OpenFlow::ControllerState, match: ofp_match, flow_mod: OpenFlow::ofp_flow_mod): bool { if ( state$_plugin != RYU ) { @@ -89,7 +89,7 @@ function ryu_flow_mod(state: Openflow::ControllerState, match: ofp_match, flow_m # 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=Openflow::generate_cookie(flow_mod$cookie), + $cookie=OpenFlow::generate_cookie(flow_mod$cookie), $idle_timeout=flow_mod$idle_timeout, $hard_timeout=flow_mod$hard_timeout, $priority=flow_mod$priority, @@ -105,7 +105,7 @@ function ryu_flow_mod(state: Openflow::ControllerState, match: ofp_match, flow_m command_type = ryu_url[flow_mod$command]; else { - Reporter::warning(fmt("The given Openflow command type '%s' is not available", cat(flow_mod$command))); + Reporter::warning(fmt("The given OpenFlow command type '%s' is not available", cat(flow_mod$command))); return F; } @@ -115,7 +115,7 @@ function ryu_flow_mod(state: Openflow::ControllerState, match: ofp_match, flow_m { print url; print to_json(mod); - event Openflow::flow_mod_success(match, flow_mod); + event OpenFlow::flow_mod_success(match, flow_mod); return T; } @@ -130,11 +130,11 @@ function ryu_flow_mod(state: Openflow::ControllerState, match: ofp_match, flow_m when ( local result = ActiveHTTP::request(request) ) { if(result$code == 200) - event Openflow::flow_mod_success(match, flow_mod, result$body); + event OpenFlow::flow_mod_success(match, flow_mod, result$body); else { Reporter::warning(fmt("Flow modification failed with error: %s", result$body)); - event Openflow::flow_mod_failure(match, flow_mod, result$body); + event OpenFlow::flow_mod_failure(match, flow_mod, result$body); return F; } } @@ -142,7 +142,7 @@ function ryu_flow_mod(state: Openflow::ControllerState, match: ofp_match, flow_m return T; } -function ryu_flow_clear(state: Openflow::ControllerState): bool +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); @@ -165,8 +165,8 @@ function ryu_flow_clear(state: Openflow::ControllerState): bool } # Ryu controller constructor -function ryu_new(host: addr, host_port: count, dpid: count): Openflow::Controller +function ryu_new(host: addr, host_port: count, dpid: count): OpenFlow::Controller { - return [$state=[$ryu_host=host, $ryu_port=host_port, $ryu_dpid=dpid, $_plugin=Openflow::RYU], + return [$state=[$ryu_host=host, $ryu_port=host_port, $ryu_dpid=dpid, $_plugin=OpenFlow::RYU], $flow_mod=ryu_flow_mod, $flow_clear=ryu_flow_clear]; } diff --git a/scripts/base/frameworks/openflow/types.bro b/scripts/base/frameworks/openflow/types.bro index 24f4e49562..e979ec75a5 100644 --- a/scripts/base/frameworks/openflow/types.bro +++ b/scripts/base/frameworks/openflow/types.bro @@ -1,4 +1,4 @@ -module Openflow; +module OpenFlow; @load ./consts @@ -39,6 +39,8 @@ export { 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: addr &optional; # IP destination address. @@ -56,6 +58,9 @@ export { # 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). @@ -64,6 +69,9 @@ export { 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. OFPP_ANY means no restrictions. + out_group: count &optional; ## Bitmap of the OFPFF_* flags flags: count &default=0; ## Output ports to send data to. 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..5ef044f707 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.openflow.ryu-basic/.stdout @@ -0,0 +1,7 @@ +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} +http://127.0.0.1:8080/stats/flowentry/add +{"match": {"tp_dst": 25, "nw_dst": "74.53.140.153", "nw_src": "10.10.1.4", "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": 25, "nw_dst": "10.10.1.4", "nw_src": "74.53.140.153", "dl_type": 2048, "tp_src": 25, "nw_proto": 6}, "dpid": 42, "flags": 0, "hard_timeout": 0, "priority": 5, "actions": [], "cookie": 4398046511146, "idle_timeout": 30} 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..319567fa6a --- /dev/null +++ b/testing/btest/scripts/base/frameworks/openflow/ryu-basic.bro @@ -0,0 +1,32 @@ +# @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=1, $command=OpenFlow::OFPFC_ADD, $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=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); + } From 21b78b7d927f4353b4daf0072990b7b339fd7acc Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Mon, 13 Apr 2015 12:54:33 -0700 Subject: [PATCH 18/93] add really simple log output plugin for openflow. --- .../frameworks/openflow/plugins/__load__.bro | 3 +- .../base/frameworks/openflow/plugins/log.bro | 59 +++++++++++++++++++ scripts/base/frameworks/openflow/types.bro | 4 +- .../openflow.log | 12 ++++ .../base/frameworks/openflow/log-basic.bro | 30 ++++++++++ 5 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 scripts/base/frameworks/openflow/plugins/log.bro create mode 100644 testing/btest/Baseline/scripts.base.frameworks.openflow.log-basic/openflow.log create mode 100644 testing/btest/scripts/base/frameworks/openflow/log-basic.bro diff --git a/scripts/base/frameworks/openflow/plugins/__load__.bro b/scripts/base/frameworks/openflow/plugins/__load__.bro index c45aa9544e..bf83a61648 100644 --- a/scripts/base/frameworks/openflow/plugins/__load__.bro +++ b/scripts/base/frameworks/openflow/plugins/__load__.bro @@ -1 +1,2 @@ -@load ./ryu \ No newline at end of file +@load ./ryu +@load ./log diff --git a/scripts/base/frameworks/openflow/plugins/log.bro b/scripts/base/frameworks/openflow/plugins/log.bro new file mode 100644 index 0000000000..0914654e06 --- /dev/null +++ b/scripts/base/frameworks/openflow/plugins/log.bro @@ -0,0 +1,59 @@ +##! OpenFlow module that outputs flow-modification commands +##! to a Bro log file. + +module OpenFlow; + +@load base/frameworks/openflow +@load base/frameworks/logging + +export { + redef enum Plugin += { + LOG, + }; + + ## Log controller constructor. + ## + ## dpid: OpenFlow switch datapath id. + ## + ## Returns: OpenFlow::Controller record + global log_new: function(dpid: count): OpenFlow::Controller; + + redef record ControllerState += { + ## OpenFlow switch datapath id. + log_dpid: count &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(LOG, [$columns=Info, $ev=log_openflow, $path="openflow"]); + } + +function log_flow_mod(state: OpenFlow::ControllerState, match: ofp_match, flow_mod: OpenFlow::ofp_flow_mod): bool + { + Log::write(LOG, [$ts=network_time(), $dpid=state$log_dpid, $match=match, $flow_mod=flow_mod]); + + return T; + } + +function log_new(dpid: count): OpenFlow::Controller + { + return [$state=[$log_dpid=dpid, $_plugin=OpenFlow::LOG], + $flow_mod=log_flow_mod, $flow_clear=ryu_flow_clear]; + } diff --git a/scripts/base/frameworks/openflow/types.bro b/scripts/base/frameworks/openflow/types.bro index e979ec75a5..a70bfb345c 100644 --- a/scripts/base/frameworks/openflow/types.bro +++ b/scripts/base/frameworks/openflow/types.bro @@ -49,7 +49,7 @@ export { tp_src: port &optional; # TCP/UDP destination port. tp_dst: port &optional; - }; + } &log; ## Openflow flow_mod definition, describing the action to perform. type ofp_flow_mod: record { @@ -76,7 +76,7 @@ export { flags: count &default=0; ## Output ports to send data to. out_ports: vector of count &default=vector(); - }; + } &log; # Functionality using this is currently not implemented. At all. # ## Body of reply to OFPST_FLOW request. 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..99562536fd --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.openflow.log-basic/openflow.log @@ -0,0 +1,12 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path openflow +#open 2015-04-13-19-54-15 +#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_group flow_mod.flags flow_mod.out_ports +#types time count count string string count count count count count addr addr port port count count enum count count count count count vector[count] +0.000000 42 - - - - - - - - - - - - 1 - OpenFlow::OFPFC_ADD 0 0 0 - 0 3,7 +1254722767.875996 42 - - - - - 2048 - 6 10.10.1.4 74.53.140.153 1470 25 42 - OpenFlow::OFPFC_ADD 30 0 5 - 0 (empty) +1254722767.875996 42 - - - - - 2048 - 6 74.53.140.153 10.10.1.4 25 25 42 - OpenFlow::OFPFC_ADD 30 0 5 - 0 (empty) +#close 2015-04-13-19-54-15 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..ea18acb8ce --- /dev/null +++ b/testing/btest/scripts/base/frameworks/openflow/log-basic.bro @@ -0,0 +1,30 @@ +# @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; + +event bro_init() + { + of_controller = OpenFlow::log_new(42); + + OpenFlow::flow_mod(of_controller, [], [$cookie=1, $command=OpenFlow::OFPFC_ADD, $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=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); + } From 00204ab8a6adcad0d62b1e7e76945c58b738cc3d Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Mon, 13 Apr 2015 16:05:55 -0700 Subject: [PATCH 19/93] introduce &weaken attribute, which basically only prevents the describe function for types to descend into record fields that are marked with it. With this, we can actually load the pacf scripts without crashing Bro when running tests :) --- scripts/base/frameworks/pacf/plugin.bro | 4 ++-- scripts/base/init-default.bro | 3 ++- src/Attr.cc | 7 ++++++- src/Attr.h | 3 ++- src/Type.cc | 10 ++++++++-- src/parse.y | 6 ++++-- src/scan.l | 1 + 7 files changed, 25 insertions(+), 9 deletions(-) diff --git a/scripts/base/frameworks/pacf/plugin.bro b/scripts/base/frameworks/pacf/plugin.bro index 944705605f..ab25911d14 100644 --- a/scripts/base/frameworks/pacf/plugin.bro +++ b/scripts/base/frameworks/pacf/plugin.bro @@ -84,8 +84,8 @@ export { # 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; + ## because of cyclic type dependency.) + plugin: Plugin &optional &weaken; }; } diff --git a/scripts/base/init-default.bro b/scripts/base/init-default.bro index 0615ce36ef..16650017cb 100644 --- a/scripts/base/init-default.bro +++ b/scripts/base/init-default.bro @@ -37,7 +37,8 @@ @load base/frameworks/reporter @load base/frameworks/sumstats @load base/frameworks/tunnels -#@load base/frameworks/pacf +@load base/frameworks/openflow +@load base/frameworks/pacf @load base/protocols/conn @load base/protocols/dhcp diff --git a/src/Attr.cc b/src/Attr.cc index fc8d3000d1..8b451ca5b1 100644 --- a/src/Attr.cc +++ b/src/Attr.cc @@ -18,7 +18,7 @@ const char* attr_name(attr_tag t) "&encrypt", "&raw_output", "&mergeable", "&priority", "&group", "&log", "&error_handler", "&type_column", - "(&tracked)", "&deprecated", + "(&tracked)", "&deprecated", "&weaken", }; return attr_names[int(t)]; @@ -436,6 +436,11 @@ void Attributes::CheckAttr(Attr* a) Error("&log applied to a type that cannot be logged"); break; + case ATTR_WEAKEN: + if ( ! in_record ) + Error("&weaken applied outside of record"); + break; + case ATTR_TYPE_COLUMN: { if ( type->Tag() != TYPE_PORT ) diff --git a/src/Attr.h b/src/Attr.h index 63f2524c21..f89fb9f119 100644 --- a/src/Attr.h +++ b/src/Attr.h @@ -35,7 +35,8 @@ typedef enum { ATTR_TYPE_COLUMN, // for input framework ATTR_TRACKED, // hidden attribute, tracked by NotifierRegistry ATTR_DEPRECATED, -#define NUM_ATTRS (int(ATTR_DEPRECATED) + 1) + ATTR_WEAKEN, +#define NUM_ATTRS (int(ATTR_WEAKEN) + 1) } attr_tag; class Attr : public BroObj { diff --git a/src/Type.cc b/src/Type.cc index 9aa86da8dc..891c69c50f 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -1129,7 +1129,10 @@ void RecordType::DescribeFields(ODesc* d) const const TypeDecl* td = FieldDecl(i); d->Add(td->id); d->Add(":"); - td->type->Describe(d); + if ( td->FindAttr(ATTR_WEAKEN) ) + d->Add(""); + else + td->type->Describe(d); d->Add(";"); } } @@ -1170,7 +1173,10 @@ void RecordType::DescribeFieldsReST(ODesc* d, bool func_args) const } const TypeDecl* td = FieldDecl(i); - td->DescribeReST(d); + if ( td->FindAttr(ATTR_WEAKEN) ) + d->Add(""); + else + td->DescribeReST(d); if ( func_args ) continue; diff --git a/src/parse.y b/src/parse.y index 8054718d45..a7e9eadd19 100644 --- a/src/parse.y +++ b/src/parse.y @@ -2,7 +2,7 @@ // See the file "COPYING" in the main distribution directory for copyright. %} -%expect 78 +%expect 81 %token TOK_ADD TOK_ADD_TO TOK_ADDR TOK_ANY %token TOK_ATENDIF TOK_ATELSE TOK_ATIF TOK_ATIFDEF TOK_ATIFNDEF @@ -25,7 +25,7 @@ %token TOK_ATTR_PERSISTENT TOK_ATTR_SYNCHRONIZED %token TOK_ATTR_RAW_OUTPUT TOK_ATTR_MERGEABLE %token TOK_ATTR_PRIORITY TOK_ATTR_LOG TOK_ATTR_ERROR_HANDLER -%token TOK_ATTR_TYPE_COLUMN TOK_ATTR_DEPRECATED +%token TOK_ATTR_TYPE_COLUMN TOK_ATTR_DEPRECATED TOK_ATTR_WEAKEN %token TOK_DEBUG @@ -1291,6 +1291,8 @@ attr: { $$ = new Attr(ATTR_ERROR_HANDLER); } | TOK_ATTR_DEPRECATED { $$ = new Attr(ATTR_DEPRECATED); } + | TOK_ATTR_WEAKEN + { $$ = new Attr(ATTR_WEAKEN); } ; stmt: diff --git a/src/scan.l b/src/scan.l index a6e37a67f7..8103201303 100644 --- a/src/scan.l +++ b/src/scan.l @@ -276,6 +276,7 @@ when return TOK_WHEN; &type_column return TOK_ATTR_TYPE_COLUMN; &read_expire return TOK_ATTR_EXPIRE_READ; &redef return TOK_ATTR_REDEF; +&weaken return TOK_ATTR_WEAKEN; &write_expire return TOK_ATTR_EXPIRE_WRITE; &encrypt { From fd07b0bee98973771dfffecfd976a6fdaeb7805d Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Mon, 13 Apr 2015 16:45:31 -0700 Subject: [PATCH 20/93] mainly add a small test to the pacf framework that uses the debug plugin for shunt / drop rule additions... --- .../scripts.base.frameworks.pacf.basic/.stdout | 4 ++++ .../pacf.log | 18 ++++++++++++++++++ .../scripts/base/frameworks/pacf/basic.bro | 18 ++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout create mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.basic/pacf.log create mode 100644 testing/btest/scripts/base/frameworks/pacf/basic.bro diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout new file mode 100644 index 0000000000..1d19d37b3d --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout @@ -0,0 +1,4 @@ +pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=10.10.1.4, src_p=1470/tcp, dst_h=74.53.140.153, dst_p=25/tcp], ip=, mac=], expire=30.0 secs, priority=0, location=, i=, d=, s=, id=1, _plugin=] +pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, i=, d=, s=, id=2, _plugin=] +pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, i=, d=, s=, id=2, _plugin=[config={^J^I[all] = 1^J}, _priority=0, plugin=[name=Pacf::debug_name^J{ ^Jreturn (fmt(Debug-%s, (Pacf::do_something(Pacf::p) ? All : None)));^J}, can_expire=F, init=Pacf::debug_init^J{ ^JPacf::debug_log(Pacf::p, init);^J}, done=Pacf::debug_done^J{ ^JPacf::debug_log(Pacf::p, init);^J}, add_rule=Pacf::debug_add_rule^J{ ^JPacf::s = fmt(add_rule: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jif (Pacf::do_something(Pacf::p)) ^J^I{ ^J^Ievent Pacf::rule_added(Pacf::r, Pacf::p, );^J^Ireturn (T);^J^I}^J^Jreturn (F);^J}, remove_rule=Pacf::debug_remove_rule^J{ ^JPacf::s = fmt(remove_rule: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jevent Pacf::rule_removed(Pacf::r, Pacf::p, );^Jreturn (T);^J}, add_notification=Pacf::debug_add_notification^J{ ^JPacf::s = fmt(add_notification: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jif (Pacf::do_something(Pacf::p)) ^J^I{ ^J^Ievent Pacf::notification_added(Pacf::r, Pacf::p, );^J^Ireturn (T);^J^I}^J^Jreturn (F);^J}, remove_notification=Pacf::debug_remove_notification^J{ ^JPacf::s = fmt(remove_notification: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jreturn (Pacf::do_something(Pacf::p));^J}, transaction_begin=Pacf::debug_transaction_begin^J{ ^JPacf::debug_log(Pacf::p, transaction_begin);^J}, transaction_end=Pacf::debug_transaction_end^J{ ^JPacf::debug_log(Pacf::p, transaction_end);^J}]]] +pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=10.10.1.4, src_p=1470/tcp, dst_h=74.53.140.153, dst_p=25/tcp], ip=, mac=], expire=30.0 secs, priority=0, location=, i=, d=, s=, id=1, _plugin=[config={^J^I[all] = 1^J}, _priority=0, plugin=[name=Pacf::debug_name^J{ ^Jreturn (fmt(Debug-%s, (Pacf::do_something(Pacf::p) ? All : None)));^J}, can_expire=F, init=Pacf::debug_init^J{ ^JPacf::debug_log(Pacf::p, init);^J}, done=Pacf::debug_done^J{ ^JPacf::debug_log(Pacf::p, init);^J}, add_rule=Pacf::debug_add_rule^J{ ^JPacf::s = fmt(add_rule: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jif (Pacf::do_something(Pacf::p)) ^J^I{ ^J^Ievent Pacf::rule_added(Pacf::r, Pacf::p, );^J^Ireturn (T);^J^I}^J^Jreturn (F);^J}, remove_rule=Pacf::debug_remove_rule^J{ ^JPacf::s = fmt(remove_rule: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jevent Pacf::rule_removed(Pacf::r, Pacf::p, );^Jreturn (T);^J}, add_notification=Pacf::debug_add_notification^J{ ^JPacf::s = fmt(add_notification: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jif (Pacf::do_something(Pacf::p)) ^J^I{ ^J^Ievent Pacf::notification_added(Pacf::r, Pacf::p, );^J^Ireturn (T);^J^I}^J^Jreturn (F);^J}, remove_notification=Pacf::debug_remove_notification^J{ ^JPacf::s = fmt(remove_notification: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jreturn (Pacf::do_something(Pacf::p));^J}, transaction_begin=Pacf::debug_transaction_begin^J{ ^JPacf::debug_log(Pacf::p, transaction_begin);^J}, transaction_end=Pacf::debug_transaction_end^J{ ^JPacf::debug_log(Pacf::p, transaction_end);^J}]]] diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/pacf.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/pacf.log new file mode 100644 index 0000000000..100f5393f2 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/pacf.log @@ -0,0 +1,18 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path pacf +#open 2015-04-13-23-44-49 +#fields ts category cmd state action target entity_type entity msg location plugin +#types time enum string enum string enum string string string string string +0.000000 Pacf::MESSAGE - - - - - - activated plugin with priority 0 - Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/1470->74.53.140.153/25 - (empty) Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/1470->74.53.140.153/25 - (empty) Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/1470->74.53.140.153/25 - (empty) Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/1470->74.53.140.153/25 - (empty) Debug-All +#close 2015-04-13-23-44-49 diff --git a/testing/btest/scripts/base/frameworks/pacf/basic.bro b/testing/btest/scripts/base/frameworks/pacf/basic.bro new file mode 100644 index 0000000000..76bcd992ee --- /dev/null +++ b/testing/btest/scripts/base/frameworks/pacf/basic.bro @@ -0,0 +1,18 @@ +# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT +# @TEST-EXEC: btest-diff pacf.log +# @TEST-EXEC: btest-diff .stdout + +@load base/frameworks/pacf + +event bro_init() + { + local pacf_debug = Pacf::create_debug(T); + Pacf::activate(pacf_debug, 0); + } + +event connection_established(c: connection) + { + local id = c$id; + Pacf::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 30sec); + Pacf::drop_address(id$orig_h, 15sec); + } From 0e7ebffacfa2cc14654d982bcf0c9d2d674b3f58 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 14 Apr 2015 14:51:52 -0700 Subject: [PATCH 21/93] add bif function to test if a subnet revers to v4 or v6. If there already was a way to check this, I completely missed it... --- src/bro.bif | 27 +++++++++++++++++++ .../btest/Baseline/bifs.subnet_version/out | 4 +++ testing/btest/bifs/subnet_version.bro | 7 +++++ 3 files changed, 38 insertions(+) create mode 100644 testing/btest/Baseline/bifs.subnet_version/out create mode 100644 testing/btest/bifs/subnet_version.bro diff --git a/src/bro.bif b/src/bro.bif index 18f91b31df..4590861161 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -2076,6 +2076,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 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/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); From c42fbdab1232b590d0498a2ecb5e6f0cd5acd311 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 14 Apr 2015 15:00:49 -0700 Subject: [PATCH 22/93] move openflow to use subnets instead of addr for matches. --- scripts/base/frameworks/openflow/main.bro | 4 ++-- scripts/base/frameworks/openflow/types.bro | 4 ++-- scripts/base/utils/json.bro | 2 ++ .../openflow.log | 10 +++++----- .../scripts.base.frameworks.openflow.ryu-basic/.stdout | 4 ++-- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/scripts/base/frameworks/openflow/main.bro b/scripts/base/frameworks/openflow/main.bro index 3e2f3eca36..043bfdef28 100644 --- a/scripts/base/frameworks/openflow/main.bro +++ b/scripts/base/frameworks/openflow/main.bro @@ -140,9 +140,9 @@ function match_conn(id: conn_id, reverse: bool &default=F): ofp_match return ofp_match( $dl_type=dl_type, $nw_proto=proto, - $nw_src=orig_h, + $nw_src=addr_to_subnet(orig_h), $tp_src=orig_p, - $nw_dst=resp_h, + $nw_dst=addr_to_subnet(resp_h), $tp_dst=resp_p ); } diff --git a/scripts/base/frameworks/openflow/types.bro b/scripts/base/frameworks/openflow/types.bro index a70bfb345c..356d9e9a77 100644 --- a/scripts/base/frameworks/openflow/types.bro +++ b/scripts/base/frameworks/openflow/types.bro @@ -42,9 +42,9 @@ export { # 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: addr &optional; + nw_src: subnet &optional; # IP destination address. - nw_dst: addr &optional; + nw_dst: subnet &optional; # TCP/UDP source port. tp_src: port &optional; # TCP/UDP destination port. diff --git a/scripts/base/utils/json.bro b/scripts/base/utils/json.bro index 8ac25e3283..b6d0093b58 100644 --- a/scripts/base/utils/json.bro +++ b/scripts/base/utils/json.bro @@ -26,6 +26,8 @@ function to_json(v: any, only_loggable: bool &default=F, field_escape_pattern: p return cat(port_to_count(to_port(cat(v)))); case "addr": + fallthrough; + case "subnet": return cat("\"", v, "\""); case "int": 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 index 99562536fd..abfe8d961a 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.openflow.log-basic/openflow.log +++ b/testing/btest/Baseline/scripts.base.frameworks.openflow.log-basic/openflow.log @@ -3,10 +3,10 @@ #empty_field (empty) #unset_field - #path openflow -#open 2015-04-13-19-54-15 +#open 2015-04-14-21-58-29 #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_group flow_mod.flags flow_mod.out_ports -#types time count count string string count count count count count addr addr port port count count enum count count count count count vector[count] +#types time count count string string count count count count count subnet subnet port port count count enum count count count count count vector[count] 0.000000 42 - - - - - - - - - - - - 1 - OpenFlow::OFPFC_ADD 0 0 0 - 0 3,7 -1254722767.875996 42 - - - - - 2048 - 6 10.10.1.4 74.53.140.153 1470 25 42 - OpenFlow::OFPFC_ADD 30 0 5 - 0 (empty) -1254722767.875996 42 - - - - - 2048 - 6 74.53.140.153 10.10.1.4 25 25 42 - OpenFlow::OFPFC_ADD 30 0 5 - 0 (empty) -#close 2015-04-13-19-54-15 +1254722767.875996 42 - - - - - 2048 - 6 10.10.1.4/32 74.53.140.153/32 1470 25 42 - OpenFlow::OFPFC_ADD 30 0 5 - 0 (empty) +1254722767.875996 42 - - - - - 2048 - 6 74.53.140.153/32 10.10.1.4/32 25 25 42 - OpenFlow::OFPFC_ADD 30 0 5 - 0 (empty) +#close 2015-04-14-21-58-29 diff --git a/testing/btest/Baseline/scripts.base.frameworks.openflow.ryu-basic/.stdout b/testing/btest/Baseline/scripts.base.frameworks.openflow.ryu-basic/.stdout index 5ef044f707..c5fecac835 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.openflow.ryu-basic/.stdout +++ b/testing/btest/Baseline/scripts.base.frameworks.openflow.ryu-basic/.stdout @@ -2,6 +2,6 @@ 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} http://127.0.0.1:8080/stats/flowentry/add -{"match": {"tp_dst": 25, "nw_dst": "74.53.140.153", "nw_src": "10.10.1.4", "dl_type": 2048, "tp_src": 1470, "nw_proto": 6}, "dpid": 42, "flags": 0, "hard_timeout": 0, "priority": 5, "actions": [], "cookie": 4398046511146, "idle_timeout": 30} +{"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": 25, "nw_dst": "10.10.1.4", "nw_src": "74.53.140.153", "dl_type": 2048, "tp_src": 25, "nw_proto": 6}, "dpid": 42, "flags": 0, "hard_timeout": 0, "priority": 5, "actions": [], "cookie": 4398046511146, "idle_timeout": 30} +{"match": {"tp_dst": 25, "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} From aad988d2f24662af0a8d3cca2781ab5646d1116b Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 14 Apr 2015 15:15:25 -0700 Subject: [PATCH 23/93] get rid of pacf prototype that we did not use. --- .../base/frameworks/pacf-proto/__load__.bro | 1 - scripts/base/frameworks/pacf-proto/main.bro | 111 ------------------ .../pacf-proto/plugins/__load__.bro | 1 - .../pacf-proto/plugins/openflow.bro | 111 ------------------ 4 files changed, 224 deletions(-) delete mode 100644 scripts/base/frameworks/pacf-proto/__load__.bro delete mode 100644 scripts/base/frameworks/pacf-proto/main.bro delete mode 100644 scripts/base/frameworks/pacf-proto/plugins/__load__.bro delete mode 100644 scripts/base/frameworks/pacf-proto/plugins/openflow.bro diff --git a/scripts/base/frameworks/pacf-proto/__load__.bro b/scripts/base/frameworks/pacf-proto/__load__.bro deleted file mode 100644 index d551be57d3..0000000000 --- a/scripts/base/frameworks/pacf-proto/__load__.bro +++ /dev/null @@ -1 +0,0 @@ -@load ./main \ No newline at end of file diff --git a/scripts/base/frameworks/pacf-proto/main.bro b/scripts/base/frameworks/pacf-proto/main.bro deleted file mode 100644 index 8500f89772..0000000000 --- a/scripts/base/frameworks/pacf-proto/main.bro +++ /dev/null @@ -1,111 +0,0 @@ -@load ./plugins - - -module PACF; - - -# Internal id counter for rule ids. -global LAST_ID:count = 0; - - -export { - - ## Type of the action. - ## - type RuleActionType: enum { - ## Drop packets matching a given RuleMatch record. - DROP, - ## Modify packets matching a given RuleMatch record - ## according to the ModifyArgs record. - MODIFY, - } &redef; - - - type RuleActionTarget: enum { - FORWARD, - MONITOR, - } &redef; - - ## Uni or bidriectional flow. - ## - type FlowType: enum { - ## Unidirectional flow. - PACF::UNIDIRECTIONAL, - ## Bidirectional flow. - PACF::BIDIRECTIONAL, - }; - - ## Properties which descibes a matching flow / connection - ## - type RuleMatch: record { - ## Ethernet protocol (ipv4, ipv6, ipip ... aso). - # eth_proto: ethernet_proto &optional; # Here should mb IPPROTO_* be used. - ## VLAN id. - vlan: count &optional; - ## Source MAC address. - src_mac: string &optional; - ## Source IP address (IPv4 | IPv6). - src_ip: addr &optional; - ## Source Port. - src_port: port &optional; - ## Destination MAC address. - dst_mac: string &optional; - ## Destination IP address. - dst_ip: addr &optional; - ## Destination Port. - dst_port: port &optional; - ## IP transport protocol. - ip_proto: transport_proto &optional; # Here should mb IPPROTO_* be used. - }; - - ## Action to be done on flows / connections that match. - ## - type RuleAction: record { - type_: RuleActionType; - target: RuleActionTarget &default=FORWARD; - ## Timeout n seconds after the last packet. - soft_timeout: count &optional; - ## Timeout after n seconds. - hard_timeout: count &optional; - ## Priority of the action. - priority: int &default=-0; - }; - - ## Rule which descibes the actions to take on a matching - ## flow / connection. - type Rule: record { - ## Rule id. - id: count &default=LAST_ID; - ## Flows / Connections which the rule should match. - match: RuleMatch; - ## Actions which will be taken when a flow / connection matches. - action: vector of RuleAction; - ## Should it be matched uni or bidriectional. - direction: FlowType; - }; - - ## Registered plugins - type Plugin: enum { - }; - - - type BackendState: record { - - } &redef; - - - ## A PACF backend which implements a subset of the PACF - ## features for a specific implementation - type Backend: record { - ## The type of the plugin (more then one of the same type can exist). - type_: Plugin; - ## Insert function to apply a specific rule - insert: function(state: PACF::BackendState, rule: PACF::Rule): bool &optional; - ## Remove function to remove a specific rule - remove: function(id: count): bool &optional; - state: BackendState &optional; - } &redef; - - global PACF::drop: event(); - global PACF::undrop: event(); -} diff --git a/scripts/base/frameworks/pacf-proto/plugins/__load__.bro b/scripts/base/frameworks/pacf-proto/plugins/__load__.bro deleted file mode 100644 index 2b1a02132c..0000000000 --- a/scripts/base/frameworks/pacf-proto/plugins/__load__.bro +++ /dev/null @@ -1 +0,0 @@ -@load ./openflow \ No newline at end of file diff --git a/scripts/base/frameworks/pacf-proto/plugins/openflow.bro b/scripts/base/frameworks/pacf-proto/plugins/openflow.bro deleted file mode 100644 index a3aa6414d8..0000000000 --- a/scripts/base/frameworks/pacf-proto/plugins/openflow.bro +++ /dev/null @@ -1,111 +0,0 @@ -@load ../main -@load base/frameworks/openflow - - -module PACFOpenflow; - - -export { - redef enum PACF::Plugin += { - PACF::OPENFLOW, - }; - - redef record PACF::BackendState += { - openflow_controller: Openflow::Controller &optional; - }; - - global new: function(controller: Openflow::Controller): PACF::Backend; -} - - -function insert(state: PACF::BackendState, rule: PACF::Rule): bool - { - for(i in rule$action) - { - switch(rule$action[i]$type_) - { - case PACF::DROP: - if(!state?$openflow_controller) - { - Reporter::warning(fmt("The given PACF::Backend %s is not an PACFOpenflow backend", cat(state))); - return F; - } - - # Create openflow records - local nw_proto = Openflow::IP_TCP; - if(rule$match$ip_proto == udp) - nw_proto = Openflow::IP_UDP; - else if(rule$match$ip_proto == icmp) - nw_proto = Openflow::IP_ICMP; - - local match: Openflow::ofp_match = [ - $in_port=state$openflow_controller$state$port_state[rule$match$src_ip], - $nw_src=rule$match$src_ip, - $nw_dst=rule$match$dst_ip, - $nw_proto=nw_proto, - $tp_src=rule$match$src_port, - $tp_dst=rule$match$dst_port - ]; - - local flow_mod: Openflow::ofp_flow_mod = [ - $match=match, - #$cookie=cookie, - $idle_timeout=30, - $hard_timeout=0, - # No action means drop. - $actions=vector() - ]; - - if(rule$direction == PACF::BIDIRECTIONAL) - { - local reverse_match: Openflow::ofp_match = [ - $in_port=state$openflow_controller$state$port_state[rule$match$dst_ip], - $nw_src=rule$match$dst_ip, - $nw_dst=rule$match$src_ip, - $nw_proto=nw_proto, - $tp_src=rule$match$dst_port, - $tp_dst=rule$match$src_port - ]; - - local reverse_flow_mod: Openflow::ofp_flow_mod = [ - $match=reverse_match, - #$cookie=cookie, - $idle_timeout=30, - $hard_timeout=0, - # No action means drop. - $actions=vector() - ]; - } - - if(rule$action[i]$target == PACF::MONITOR) - { - local action: vector of Openflow::ofp_action_output; - action[|action|] = Openflow::ofp_action_output($port_=state$openflow_controller$state$port_state[rule$match$dst_ip]); - flow_mod$actions=action; - - if(rule$direction == PACF::BIDIRECTIONAL) - { - local reverse_action: vector of Openflow::ofp_action_output; - reverse_action[|reverse_action|] = Openflow::ofp_action_output($port_=state$openflow_controller$state$port_state[rule$match$src_ip]); - reverse_flow_mod$actions=reverse_action; - } - } - - if(rule$direction == PACF::BIDIRECTIONAL) - return Openflow::flow_mod(state$openflow_controller, flow_mod) && Openflow::flow_mod(state$openflow_controller, reverse_flow_mod); - else - return Openflow::flow_mod(state$openflow_controller, flow_mod); - break; - default: - Reporter::warning(fmt("The PACF ActionType %s is not supported by this plugin", cat(rule$action[i]$type_))); - break; - } - } - return F; - } - - -function new(controller: Openflow::Controller): PACF::Backend - { - return [$type_=PACF::OPENFLOW, $state=[$openflow_controller=controller], $insert=insert]; - } From 7d7578146fd59201f733fe17141d5fdebe178ae4 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 14 Apr 2015 15:22:19 -0700 Subject: [PATCH 24/93] Add basic OpenFlow plugin for Pacf. This also changes a few types in pacf and adds a few needed bits and pieces to the OpenFlow framework. And - it even has a testcase... --- .../base/frameworks/openflow/plugins/log.bro | 9 +- .../base/frameworks/openflow/plugins/ryu.bro | 7 +- scripts/base/frameworks/openflow/types.bro | 2 + scripts/base/frameworks/pacf/main.bro | 45 ++--- scripts/base/frameworks/pacf/plugin.bro | 6 +- .../base/frameworks/pacf/plugins/__load__.bro | 1 + .../base/frameworks/pacf/plugins/openflow.bro | 164 ++++++++++++++++++ scripts/base/frameworks/pacf/types.bro | 4 +- .../.stdout | 8 +- .../openflow.log | 12 ++ .../pacf.log | 12 ++ .../scripts/base/frameworks/pacf/openflow.bro | 21 +++ 12 files changed, 258 insertions(+), 33 deletions(-) create mode 100644 scripts/base/frameworks/pacf/plugins/openflow.bro create mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log create mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/pacf.log create mode 100644 testing/btest/scripts/base/frameworks/pacf/openflow.bro diff --git a/scripts/base/frameworks/openflow/plugins/log.bro b/scripts/base/frameworks/openflow/plugins/log.bro index 0914654e06..cef252b95d 100644 --- a/scripts/base/frameworks/openflow/plugins/log.bro +++ b/scripts/base/frameworks/openflow/plugins/log.bro @@ -45,15 +45,20 @@ event bro_init() &priority=5 Log::create_stream(LOG, [$columns=Info, $ev=log_openflow, $path="openflow"]); } -function log_flow_mod(state: OpenFlow::ControllerState, match: ofp_match, flow_mod: OpenFlow::ofp_flow_mod): bool +function log_flow_mod(state: ControllerState, match: ofp_match, flow_mod: OpenFlow::ofp_flow_mod): bool { Log::write(LOG, [$ts=network_time(), $dpid=state$log_dpid, $match=match, $flow_mod=flow_mod]); return T; } +function log_describe(state: ControllerState): string + { + return fmt("OpenFlog Log Plugin - DPID %d", state$log_dpid); + } + function log_new(dpid: count): OpenFlow::Controller { return [$state=[$log_dpid=dpid, $_plugin=OpenFlow::LOG], - $flow_mod=log_flow_mod, $flow_clear=ryu_flow_clear]; + $flow_mod=log_flow_mod, $flow_clear=ryu_flow_clear, $describe=log_describe]; } diff --git a/scripts/base/frameworks/openflow/plugins/ryu.bro b/scripts/base/frameworks/openflow/plugins/ryu.bro index 181c9d89be..79d6a4a6fe 100644 --- a/scripts/base/frameworks/openflow/plugins/ryu.bro +++ b/scripts/base/frameworks/openflow/plugins/ryu.bro @@ -164,9 +164,14 @@ function ryu_flow_clear(state: OpenFlow::ControllerState): bool return T; } +function ryu_describe(state: ControllerState): string + { + return fmt("Ryu Plugin - http://%s:%d - DPID: %d", state$ryu_host, state$ryu_port, state$ryu_dpid); + } + # Ryu controller constructor function ryu_new(host: addr, host_port: count, dpid: count): OpenFlow::Controller { return [$state=[$ryu_host=host, $ryu_port=host_port, $ryu_dpid=dpid, $_plugin=OpenFlow::RYU], - $flow_mod=ryu_flow_mod, $flow_clear=ryu_flow_clear]; + $flow_mod=ryu_flow_mod, $flow_clear=ryu_flow_clear, $describe=ryu_describe]; } diff --git a/scripts/base/frameworks/openflow/types.bro b/scripts/base/frameworks/openflow/types.bro index 356d9e9a77..6c10b80125 100644 --- a/scripts/base/frameworks/openflow/types.bro +++ b/scripts/base/frameworks/openflow/types.bro @@ -111,6 +111,8 @@ export { type Controller: record { ## Controller related state. state: ControllerState; + ## function that describes the controller. Has to be implemented. + describe: function(state: ControllerState): string; ## flow_mod function flow_mod: function(state: ControllerState, match: ofp_match, flow_mod: ofp_flow_mod): bool &optional; ## flow_clear function diff --git a/scripts/base/frameworks/pacf/main.bro b/scripts/base/frameworks/pacf/main.bro index 0e0d930fce..c3b696bec2 100644 --- a/scripts/base/frameworks/pacf/main.bro +++ b/scripts/base/frameworks/pacf/main.bro @@ -81,7 +81,7 @@ export { ## 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; + global add_rule: function(r: Rule) : count; ## Removes a rule. ## @@ -91,7 +91,7 @@ export { ## 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; + global remove_rule: function(id: count) : bool; ###### Asynchronous feedback on rules. @@ -152,7 +152,7 @@ export { ## 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_notification: function(id: string) : bool; + global remove_notification: function(id: count) : bool; ###### Asynchronous feedback on notifications. @@ -240,6 +240,10 @@ export { ## Plugin triggering the log entry. plugin: string &log &optional; }; + + ## Event that can be handled to access the :bro:type:`Pacf::Info` + ## record as it is sent on to the logging framework. + global log_pacf: event(rec: Info); } redef record Rule += { @@ -248,12 +252,12 @@ redef record Rule += { }; global plugins: vector of PluginState; -global rule_counter: count = 0; -global rules: table[string] of Rule; +global rule_counter: count = 1; +global rules: table[count] of Rule; event bro_init() &priority=5 { - Log::create_stream(Pacf::LOG, [$columns=Info]); + Log::create_stream(Pacf::LOG, [$columns=Info, $ev=log_pacf, $path="pacf"]); } function entity_to_info(info: Info, e: Entity) @@ -294,7 +298,7 @@ function rule_to_info(info: Info, r: Rule) if ( r?$location ) info$location = r$location; - + entity_to_info(info, r$entity); } @@ -353,18 +357,18 @@ function drop_address(a: addr, t: interval, location: string &default="") : bool { 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); - return |id| > 0; + return id > 0; } function shunt_flow(f: flow_id, t: interval, location: string &default="") : bool { local e: Entity = [$ty=FLOW, $flow=f]; local r: Rule = [$ty=DROP, $target=MONITOR, $entity=e, $expire=t, $location=location]; - + local id = add_rule(r); - return |id| > 0; + return id > 0; } function reset(e: Entity) @@ -377,15 +381,15 @@ function clear() print "Pacf::clear not implemented yet"; } -function add_rule(r: Rule) : string +function add_rule(r: Rule) : count { - r$id = fmt("%d", ++rule_counter); + r$id = ++rule_counter; for ( i in plugins ) { local p = plugins[i]; - if ( p$plugin$add_rule(p, r) ) + if ( p$plugin$add_rule(p, r) ) { r$_plugin = p; log_rule(r, "ADD", REQUESTED, p); @@ -394,14 +398,15 @@ function add_rule(r: Rule) : string } log_rule_no_plugin(r, FAILED, "not supported"); + return 0; } -function remove_rule(id: string) : bool +function remove_rule(id: count) : bool { local r = rules[id]; local p = r$_plugin; - - if ( ! p$plugin$remove_rule(r$_plugin, r) ) + + if ( ! p$plugin$remove_rule(r$_plugin, r) ) { log_rule_error(r, "remove failed", p); return F; @@ -426,7 +431,7 @@ event rule_added(r: Rule, p: PluginState, msg: string &default="") log_rule(r, "ADD", SUCCEEDED, p); rules[r$id] = r; - + if ( r?$expire && ! p$plugin$can_expire ) schedule r$expire { rule_expire(r, p) }; } @@ -453,7 +458,7 @@ function add_notification(n: Notification) : string print "Pacf::add_notification not implemented yet"; } -function remove_notification(id: string) : bool +function remove_notification(id: count) : bool { print "Pacf::remove_notification not implemented yet"; } @@ -473,5 +478,3 @@ event notification_timeout(n: Notification, p: PluginState) event notification_error(n: Notification, p: PluginState, msg: string &default="") { } - - diff --git a/scripts/base/frameworks/pacf/plugin.bro b/scripts/base/frameworks/pacf/plugin.bro index ab25911d14..6c33462a99 100644 --- a/scripts/base/frameworks/pacf/plugin.bro +++ b/scripts/base/frameworks/pacf/plugin.bro @@ -13,7 +13,7 @@ export { _priority: int &default=+0; }; - # Definitioan of a plugin. + # 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 @@ -37,7 +37,7 @@ export { can_expire: bool; # One-time initialization functionl called when plugin gets registered, and - # befire any ther methods are called. + # before any other methods are called. init: function(state: PluginState) &optional; # One-time finalization function called when a plugin is shutdown; no further @@ -72,7 +72,7 @@ export { # 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. + # configuration of multiple rules at once, including replaying a previous state. transaction_begin: function(state: PluginState) &optional; transaction_end: function(state: PluginState) &optional; }; diff --git a/scripts/base/frameworks/pacf/plugins/__load__.bro b/scripts/base/frameworks/pacf/plugins/__load__.bro index 0b76aa2b74..8eda6f9b97 100644 --- a/scripts/base/frameworks/pacf/plugins/__load__.bro +++ b/scripts/base/frameworks/pacf/plugins/__load__.bro @@ -1 +1,2 @@ @load ./debug +@load ./openflow diff --git a/scripts/base/frameworks/pacf/plugins/openflow.bro b/scripts/base/frameworks/pacf/plugins/openflow.bro new file mode 100644 index 0000000000..990c34639f --- /dev/null +++ b/scripts/base/frameworks/pacf/plugins/openflow.bro @@ -0,0 +1,164 @@ +@load ../plugin +@load base/frameworks/openflow + +module Pacf; + +export { + type OfConfig: record { + monitor: bool &default=T; + forward: bool &default=T; + idle_timeout: count &default=60; + table_id: count &optional; + }; + + redef record PluginState += { + ## OpenFlow controller for Pacf OpenFlow plugin + of_controller: OpenFlow::Controller &optional; + ## OpenFlow configuration record that is passed on initialization + of_config: OfConfig &optional; + }; + + ## Instantiates an openflow plugin for the PACF framework. + global create_openflow: function(controller: OpenFlow::Controller, config: OfConfig &default=[]) : PluginState; +} + +function openflow_name(p: PluginState) : string + { + return fmt("Openflow - %s", p$of_controller$describe(p$of_controller$state)); + } + +function openflow_check_rule(c: OfConfig, r: Rule) : bool + { + if ( r$target == MONITOR && c$monitor ) + return T; + + if ( r$target == FORWARD && c$forward ) + return T; + + return F; + } + +function entity_to_match(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 v; + } + + local dl_type = OpenFlow::ETH_IPv4; + + if ( e$ty == ADDRESS || e$ty == RESPONDER || e$ty == ORIGINATOR ) + { + if ( is_v6_subnet(e$ip) ) + dl_type = OpenFlow::ETH_IPv6; + + if ( e$ty == ADDRESS || e$ty == ORIGINATOR ) + v[|v|] = OpenFlow::ofp_match( + $dl_type=dl_type, + $nw_src=e$ip + ); + + if ( e$ty == ADDRESS || e$ty == RESPONDER ) + v[|v|] = OpenFlow::ofp_match( + $dl_type=dl_type, + $nw_dst=e$ip + ); + + return v; + } + + local proto = OpenFlow::IP_TCP; + + if ( e$ty == FLOW ) + { + if ( is_v6_addr(e$flow$src_h) ) + dl_type = OpenFlow::ETH_IPv6; + + if ( is_udp_port(e$flow$src_p) ) + proto = OpenFlow::IP_UDP; + else if ( is_icmp_port(e$flow$src_p) ) + proto = OpenFlow::IP_ICMP; + + v[|v|] = OpenFlow::ofp_match( + $dl_type=dl_type, + $nw_proto=proto, + $nw_src=addr_to_subnet(e$flow$src_h), + $tp_src=e$flow$src_p, + $nw_dst=addr_to_subnet(e$flow$dst_h), + $tp_dst=e$flow$dst_p + ); + return v; + } + + Reporter::error(fmt("Entity type %s not supported for openflow yet", cat(e$ty))); + return v; + } + +function openflow_add_rule(p: PluginState, r: Rule) : bool + { + local c = p$of_config; + + if ( ! openflow_check_rule(c, r) ) + return F; + + local flow_mod: OpenFlow::ofp_flow_mod = [ + $cookie=r$id, + $command=OpenFlow::OFPFC_ADD, + $idle_timeout=c$idle_timeout, + $priority=int_to_count(r$priority) + ]; + + 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; + + local matches = entity_to_match(r$entity); + + for ( i in matches ) + { + if ( ! OpenFlow::flow_mod(p$of_controller, matches[i], flow_mod) ) + 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$of_config, r) ) + return F; + + local flow_mod: OpenFlow::ofp_flow_mod = [ + $cookie=r$id, + $command=OpenFlow::OFPFC_DELETE + ]; + + OpenFlow::flow_mod(p$of_controller, [], flow_mod); + + return T; + } + +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 +# $add_notification = openflow_add_notification, +# $remove_notification = openflow_remove_notification, +# $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/pacf/types.bro b/scripts/base/frameworks/pacf/types.bro index 8e3a3b999d..2344155477 100644 --- a/scripts/base/frameworks/pacf/types.bro +++ b/scripts/base/frameworks/pacf/types.bro @@ -81,7 +81,7 @@ export { d: double &optional; ##< Argument for rule types requiring a double argument. s: string &optional; ##< Argument for rule types requiring a string argument. - id: string &default=""; ##< Internally determined unique ID for this rule. Will be set when added. + id: count &default=0; ##< Internally determined unique ID for this rule. Will be set when added. }; ## Type of notifications that the framework supports. Each type lists the @@ -113,7 +113,7 @@ export { d: double; ##< Argument for notification types requiring a double argument. s: string; ##< Argument for notification types requiring a string argument. - id: string &default=""; ##< Internally determined unique ID for this notification. Will be set when added. + id: count &default=0; ##< Internally determined unique ID for this notification. Will be set when added. }; } diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout index 1d19d37b3d..30e8520853 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout @@ -1,4 +1,4 @@ -pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=10.10.1.4, src_p=1470/tcp, dst_h=74.53.140.153, dst_p=25/tcp], ip=, mac=], expire=30.0 secs, priority=0, location=, i=, d=, s=, id=1, _plugin=] -pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, i=, d=, s=, id=2, _plugin=] -pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, i=, d=, s=, id=2, _plugin=[config={^J^I[all] = 1^J}, _priority=0, plugin=[name=Pacf::debug_name^J{ ^Jreturn (fmt(Debug-%s, (Pacf::do_something(Pacf::p) ? All : None)));^J}, can_expire=F, init=Pacf::debug_init^J{ ^JPacf::debug_log(Pacf::p, init);^J}, done=Pacf::debug_done^J{ ^JPacf::debug_log(Pacf::p, init);^J}, add_rule=Pacf::debug_add_rule^J{ ^JPacf::s = fmt(add_rule: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jif (Pacf::do_something(Pacf::p)) ^J^I{ ^J^Ievent Pacf::rule_added(Pacf::r, Pacf::p, );^J^Ireturn (T);^J^I}^J^Jreturn (F);^J}, remove_rule=Pacf::debug_remove_rule^J{ ^JPacf::s = fmt(remove_rule: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jevent Pacf::rule_removed(Pacf::r, Pacf::p, );^Jreturn (T);^J}, add_notification=Pacf::debug_add_notification^J{ ^JPacf::s = fmt(add_notification: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jif (Pacf::do_something(Pacf::p)) ^J^I{ ^J^Ievent Pacf::notification_added(Pacf::r, Pacf::p, );^J^Ireturn (T);^J^I}^J^Jreturn (F);^J}, remove_notification=Pacf::debug_remove_notification^J{ ^JPacf::s = fmt(remove_notification: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jreturn (Pacf::do_something(Pacf::p));^J}, transaction_begin=Pacf::debug_transaction_begin^J{ ^JPacf::debug_log(Pacf::p, transaction_begin);^J}, transaction_end=Pacf::debug_transaction_end^J{ ^JPacf::debug_log(Pacf::p, transaction_end);^J}]]] -pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=10.10.1.4, src_p=1470/tcp, dst_h=74.53.140.153, dst_p=25/tcp], ip=, mac=], expire=30.0 secs, priority=0, location=, i=, d=, s=, id=1, _plugin=[config={^J^I[all] = 1^J}, _priority=0, plugin=[name=Pacf::debug_name^J{ ^Jreturn (fmt(Debug-%s, (Pacf::do_something(Pacf::p) ? All : None)));^J}, can_expire=F, init=Pacf::debug_init^J{ ^JPacf::debug_log(Pacf::p, init);^J}, done=Pacf::debug_done^J{ ^JPacf::debug_log(Pacf::p, init);^J}, add_rule=Pacf::debug_add_rule^J{ ^JPacf::s = fmt(add_rule: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jif (Pacf::do_something(Pacf::p)) ^J^I{ ^J^Ievent Pacf::rule_added(Pacf::r, Pacf::p, );^J^Ireturn (T);^J^I}^J^Jreturn (F);^J}, remove_rule=Pacf::debug_remove_rule^J{ ^JPacf::s = fmt(remove_rule: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jevent Pacf::rule_removed(Pacf::r, Pacf::p, );^Jreturn (T);^J}, add_notification=Pacf::debug_add_notification^J{ ^JPacf::s = fmt(add_notification: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jif (Pacf::do_something(Pacf::p)) ^J^I{ ^J^Ievent Pacf::notification_added(Pacf::r, Pacf::p, );^J^Ireturn (T);^J^I}^J^Jreturn (F);^J}, remove_notification=Pacf::debug_remove_notification^J{ ^JPacf::s = fmt(remove_notification: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jreturn (Pacf::do_something(Pacf::p));^J}, transaction_begin=Pacf::debug_transaction_begin^J{ ^JPacf::debug_log(Pacf::p, transaction_begin);^J}, transaction_end=Pacf::debug_transaction_end^J{ ^JPacf::debug_log(Pacf::p, transaction_end);^J}]]] +pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=10.10.1.4, src_p=1470/tcp, dst_h=74.53.140.153, dst_p=25/tcp], ip=, mac=], expire=30.0 secs, priority=0, location=, i=, d=, s=, id=2, _plugin=] +pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, i=, d=, s=, id=3, _plugin=] +pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, i=, d=, s=, id=3, _plugin=[config={^J^I[all] = 1^J}, _priority=0, plugin=[name=Pacf::debug_name^J{ ^Jreturn (fmt(Debug-%s, (Pacf::do_something(Pacf::p) ? All : None)));^J}, can_expire=F, init=Pacf::debug_init^J{ ^JPacf::debug_log(Pacf::p, init);^J}, done=Pacf::debug_done^J{ ^JPacf::debug_log(Pacf::p, init);^J}, add_rule=Pacf::debug_add_rule^J{ ^JPacf::s = fmt(add_rule: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jif (Pacf::do_something(Pacf::p)) ^J^I{ ^J^Ievent Pacf::rule_added(Pacf::r, Pacf::p, );^J^Ireturn (T);^J^I}^J^Jreturn (F);^J}, remove_rule=Pacf::debug_remove_rule^J{ ^JPacf::s = fmt(remove_rule: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jevent Pacf::rule_removed(Pacf::r, Pacf::p, );^Jreturn (T);^J}, add_notification=Pacf::debug_add_notification^J{ ^JPacf::s = fmt(add_notification: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jif (Pacf::do_something(Pacf::p)) ^J^I{ ^J^Ievent Pacf::notification_added(Pacf::r, Pacf::p, );^J^Ireturn (T);^J^I}^J^Jreturn (F);^J}, remove_notification=Pacf::debug_remove_notification^J{ ^JPacf::s = fmt(remove_notification: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jreturn (Pacf::do_something(Pacf::p));^J}, transaction_begin=Pacf::debug_transaction_begin^J{ ^JPacf::debug_log(Pacf::p, transaction_begin);^J}, transaction_end=Pacf::debug_transaction_end^J{ ^JPacf::debug_log(Pacf::p, transaction_end);^J}], of_controller=, of_config=]] +pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=10.10.1.4, src_p=1470/tcp, dst_h=74.53.140.153, dst_p=25/tcp], ip=, mac=], expire=30.0 secs, priority=0, location=, i=, d=, s=, id=2, _plugin=[config={^J^I[all] = 1^J}, _priority=0, plugin=[name=Pacf::debug_name^J{ ^Jreturn (fmt(Debug-%s, (Pacf::do_something(Pacf::p) ? All : None)));^J}, can_expire=F, init=Pacf::debug_init^J{ ^JPacf::debug_log(Pacf::p, init);^J}, done=Pacf::debug_done^J{ ^JPacf::debug_log(Pacf::p, init);^J}, add_rule=Pacf::debug_add_rule^J{ ^JPacf::s = fmt(add_rule: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jif (Pacf::do_something(Pacf::p)) ^J^I{ ^J^Ievent Pacf::rule_added(Pacf::r, Pacf::p, );^J^Ireturn (T);^J^I}^J^Jreturn (F);^J}, remove_rule=Pacf::debug_remove_rule^J{ ^JPacf::s = fmt(remove_rule: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jevent Pacf::rule_removed(Pacf::r, Pacf::p, );^Jreturn (T);^J}, add_notification=Pacf::debug_add_notification^J{ ^JPacf::s = fmt(add_notification: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jif (Pacf::do_something(Pacf::p)) ^J^I{ ^J^Ievent Pacf::notification_added(Pacf::r, Pacf::p, );^J^Ireturn (T);^J^I}^J^Jreturn (F);^J}, remove_notification=Pacf::debug_remove_notification^J{ ^JPacf::s = fmt(remove_notification: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jreturn (Pacf::do_something(Pacf::p));^J}, transaction_begin=Pacf::debug_transaction_begin^J{ ^JPacf::debug_log(Pacf::p, transaction_begin);^J}, transaction_end=Pacf::debug_transaction_end^J{ ^JPacf::debug_log(Pacf::p, transaction_end);^J}], of_controller=, of_config=]] diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log new file mode 100644 index 0000000000..6031a6cdc0 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log @@ -0,0 +1,12 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path openflow +#open 2015-04-14-22-20-31 +#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_group flow_mod.flags flow_mod.out_ports +#types time count count string string count count count count count subnet subnet port port count count enum count count count count count vector[count] +1254722767.875996 42 - - - - - 2048 - 6 10.10.1.4/32 74.53.140.153/32 1470 25 2 - OpenFlow::OFPFC_ADD 60 30 0 - 0 (empty) +1254722767.875996 42 - - - - - 2048 - - 10.10.1.4/32 - - - 3 - OpenFlow::OFPFC_ADD 60 15 0 - 0 (empty) +1254722767.875996 42 - - - - - 2048 - - - 10.10.1.4/32 - - 3 - OpenFlow::OFPFC_ADD 60 15 0 - 0 (empty) +#close 2015-04-14-22-20-31 diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/pacf.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/pacf.log new file mode 100644 index 0000000000..c0362c23c4 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/pacf.log @@ -0,0 +1,12 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path pacf +#open 2015-04-14-22-20-31 +#fields ts category cmd state action target entity_type entity msg location plugin +#types time enum string enum string enum string string string string string +0.000000 Pacf::MESSAGE - - - - - - activated plugin with priority 0 - Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/1470->74.53.140.153/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +#close 2015-04-14-22-20-31 diff --git a/testing/btest/scripts/base/frameworks/pacf/openflow.bro b/testing/btest/scripts/base/frameworks/pacf/openflow.bro new file mode 100644 index 0000000000..7ea537e505 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/pacf/openflow.bro @@ -0,0 +1,21 @@ +# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT +# @TEST-EXEC: btest-diff pacf.log +# @TEST-EXEC: btest-diff openflow.log + +@load base/frameworks/pacf + +global of_controller: OpenFlow::Controller; + +event bro_init() + { + of_controller = OpenFlow::log_new(42); + local pacf_of = Pacf::create_openflow(of_controller); + Pacf::activate(pacf_of, 0); + } + +event connection_established(c: connection) + { + local id = c$id; + Pacf::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 30sec); + Pacf::drop_address(id$orig_h, 15sec); + } From a3bfa92125709065dfa29204ce77f99374a62c35 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 15 Apr 2015 11:11:40 -0700 Subject: [PATCH 25/93] introduce more mac address mac types, support them in OpenFlow plugin, add support for a few rule types in OpenFlow plugin and add predicates for matches and flow_mod modifiers. --- .../base/frameworks/pacf/plugins/openflow.bro | 108 +++++++++++++++--- scripts/base/frameworks/pacf/types.bro | 6 +- 2 files changed, 95 insertions(+), 19 deletions(-) diff --git a/scripts/base/frameworks/pacf/plugins/openflow.bro b/scripts/base/frameworks/pacf/plugins/openflow.bro index 990c34639f..8bda72092e 100644 --- a/scripts/base/frameworks/pacf/plugins/openflow.bro +++ b/scripts/base/frameworks/pacf/plugins/openflow.bro @@ -9,6 +9,9 @@ export { forward: bool &default=T; idle_timeout: count &default=60; table_id: count &optional; + + match_pred: function(p: PluginState, e: Entity, m: vector of OpenFlow::ofp_match): vector of OpenFlow::ofp_match &optional &weaken; + flow_mod_pred: function(p: PluginState, r: Rule, m: OpenFlow::ofp_flow_mod): OpenFlow::ofp_flow_mod &optional &weaken; }; redef record PluginState += { @@ -38,7 +41,23 @@ function openflow_check_rule(c: OfConfig, r: Rule) : bool return F; } -function entity_to_match(e: Entity): vector of OpenFlow::ofp_match +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 entity_to_match(p: PluginState, e: Entity): vector of OpenFlow::ofp_match { local v : vector of OpenFlow::ofp_match = vector(); @@ -46,7 +65,32 @@ function entity_to_match(e: Entity): vector of OpenFlow::ofp_match { v[|v|] = OpenFlow::match_conn(e$conn); # forward and... v[|v|] = OpenFlow::match_conn(e$conn, T); # reverse - return v; + return openflow_match_pred(p, e, v); + } + + if ( e$ty == MAC || e$ty == ORIGMAC || e$ty == DESTMAC ) + { + if ( e$ty == MAC || e$ty == ORIGMAC ) + v[|v|] = OpenFlow::ofp_match( + $dl_src=e$mac + ); + + if ( e$ty == MAC || e$ty == DESTMAC ) + v[|v|] = OpenFlow::ofp_match( + $dl_dst=e$mac + ); + + return openflow_match_pred(p, e, v); + } + + if ( e$ty == MACFLOW ) + { + v[|v|] = OpenFlow::ofp_match( + $dl_src=e$mac, + $dl_dst=e$dst_mac + ); + + return openflow_match_pred(p, e, v); } local dl_type = OpenFlow::ETH_IPv4; @@ -68,7 +112,7 @@ function entity_to_match(e: Entity): vector of OpenFlow::ofp_match $nw_dst=e$ip ); - return v; + return openflow_match_pred(p, e, v); } local proto = OpenFlow::IP_TCP; @@ -91,11 +135,50 @@ function entity_to_match(e: Entity): vector of OpenFlow::ofp_match $nw_dst=addr_to_subnet(e$flow$dst_h), $tp_dst=e$flow$dst_p ); - return v; + + return openflow_match_pred(p, e, v); } Reporter::error(fmt("Entity type %s not supported for openflow yet", cat(e$ty))); - return v; + 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=r$id, + $command=OpenFlow::OFPFC_ADD, + $idle_timeout=c$idle_timeout, + $priority=int_to_count(r$priority) + ); + + 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$out_ports = vector(OpenFlow::OFPP_NORMAL); + } + else if ( r$ty == REDIRECT ) + { + # redirect to port i + flow_mod$out_ports = vector(int_to_count(r$i)); + } + 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 @@ -105,19 +188,8 @@ function openflow_add_rule(p: PluginState, r: Rule) : bool if ( ! openflow_check_rule(c, r) ) return F; - local flow_mod: OpenFlow::ofp_flow_mod = [ - $cookie=r$id, - $command=OpenFlow::OFPFC_ADD, - $idle_timeout=c$idle_timeout, - $priority=int_to_count(r$priority) - ]; - - 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; - - local matches = entity_to_match(r$entity); + local flow_mod = openflow_rule_to_flow_mod(p, r); + local matches = entity_to_match(p, r$entity); for ( i in matches ) { diff --git a/scripts/base/frameworks/pacf/types.bro b/scripts/base/frameworks/pacf/types.bro index 2344155477..b1663f19d9 100644 --- a/scripts/base/frameworks/pacf/types.bro +++ b/scripts/base/frameworks/pacf/types.bro @@ -10,6 +10,9 @@ export { CONNECTION, ##< All of a bi-directional connection's activity. FLOW, ##< All of a uni-directional flow's activity. MAC, ##< Activity involving a MAC address. + ORIGMAC, ##< Activity *from* a source MAC address. + DESTMAC, ##< Activity *to* a destination MAC adress. + MACFLOW ##< Activity involving a pair of MAC addresses. }; ## Type defining the enity an :bro:id:`Rule` is operating on. @@ -18,7 +21,8 @@ export { conn: conn_id &optional; ##< Used with :bro:id:`CONNECTION` . flow: flow_id &optional; ##< Used with :bro:id:`FLOW` . ip: subnet &optional; ##< Used with :bro:id:`ORIGINATOR`/:bro:id:`RESPONDER`/:bro:id:`ADDRESS`; can specifiy a CIDR subnet. - mac: string &optional; ##< Used with :bro:id:`MAC` . + mac: string &optional; ##< Used with :bro:id:`MAC`/:bro:id:`ORIGMAC`/:bro:id:`DESTMAC`. + dst_mac: string &optional; ##< Used with :bro:id:`MACFLOW`; specifies the destination for the flow. }; ## Target of :bro:id:`Rule` action. From 9290718bd6d8ce7f04708c6237e579f3debd19b1 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Thu, 16 Apr 2015 12:44:45 -0700 Subject: [PATCH 26/93] Allow setting packet and byte thresholds for connections. This extends the ConnSize analyzer to be able to raise events when each direction of a connection crosses a certain amount of bytes or packets. Thresholds are set using set_conn_bytes_threshold(c$id, [num-bytes], [direction]); and set_conn_packets_threshold(c$id, [num-packets], [direction]); respectively. They raise the event event conn_bytes_threshold_crossed(c: connection, threshold: count, is_orig: bool) and event conn_packets_threshold_crossed(c: connection, threshold: count, is_orig: bool) respectively. Current thresholds can be examined using get_conn_bytes_threshold and get_conn_packets_threshold Currently only one threshold can be set per connection. This also fixes a bug where child packet analyzers of the TCP analyzer where not found using FindChild. --- src/analyzer/Analyzer.h | 4 +- .../protocol/conn-size/CMakeLists.txt | 1 + src/analyzer/protocol/conn-size/ConnSize.cc | 77 +++++++++++++ src/analyzer/protocol/conn-size/ConnSize.h | 9 ++ src/analyzer/protocol/conn-size/events.bif | 23 ++++ src/analyzer/protocol/conn-size/functions.bif | 106 ++++++++++++++++++ src/analyzer/protocol/tcp/TCP.cc | 44 ++++++++ src/analyzer/protocol/tcp/TCP.h | 6 +- .../Baseline/core.conn-size-threshold/.stdout | 23 ++++ testing/btest/core/conn-size-threshold.bro | 32 ++++++ 10 files changed, 321 insertions(+), 4 deletions(-) create mode 100644 src/analyzer/protocol/conn-size/functions.bif create mode 100644 testing/btest/Baseline/core.conn-size-threshold/.stdout create mode 100644 testing/btest/core/conn-size-threshold.bro diff --git a/src/analyzer/Analyzer.h b/src/analyzer/Analyzer.h index 1eda4c3cf1..83157aadde 100644 --- a/src/analyzer/Analyzer.h +++ b/src/analyzer/Analyzer.h @@ -400,7 +400,7 @@ public: * * @return The analyzer, or null if not found. */ - Analyzer* FindChild(ID id); + virtual Analyzer* FindChild(ID id); /** * Recursively searches all (direct or indirect) childs of the @@ -411,7 +411,7 @@ public: * @return The first analyzer of the given type found, or null if * none. */ - Analyzer* FindChild(Tag tag); + virtual Analyzer* FindChild(Tag tag); /** * Recursively searches all (direct or indirect) childs of the diff --git a/src/analyzer/protocol/conn-size/CMakeLists.txt b/src/analyzer/protocol/conn-size/CMakeLists.txt index efaadef401..f89a6e5b88 100644 --- a/src/analyzer/protocol/conn-size/CMakeLists.txt +++ b/src/analyzer/protocol/conn-size/CMakeLists.txt @@ -6,4 +6,5 @@ include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DI bro_plugin_begin(Bro ConnSize) bro_plugin_cc(ConnSize.cc Plugin.cc) bro_plugin_bif(events.bif) +bro_plugin_bif(functions.bif) bro_plugin_end() diff --git a/src/analyzer/protocol/conn-size/ConnSize.cc b/src/analyzer/protocol/conn-size/ConnSize.cc index 5bfeb2bf90..fbe6b87487 100644 --- a/src/analyzer/protocol/conn-size/ConnSize.cc +++ b/src/analyzer/protocol/conn-size/ConnSize.cc @@ -29,6 +29,11 @@ void ConnSize_Analyzer::Init() orig_pkts = 0; resp_bytes = 0; resp_pkts = 0; + + orig_bytes_thresh = 0; + orig_pkts = 0; + resp_bytes_thresh = 0; + resp_pkts = 0; } void ConnSize_Analyzer::Done() @@ -36,6 +41,18 @@ void ConnSize_Analyzer::Done() Analyzer::Done(); } +void ConnSize_Analyzer::ThresholdEvent(EventHandlerPtr f, uint64 threshold, bool is_orig) + { + if ( ! f ) + return; + + val_list* vl = new val_list; + vl->append(BuildConnVal()); + vl->append(new Val(threshold, TYPE_COUNT)); + vl->append(new Val(is_orig, TYPE_BOOL)); + ConnectionEvent(f, vl); + } + void ConnSize_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); @@ -44,11 +61,71 @@ void ConnSize_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, { orig_bytes += ip->TotalLen(); orig_pkts ++; + + if ( orig_bytes_thresh && orig_bytes >= orig_bytes_thresh ) + { + ThresholdEvent(conn_bytes_threshold_crossed, orig_bytes_thresh, is_orig); + orig_bytes_thresh = 0; + } + + if ( orig_pkts_thresh && orig_pkts >= orig_pkts_thresh ) + { + ThresholdEvent(conn_packets_threshold_crossed, orig_pkts_thresh, is_orig); + orig_pkts_thresh = 0; + } } else { resp_bytes += ip->TotalLen(); resp_pkts ++; + + if ( resp_bytes_thresh && resp_bytes >= resp_bytes_thresh ) + { + ThresholdEvent(conn_bytes_threshold_crossed, resp_bytes_thresh, is_orig); + resp_bytes_thresh = 0; + } + + if ( resp_pkts_thresh && resp_pkts >= resp_pkts_thresh ) + { + ThresholdEvent(conn_packets_threshold_crossed, resp_pkts_thresh, is_orig); + resp_pkts_thresh = 0; + } + } + } + +void ConnSize_Analyzer::SetThreshold(uint64 threshold, bool bytes, bool orig) + { + if ( bytes ) + { + if ( orig ) + orig_bytes_thresh = threshold; + else + resp_bytes_thresh = threshold; + } + else + { + if ( orig ) + orig_pkts_thresh = threshold; + else + resp_pkts_thresh = threshold; + } + } + +uint64_t ConnSize_Analyzer::GetThreshold(bool bytes, bool orig) + { + if ( bytes ) + { + if ( orig ) + return orig_bytes_thresh; + else + return resp_bytes_thresh; + } + else + { + if ( orig ) + return orig_pkts_thresh; + else + return resp_pkts_thresh; } } diff --git a/src/analyzer/protocol/conn-size/ConnSize.h b/src/analyzer/protocol/conn-size/ConnSize.h index d48c448822..41388ceb3c 100644 --- a/src/analyzer/protocol/conn-size/ConnSize.h +++ b/src/analyzer/protocol/conn-size/ConnSize.h @@ -21,6 +21,9 @@ public: virtual void UpdateConnVal(RecordVal *conn_val); virtual void FlipRoles(); + void SetThreshold(uint64_t threshold, bool bytes, bool orig); + uint64 GetThreshold(bool bytes, bool orig); + static analyzer::Analyzer* Instantiate(Connection* conn) { return new ConnSize_Analyzer(conn); } @@ -28,11 +31,17 @@ protected: virtual void DeliverPacket(int len, const u_char* data, bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen); + void ThresholdEvent(EventHandlerPtr f, uint64 threshold, bool is_orig); uint64_t orig_bytes; uint64_t resp_bytes; uint64_t orig_pkts; uint64_t resp_pkts; + + uint64_t orig_bytes_thresh; + uint64_t resp_bytes_thresh; + uint64_t orig_pkts_thresh; + uint64_t resp_pkts_thresh; }; } } // namespace analyzer::* diff --git a/src/analyzer/protocol/conn-size/events.bif b/src/analyzer/protocol/conn-size/events.bif index e69de29bb2..ab1034ebb8 100644 --- a/src/analyzer/protocol/conn-size/events.bif +++ b/src/analyzer/protocol/conn-size/events.bif @@ -0,0 +1,23 @@ +## Generated for a connection that crossed a set byte threshold +## +## c: the connection +## +## threshold: the threshold that was set +## +## is_orig: True if the threshold was crossed by the originator of the connection +## +## .. bro:see:: set_conn_packets_threshold set_conn_bytes_threshold conn_packets_threshold_crossed +## get_conn_bytes_threshold get_conn_packets_threshold +event conn_bytes_threshold_crossed%(c: connection, threshold: count, is_orig: bool%); + +## Generated for a connection that crossed a set packet threshold +## +## c: the connection +## +## threshold: the threshold that was set +## +## is_orig: True if the threshold was crossed by the originator of the connection +## +## .. bro:see:: set_conn_packets_threshold set_conn_bytes_threshold conn_bytes_threshold_crossed +## get_conn_bytes_threshold get_conn_packets_threshold +event conn_packets_threshold_crossed%(c: connection, threshold: count, is_orig: bool%); diff --git a/src/analyzer/protocol/conn-size/functions.bif b/src/analyzer/protocol/conn-size/functions.bif new file mode 100644 index 0000000000..838c5976c4 --- /dev/null +++ b/src/analyzer/protocol/conn-size/functions.bif @@ -0,0 +1,106 @@ + +%%{ +#include "analyzer/protocol/conn-size/ConnSize.h" + +analyzer::Analyzer* GetConnsizeAnalyzer(Val* cid) + { + Connection* c = sessions->FindConnection(cid); + if ( ! c ) + { + reporter->Error("cannot find connection"); + return 0; + } + + analyzer::Analyzer* a = c->FindAnalyzer("CONNSIZE"); + if ( ! a ) + reporter->Error("connection does not have ConnSize analyzer"); + + return a; + } + +%%} + +## Sets a threshold for connection sizes. +## +## cid: The connection id. +## +## threshold: Threshold in bytes. +## +## is_orig: If true, threshold is set for bytes from originator, otherwhise for bytes from responder. +## +## .. bro:see:: set_conn_packets_threshold conn_bytes_threshold_crossed conn_packets_threshold_crossed +## get_conn_bytes_threshold get_conn_packets_threshold +function set_conn_bytes_threshold%(cid: conn_id, threshold: count, is_orig: bool%): bool + %{ + analyzer::Analyzer* a = GetConnsizeAnalyzer(cid); + if ( ! a ) + return new Val(0, TYPE_BOOL); + + static_cast(a)->SetThreshold(threshold, 1, is_orig); + + return new Val(0, TYPE_BOOL); + %} + +## Sets a threshold for connection packets. +## +## cid: The connection id. +## +## threshold: Threshold in packets. +## +## is_orig: If true, threshold is set for packets from originator, otherwhise for packets from responder. +## +## .. bro:see:: set_conn_bytes_threshold conn_bytes_threshold_crossed conn_packets_threshold_crossed +## get_conn_bytes_threshold get_conn_packets_threshold +function set_conn_packets_threshold%(cid: conn_id, threshold: count, is_orig: bool%): bool + %{ + analyzer::Analyzer* a = GetConnsizeAnalyzer(cid); + if ( ! a ) + return new Val(0, TYPE_BOOL); + + static_cast(a)->SetThreshold(threshold, 0, is_orig); + + return new Val(0, TYPE_BOOL); + %} + +## Gets the current byte threshold size for a connection. +## +## cid: The connection id. +## +## is_orig: If true, threshold of originator, otherwhise threshold of responder. +## +## Returns: 0 if no threshold is set or the threshold in bytes +## +## .. bro:see:: set_conn_packets_threshold conn_bytes_threshold_crossed conn_packets_threshold_crossed +## get_conn_packets_threshold +function get_conn_bytes_threshold%(cid: conn_id, is_orig: bool%): count + %{ + analyzer::Analyzer* a = GetConnsizeAnalyzer(cid); + if ( ! a ) + return new Val(0, TYPE_COUNT); + + return new Val( + static_cast(a)->GetThreshold(1, is_orig), + TYPE_COUNT); + %} + +## Gets the current packet threshold size for a connection. +## +## cid: The connection id. +## +## is_orig: If true, threshold of originator, otherwhise threshold of responder. +## +## Returns: 0 if no threshold is set or the threshold in packets +## +## .. bro:see:: set_conn_packets_threshold conn_bytes_threshold_crossed conn_packets_threshold_crossed +## get_conn_bytes_threshold +function get_conn_packets_threshold%(cid: conn_id, is_orig: bool%): count + %{ + analyzer::Analyzer* a = GetConnsizeAnalyzer(cid); + if ( ! a ) + return new Val(0, TYPE_COUNT); + + return new Val( + static_cast(a)->GetThreshold(0, is_orig), + TYPE_COUNT); + %} + diff --git a/src/analyzer/protocol/tcp/TCP.cc b/src/analyzer/protocol/tcp/TCP.cc index 88def89689..72cad8a05c 100644 --- a/src/analyzer/protocol/tcp/TCP.cc +++ b/src/analyzer/protocol/tcp/TCP.cc @@ -367,6 +367,41 @@ void TCP_Analyzer::Done() finished = 1; } +analyzer::Analyzer* TCP_Analyzer::FindChild(ID arg_id) + { + analyzer::Analyzer* child = analyzer::TransportLayerAnalyzer::FindChild(arg_id); + + if ( child ) + return child; + + LOOP_OVER_GIVEN_CHILDREN(i, packet_children) + { + analyzer::Analyzer* child = (*i)->FindChild(arg_id); + if ( child ) + return child; + } + + return 0; + } + +analyzer::Analyzer* TCP_Analyzer::FindChild(Tag arg_tag) + { + analyzer::Analyzer* child = analyzer::TransportLayerAnalyzer::FindChild(arg_tag); + + if ( child ) + return child; + + LOOP_OVER_GIVEN_CHILDREN(i, packet_children) + { + analyzer::Analyzer* child = (*i)->FindChild(arg_tag); + if ( child ) + return child; + } + + return 0; + } + + void TCP_Analyzer::EnableReassembly() { SetReassembler(new TCP_Reassembler(this, this, @@ -1764,6 +1799,15 @@ bool TCP_Analyzer::HadGap(bool is_orig) const return endp && endp->HadGap(); } +void TCP_Analyzer::AddChildPacketAnalyzer(analyzer::Analyzer* a) + { + DBG_LOG(DBG_ANALYZER, "%s added packet child %s", + this->GetAnalyzerName(), a->GetAnalyzerName()); + + packet_children.push_back(a); + a->SetParent(this); + } + int TCP_Analyzer::DataPending(TCP_Endpoint* closing_endp) { if ( Skipping() ) diff --git a/src/analyzer/protocol/tcp/TCP.h b/src/analyzer/protocol/tcp/TCP.h index 3073d75fb2..608c06a5aa 100644 --- a/src/analyzer/protocol/tcp/TCP.h +++ b/src/analyzer/protocol/tcp/TCP.h @@ -47,8 +47,10 @@ public: // Add a child analyzer that will always get the packets, // independently of whether we do any reassembly. - void AddChildPacketAnalyzer(analyzer::Analyzer* a) - { packet_children.push_back(a); a->SetParent(this); } + void AddChildPacketAnalyzer(analyzer::Analyzer* a); + + virtual Analyzer* FindChild(ID id); + virtual Analyzer* FindChild(Tag tag); // True if the connection has closed in some sense, false otherwise. int IsClosed() const { return orig->did_close || resp->did_close; } diff --git a/testing/btest/Baseline/core.conn-size-threshold/.stdout b/testing/btest/Baseline/core.conn-size-threshold/.stdout new file mode 100644 index 0000000000..76ad7c0696 --- /dev/null +++ b/testing/btest/Baseline/core.conn-size-threshold/.stdout @@ -0,0 +1,23 @@ +0 +0 +0 +0 +Threshold set for [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp] +3000 +2000 +63 +50 +triggered bytes, [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp], 2000, F +triggered bytes, [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp], 3000, T +triggered packets, [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp], 50, F +0 +0 +0 +0 +Threshold set for [orig_h=192.168.1.77, orig_p=57655/tcp, resp_h=209.197.168.151, resp_p=1024/tcp] +3000 +2000 +63 +50 +triggered bytes, [orig_h=192.168.1.77, orig_p=57655/tcp, resp_h=209.197.168.151, resp_p=1024/tcp], 2000, F +triggered packets, [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp], 63, T diff --git a/testing/btest/core/conn-size-threshold.bro b/testing/btest/core/conn-size-threshold.bro new file mode 100644 index 0000000000..304683e7e3 --- /dev/null +++ b/testing/btest/core/conn-size-threshold.bro @@ -0,0 +1,32 @@ +# @TEST-EXEC: bro -r $TRACES/irc-dcc-send.trace %INPUT +# @TEST-EXEC: btest-diff .stdout + +event connection_established(c: connection) + { + print get_conn_bytes_threshold(c$id, T); + print get_conn_bytes_threshold(c$id, F); + print get_conn_packets_threshold(c$id, T); + print get_conn_packets_threshold(c$id, F); + + print fmt("Threshold set for %s", cat(c$id)); + set_conn_bytes_threshold(c$id, 3000, T); + set_conn_bytes_threshold(c$id, 2000, F); + + set_conn_packets_threshold(c$id, 50, F); + set_conn_packets_threshold(c$id, 63, T); + + print get_conn_bytes_threshold(c$id, T); + print get_conn_bytes_threshold(c$id, F); + print get_conn_packets_threshold(c$id, T); + print get_conn_packets_threshold(c$id, F); + } + +event conn_bytes_threshold_crossed(c: connection, threshold: count, is_orig: bool) + { + print "triggered bytes", c$id, threshold, is_orig; + } + +event conn_packets_threshold_crossed(c: connection, threshold: count, is_orig: bool) + { + print "triggered packets", c$id, threshold, is_orig; + } From d876c044dfd9899d0aff53d7751003240879a66c Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Thu, 16 Apr 2015 15:36:48 -0700 Subject: [PATCH 27/93] Add high level api for thresholding that holds lists of thresholds and raises an event for each threshold exactly once. --- scripts/base/protocols/conn/__load__.bro | 1 + scripts/base/protocols/conn/thresholds.bro | 274 ++++++++++++++++++ src/analyzer/protocol/conn-size/ConnSize.cc | 32 +- src/analyzer/protocol/conn-size/ConnSize.h | 1 + src/analyzer/protocol/conn-size/events.bif | 16 +- src/analyzer/protocol/conn-size/functions.bif | 37 +-- .../.stdout | 10 + testing/btest/core/conn-size-threshold.bro | 24 +- .../scripts/base/protocols/conn/threshold.bro | 30 ++ 9 files changed, 381 insertions(+), 44 deletions(-) create mode 100644 scripts/base/protocols/conn/thresholds.bro create mode 100644 testing/btest/Baseline/scripts.base.protocols.conn.threshold/.stdout create mode 100644 testing/btest/scripts/base/protocols/conn/threshold.bro diff --git a/scripts/base/protocols/conn/__load__.bro b/scripts/base/protocols/conn/__load__.bro index 719486d885..7452ffa9c8 100644 --- a/scripts/base/protocols/conn/__load__.bro +++ b/scripts/base/protocols/conn/__load__.bro @@ -2,3 +2,4 @@ @load ./contents @load ./inactivity @load ./polling +@load ./thresholds diff --git a/scripts/base/protocols/conn/thresholds.bro b/scripts/base/protocols/conn/thresholds.bro new file mode 100644 index 0000000000..226ac262ce --- /dev/null +++ b/scripts/base/protocols/conn/thresholds.bro @@ -0,0 +1,274 @@ +##! Implements a generic way to throw events when a connection crosses a +##! fixed threshold of bytes or packets + +module ConnThreshold; + +export { + + type Thresholds: record { + orig_byte_thresholds: set[count] &default=count_set(); ##< current originator byte thresholds we watch for + resp_byte_thresholds: set[count] &default=count_set(); ##< current responder byte thresholds we watch for + orig_packet_thresholds: set[count] &default=count_set(); ##< corrent originator packet thresholds we watch for + resp_packet_thresholds: set[count] &default=count_set(); ##< corrent responder packet thresholds we watch for + }; + + ## Sets a byte threshold for connection sizes, adding it to potentially already existing thresholds. + ## conn_bytes_threshold_crossed will be raised for each set threshold. + ## + ## cid: The connection id. + ## + ## threshold: Threshold in bytes. + ## + ## is_orig: If true, threshold is set for bytes from originator, otherwhise for bytes from responder. + ## + ## Returns: T on success, F on failure. + ## + ## .. bro:see:: bytes_threshold_crossed packets_threshold_crossed set_packets_threshold + ## delete_bytes_threshold delete_packets_threshold + global set_bytes_threshold: function(c: connection, threshold: count, is_orig: bool): bool; + + ## Sets a packet threshold for connection sizes, adding it to potentially already existing thresholds. + ## conn_packets_threshold_crossed will be raised for each set threshold. + ## + ## cid: The connection id. + ## + ## threshold: Threshold in packets. + ## + ## is_orig: If true, threshold is set for packets from originator, otherwhise for packets from responder. + ## + ## Returns: T on success, F on failure. + ## + ## .. bro:see:: bytes_threshold_crossed packets_threshold_crossed set_bytes_threshold + ## delete_bytes_threshold delete_packets_threshold + global set_packets_threshold: function(c: connection, threshold: count, is_orig: bool): bool; + + ## Deletes a byte threshold for connection sizes. + ## + ## cid: The connection id. + ## + ## threshold: Threshold in bytes to remove. + ## + ## is_orig: If true, threshold is removed for packets from originator, otherwhise for packets from responder. + ## + ## Returns: T on success, F on failure. + ## + ## .. bro:see:: bytes_threshold_crossed packets_threshold_crossed set_bytes_threshold set_packets_threshold + ## delete_packets_threshold + global delete_bytes_threshold: function(c: connection, threshold: count, is_orig: bool): bool; + + ## Deletes a packet threshold for connection sizes. + ## + ## cid: The connection id. + ## + ## threshold: Threshold in packets. + ## + ## is_orig: If true, threshold is removed for packets from originator, otherwhise for packets from responder. + ## + ## Returns: T on success, F on failure. + ## + ## .. bro:see:: bytes_threshold_crossed packets_threshold_crossed set_bytes_threshold set_packets_threshold + ## delete_bytes_threshold + global delete_packets_threshold: function(c: connection, threshold: count, is_orig: bool): bool; + + ## Generated for a connection that crossed a set byte threshold + ## + ## c: the connection + ## + ## threshold: the threshold that was set + ## + ## is_orig: True if the threshold was crossed by the originator of the connection + ## + ## .. bro:see:: packets_threshold_crossed set_bytes_threshold set_packets_threshold + ## delete_bytes_threshold delete_packets_threshold + global bytes_threshold_crossed: event(c: connection, threshold: count, is_orig: bool); + + ## Generated for a connection that crossed a set byte threshold + ## + ## c: the connection + ## + ## threshold: the threshold that was set + ## + ## is_orig: True if the threshold was crossed by the originator of the connection + ## + ## .. bro:see:: bytes_threshold_crossed set_bytes_threshold set_packets_threshold + ## delete_bytes_threshold delete_packets_threshold + global packets_threshold_crossed: event(c: connection, threshold: count, is_orig: bool); +} + +redef record connection += { + thresholds: ConnThreshold::Thresholds &optional; +}; + +function set_conn_thresholds(c: connection) + { + if ( c?$thresholds ) + return; + + c$thresholds = Thresholds(); + } + +function find_min_threshold(t: set[count]): count + { + if ( |t| == 0 ) + return 0; + + local first = T; + local min: count = 0; + + for ( i in t ) + { + if ( first ) + { + min = i; + first = F; + } + else + { + if ( i < min ) + min = i; + } + } + + return min; + } + +function set_current_threshold(c: connection, bytes: bool, is_orig: bool): bool + { + local t: count = 0; + local cur: count = 0; + + if ( bytes && is_orig ) + { + t = find_min_threshold(c$thresholds$orig_byte_thresholds); + cur = get_current_conn_bytes_threshold(c$id, is_orig); + } + else if ( bytes && ! is_orig ) + { + t = find_min_threshold(c$thresholds$resp_byte_thresholds); + cur = get_current_conn_bytes_threshold(c$id, is_orig); + } + else if ( ! bytes && is_orig ) + { + t = find_min_threshold(c$thresholds$orig_packet_thresholds); + cur = get_current_conn_packets_threshold(c$id, is_orig); + } + else if ( ! bytes && ! is_orig ) + { + t = find_min_threshold(c$thresholds$resp_packet_thresholds); + cur = get_current_conn_packets_threshold(c$id, is_orig); + } + + if ( t == cur ) + return T; + + if ( bytes && is_orig ) + return set_current_conn_bytes_threshold(c$id, t, T); + else if ( bytes && ! is_orig ) + return set_current_conn_bytes_threshold(c$id, t, F); + else if ( ! bytes && is_orig ) + return set_current_conn_packets_threshold(c$id, t, T); + else if ( ! bytes && ! is_orig ) + return set_current_conn_packets_threshold(c$id, t, F); + } + +function set_bytes_threshold(c: connection, threshold: count, is_orig: bool): bool + { + set_conn_thresholds(c); + + if ( threshold == 0 ) + return F; + + if ( is_orig ) + add c$thresholds$orig_byte_thresholds[threshold]; + else + add c$thresholds$resp_byte_thresholds[threshold]; + + return set_current_threshold(c, T, is_orig); + } + +function set_packets_threshold(c: connection, threshold: count, is_orig: bool): bool + { + set_conn_thresholds(c); + + if ( threshold == 0 ) + return F; + + if ( is_orig ) + add c$thresholds$orig_packet_thresholds[threshold]; + else + add c$thresholds$resp_packet_thresholds[threshold]; + + return set_current_threshold(c, F, is_orig); + } + +function delete_bytes_threshold(c: connection, threshold: count, is_orig: bool): bool + { + set_conn_thresholds(c); + + if ( is_orig && threshold in c$thresholds$orig_byte_thresholds ) + { + delete c$thresholds$orig_byte_thresholds[threshold]; + set_current_threshold(c, T, is_orig); + return T; + } + else if ( ! is_orig && threshold in c$thresholds$resp_byte_thresholds ) + { + delete c$thresholds$resp_byte_thresholds[threshold]; + set_current_threshold(c, T, is_orig); + return T; + } + + return F; + } + +function delete_packets_threshold(c: connection, threshold: count, is_orig: bool): bool + { + set_conn_thresholds(c); + + if ( is_orig && threshold in c$thresholds$orig_packet_thresholds ) + { + delete c$thresholds$orig_packet_thresholds[threshold]; + set_current_threshold(c, F, is_orig); + return T; + } + else if ( ! is_orig && threshold in c$thresholds$resp_packet_thresholds ) + { + delete c$thresholds$resp_packet_thresholds[threshold]; + set_current_threshold(c, F, is_orig); + return T; + } + + return F; + } + +event conn_bytes_threshold_crossed(c: connection, threshold: count, is_orig: bool) &priority=5 + { + if ( is_orig && threshold in c$thresholds$orig_byte_thresholds ) + { + delete c$thresholds$orig_byte_thresholds[threshold]; + event ConnThreshold::bytes_threshold_crossed(c, threshold, is_orig); + } + else if ( ! is_orig && threshold in c$thresholds$resp_byte_thresholds ) + { + delete c$thresholds$resp_byte_thresholds[threshold]; + event ConnThreshold::bytes_threshold_crossed(c, threshold, is_orig); + } + + set_current_threshold(c, T, is_orig); + } + +event conn_packets_threshold_crossed(c: connection, threshold: count, is_orig: bool) &priority=5 + { + if ( is_orig && threshold in c$thresholds$orig_packet_thresholds ) + { + delete c$thresholds$orig_packet_thresholds[threshold]; + event ConnThreshold::packets_threshold_crossed(c, threshold, is_orig); + } + else if ( ! is_orig && threshold in c$thresholds$resp_packet_thresholds ) + { + delete c$thresholds$resp_packet_thresholds[threshold]; + event ConnThreshold::packets_threshold_crossed(c, threshold, is_orig); + } + + set_current_threshold(c, F, is_orig); + } diff --git a/src/analyzer/protocol/conn-size/ConnSize.cc b/src/analyzer/protocol/conn-size/ConnSize.cc index fbe6b87487..160d0bdcc3 100644 --- a/src/analyzer/protocol/conn-size/ConnSize.cc +++ b/src/analyzer/protocol/conn-size/ConnSize.cc @@ -53,15 +53,10 @@ void ConnSize_Analyzer::ThresholdEvent(EventHandlerPtr f, uint64 threshold, bool ConnectionEvent(f, vl); } -void ConnSize_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen) +void ConnSize_Analyzer::CheckSizes(bool is_orig) { - Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); - if ( is_orig ) { - orig_bytes += ip->TotalLen(); - orig_pkts ++; - if ( orig_bytes_thresh && orig_bytes >= orig_bytes_thresh ) { ThresholdEvent(conn_bytes_threshold_crossed, orig_bytes_thresh, is_orig); @@ -76,9 +71,6 @@ void ConnSize_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, } else { - resp_bytes += ip->TotalLen(); - resp_pkts ++; - if ( resp_bytes_thresh && resp_bytes >= resp_bytes_thresh ) { ThresholdEvent(conn_bytes_threshold_crossed, resp_bytes_thresh, is_orig); @@ -93,6 +85,25 @@ void ConnSize_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, } } +void ConnSize_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen) + { + Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); + + if ( is_orig ) + { + orig_bytes += ip->TotalLen(); + orig_pkts ++; + + } + else + { + resp_bytes += ip->TotalLen(); + resp_pkts ++; + } + + CheckSizes(is_orig); + } + void ConnSize_Analyzer::SetThreshold(uint64 threshold, bool bytes, bool orig) { if ( bytes ) @@ -109,6 +120,9 @@ void ConnSize_Analyzer::SetThreshold(uint64 threshold, bool bytes, bool orig) else resp_pkts_thresh = threshold; } + + // check if threshold is already crossed + CheckSizes(orig); } uint64_t ConnSize_Analyzer::GetThreshold(bool bytes, bool orig) diff --git a/src/analyzer/protocol/conn-size/ConnSize.h b/src/analyzer/protocol/conn-size/ConnSize.h index 41388ceb3c..d8dff57a1b 100644 --- a/src/analyzer/protocol/conn-size/ConnSize.h +++ b/src/analyzer/protocol/conn-size/ConnSize.h @@ -30,6 +30,7 @@ public: protected: virtual void DeliverPacket(int len, const u_char* data, bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen); + void CheckSizes(bool is_orig); void ThresholdEvent(EventHandlerPtr f, uint64 threshold, bool is_orig); diff --git a/src/analyzer/protocol/conn-size/events.bif b/src/analyzer/protocol/conn-size/events.bif index ab1034ebb8..14708e55b5 100644 --- a/src/analyzer/protocol/conn-size/events.bif +++ b/src/analyzer/protocol/conn-size/events.bif @@ -1,4 +1,6 @@ -## Generated for a connection that crossed a set byte threshold +## Generated for a connection that crossed a set byte threshold. Note that this +## is a low level event that can fire several times for the same threshold - you +## should probably use ConnThreshold::bytes_threshold_crossed instead. ## ## c: the connection ## @@ -6,11 +8,13 @@ ## ## is_orig: True if the threshold was crossed by the originator of the connection ## -## .. bro:see:: set_conn_packets_threshold set_conn_bytes_threshold conn_packets_threshold_crossed -## get_conn_bytes_threshold get_conn_packets_threshold +## .. bro:see:: set_current_conn_packets_threshold set_current_conn_bytes_threshold conn_packets_threshold_crossed +## get_current_conn_bytes_threshold get_current_conn_packets_threshold event conn_bytes_threshold_crossed%(c: connection, threshold: count, is_orig: bool%); -## Generated for a connection that crossed a set packet threshold +## Generated for a connection that crossed a set packet threshold. Note that this +## is a low level event that can fire several times for the same threshold - you +## should probably use ConnThreshold::packets_threshold_crossed instead. ## ## c: the connection ## @@ -18,6 +22,6 @@ event conn_bytes_threshold_crossed%(c: connection, threshold: count, is_orig: bo ## ## is_orig: True if the threshold was crossed by the originator of the connection ## -## .. bro:see:: set_conn_packets_threshold set_conn_bytes_threshold conn_bytes_threshold_crossed -## get_conn_bytes_threshold get_conn_packets_threshold +## .. bro:see:: set_current_conn_packets_threshold set_current_conn_bytes_threshold conn_bytes_threshold_crossed +## get_current_conn_bytes_threshold get_current_conn_packets_threshold event conn_packets_threshold_crossed%(c: connection, threshold: count, is_orig: bool%); diff --git a/src/analyzer/protocol/conn-size/functions.bif b/src/analyzer/protocol/conn-size/functions.bif index 838c5976c4..cec59a09da 100644 --- a/src/analyzer/protocol/conn-size/functions.bif +++ b/src/analyzer/protocol/conn-size/functions.bif @@ -1,4 +1,3 @@ - %%{ #include "analyzer/protocol/conn-size/ConnSize.h" @@ -20,7 +19,9 @@ analyzer::Analyzer* GetConnsizeAnalyzer(Val* cid) %%} -## Sets a threshold for connection sizes. +## Sets the current byte threshold for connection sizes, overwriting any potential old +## threshold. Be aware that in nearly any case you will want to use the high level API +## instead (ConnThreshold::set_bytes_threshold). ## ## cid: The connection id. ## @@ -28,9 +29,9 @@ analyzer::Analyzer* GetConnsizeAnalyzer(Val* cid) ## ## is_orig: If true, threshold is set for bytes from originator, otherwhise for bytes from responder. ## -## .. bro:see:: set_conn_packets_threshold conn_bytes_threshold_crossed conn_packets_threshold_crossed -## get_conn_bytes_threshold get_conn_packets_threshold -function set_conn_bytes_threshold%(cid: conn_id, threshold: count, is_orig: bool%): bool +## .. bro:see:: set_current_conn_packets_threshold conn_bytes_threshold_crossed conn_packets_threshold_crossed +## get_current_conn_bytes_threshold get_current_conn_packets_threshold +function set_current_conn_bytes_threshold%(cid: conn_id, threshold: count, is_orig: bool%): bool %{ analyzer::Analyzer* a = GetConnsizeAnalyzer(cid); if ( ! a ) @@ -38,10 +39,12 @@ function set_conn_bytes_threshold%(cid: conn_id, threshold: count, is_orig: bool static_cast(a)->SetThreshold(threshold, 1, is_orig); - return new Val(0, TYPE_BOOL); + return new Val(1, TYPE_BOOL); %} -## Sets a threshold for connection packets. +## Sets a threshold for connection packets, overwtiting any potential old thresholds. +## Be aware that in nearly any case you will want to use the high level API +## instead (ConnThreshold::set_packets_threshold). ## ## cid: The connection id. ## @@ -49,9 +52,9 @@ function set_conn_bytes_threshold%(cid: conn_id, threshold: count, is_orig: bool ## ## is_orig: If true, threshold is set for packets from originator, otherwhise for packets from responder. ## -## .. bro:see:: set_conn_bytes_threshold conn_bytes_threshold_crossed conn_packets_threshold_crossed -## get_conn_bytes_threshold get_conn_packets_threshold -function set_conn_packets_threshold%(cid: conn_id, threshold: count, is_orig: bool%): bool +## .. bro:see:: set_current_conn_bytes_threshold conn_bytes_threshold_crossed conn_packets_threshold_crossed +## get_current_conn_bytes_threshold get_current_conn_packets_threshold +function set_current_conn_packets_threshold%(cid: conn_id, threshold: count, is_orig: bool%): bool %{ analyzer::Analyzer* a = GetConnsizeAnalyzer(cid); if ( ! a ) @@ -59,7 +62,7 @@ function set_conn_packets_threshold%(cid: conn_id, threshold: count, is_orig: bo static_cast(a)->SetThreshold(threshold, 0, is_orig); - return new Val(0, TYPE_BOOL); + return new Val(1, TYPE_BOOL); %} ## Gets the current byte threshold size for a connection. @@ -70,9 +73,9 @@ function set_conn_packets_threshold%(cid: conn_id, threshold: count, is_orig: bo ## ## Returns: 0 if no threshold is set or the threshold in bytes ## -## .. bro:see:: set_conn_packets_threshold conn_bytes_threshold_crossed conn_packets_threshold_crossed -## get_conn_packets_threshold -function get_conn_bytes_threshold%(cid: conn_id, is_orig: bool%): count +## .. bro:see:: set_current_conn_packets_threshold conn_bytes_threshold_crossed conn_packets_threshold_crossed +## get_current_conn_packets_threshold +function get_current_conn_bytes_threshold%(cid: conn_id, is_orig: bool%): count %{ analyzer::Analyzer* a = GetConnsizeAnalyzer(cid); if ( ! a ) @@ -91,9 +94,9 @@ function get_conn_bytes_threshold%(cid: conn_id, is_orig: bool%): count ## ## Returns: 0 if no threshold is set or the threshold in packets ## -## .. bro:see:: set_conn_packets_threshold conn_bytes_threshold_crossed conn_packets_threshold_crossed -## get_conn_bytes_threshold -function get_conn_packets_threshold%(cid: conn_id, is_orig: bool%): count +## .. bro:see:: set_current_conn_packets_threshold conn_bytes_threshold_crossed conn_packets_threshold_crossed +## get_current_conn_bytes_threshold +function get_current_conn_packets_threshold%(cid: conn_id, is_orig: bool%): count %{ analyzer::Analyzer* a = GetConnsizeAnalyzer(cid); if ( ! a ) diff --git a/testing/btest/Baseline/scripts.base.protocols.conn.threshold/.stdout b/testing/btest/Baseline/scripts.base.protocols.conn.threshold/.stdout new file mode 100644 index 0000000000..f5ae35abc3 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.conn.threshold/.stdout @@ -0,0 +1,10 @@ +Threshold set for [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp] +triggered bytes, [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp], 1, T +triggered bytes, [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp], 2000, F +triggered bytes, [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp], 2500, T +triggered bytes, [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp], 2700, T +triggered packets, [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp], 50, F +Threshold set for [orig_h=192.168.1.77, orig_p=57655/tcp, resp_h=209.197.168.151, resp_p=1024/tcp] +triggered bytes, [orig_h=192.168.1.77, orig_p=57655/tcp, resp_h=209.197.168.151, resp_p=1024/tcp], 1, T +triggered bytes, [orig_h=192.168.1.77, orig_p=57655/tcp, resp_h=209.197.168.151, resp_p=1024/tcp], 2000, F +triggered packets, [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp], 52, F diff --git a/testing/btest/core/conn-size-threshold.bro b/testing/btest/core/conn-size-threshold.bro index 304683e7e3..ce83e5939d 100644 --- a/testing/btest/core/conn-size-threshold.bro +++ b/testing/btest/core/conn-size-threshold.bro @@ -3,22 +3,22 @@ event connection_established(c: connection) { - print get_conn_bytes_threshold(c$id, T); - print get_conn_bytes_threshold(c$id, F); - print get_conn_packets_threshold(c$id, T); - print get_conn_packets_threshold(c$id, F); + print get_current_conn_bytes_threshold(c$id, T); + print get_current_conn_bytes_threshold(c$id, F); + print get_current_conn_packets_threshold(c$id, T); + print get_current_conn_packets_threshold(c$id, F); print fmt("Threshold set for %s", cat(c$id)); - set_conn_bytes_threshold(c$id, 3000, T); - set_conn_bytes_threshold(c$id, 2000, F); + set_current_conn_bytes_threshold(c$id, 3000, T); + set_current_conn_bytes_threshold(c$id, 2000, F); - set_conn_packets_threshold(c$id, 50, F); - set_conn_packets_threshold(c$id, 63, T); + set_current_conn_packets_threshold(c$id, 50, F); + set_current_conn_packets_threshold(c$id, 63, T); - print get_conn_bytes_threshold(c$id, T); - print get_conn_bytes_threshold(c$id, F); - print get_conn_packets_threshold(c$id, T); - print get_conn_packets_threshold(c$id, F); + print get_current_conn_bytes_threshold(c$id, T); + print get_current_conn_bytes_threshold(c$id, F); + print get_current_conn_packets_threshold(c$id, T); + print get_current_conn_packets_threshold(c$id, F); } event conn_bytes_threshold_crossed(c: connection, threshold: count, is_orig: bool) diff --git a/testing/btest/scripts/base/protocols/conn/threshold.bro b/testing/btest/scripts/base/protocols/conn/threshold.bro new file mode 100644 index 0000000000..13daa8fff0 --- /dev/null +++ b/testing/btest/scripts/base/protocols/conn/threshold.bro @@ -0,0 +1,30 @@ +# @TEST-EXEC: bro -r $TRACES/irc-dcc-send.trace %INPUT +# @TEST-EXEC: btest-diff .stdout + +event connection_established(c: connection) + { + print fmt("Threshold set for %s", cat(c$id)); + ConnThreshold::set_bytes_threshold(c, 1, T); + ConnThreshold::set_bytes_threshold(c, 2500, T); + ConnThreshold::set_bytes_threshold(c, 2700, T); + ConnThreshold::set_bytes_threshold(c, 3000, T); + ConnThreshold::delete_bytes_threshold(c, 3000, T); + ConnThreshold::set_bytes_threshold(c, 2000, F); + + ConnThreshold::set_packets_threshold(c, 50, F); + ConnThreshold::set_packets_threshold(c, 51, F); + ConnThreshold::set_packets_threshold(c, 52, F); + ConnThreshold::delete_packets_threshold(c, 51, F); + ConnThreshold::set_packets_threshold(c, 63, T); + ConnThreshold::delete_packets_threshold(c, 63, T); + } + +event ConnThreshold::bytes_threshold_crossed(c: connection, threshold: count, is_orig: bool) + { + print "triggered bytes", c$id, threshold, is_orig; + } + +event ConnThreshold::packets_threshold_crossed(c: connection, threshold: count, is_orig: bool) + { + print "triggered packets", c$id, threshold, is_orig; + } From e21238d454696844bf4c7910ad8caa552e0c97e7 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Thu, 16 Apr 2015 15:44:46 -0700 Subject: [PATCH 28/93] add a few more flow_mod options and the option to check via a predicate if a module wants to be responsible for a certain rule... --- scripts/base/frameworks/openflow/plugins/ryu.bro | 7 +++++++ scripts/base/frameworks/openflow/types.bro | 3 ++- scripts/base/frameworks/pacf/plugins/openflow.bro | 14 +++++++++----- scripts/base/frameworks/pacf/types.bro | 2 +- .../openflow.log | 14 +++++++------- 5 files changed, 26 insertions(+), 14 deletions(-) diff --git a/scripts/base/frameworks/openflow/plugins/ryu.bro b/scripts/base/frameworks/openflow/plugins/ryu.bro index 79d6a4a6fe..2340ac4d60 100644 --- a/scripts/base/frameworks/openflow/plugins/ryu.bro +++ b/scripts/base/frameworks/openflow/plugins/ryu.bro @@ -60,6 +60,8 @@ type ryu_ofp_flow_mod: record { 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 @@ -98,6 +100,11 @@ function ryu_flow_mod(state: OpenFlow::ControllerState, match: ofp_match, flow_m $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; diff --git a/scripts/base/frameworks/openflow/types.bro b/scripts/base/frameworks/openflow/types.bro index 6c10b80125..26862f6df3 100644 --- a/scripts/base/frameworks/openflow/types.bro +++ b/scripts/base/frameworks/openflow/types.bro @@ -70,7 +70,8 @@ export { ## Priority level of flow entry. priority: count &default=0; ## For OFPFC_DELETE* commands, require matching entried to include - ## this as an output port. OFPP_ANY means no restrictions. + ## 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; diff --git a/scripts/base/frameworks/pacf/plugins/openflow.bro b/scripts/base/frameworks/pacf/plugins/openflow.bro index 8bda72092e..518f6cec28 100644 --- a/scripts/base/frameworks/pacf/plugins/openflow.bro +++ b/scripts/base/frameworks/pacf/plugins/openflow.bro @@ -10,6 +10,7 @@ export { idle_timeout: count &default=60; table_id: count &optional; + check_pred: function(p: PluginState, r: Rule): bool &optional &weaken; match_pred: function(p: PluginState, e: Entity, m: vector of OpenFlow::ofp_match): vector of OpenFlow::ofp_match &optional &weaken; flow_mod_pred: function(p: PluginState, r: Rule, m: OpenFlow::ofp_flow_mod): OpenFlow::ofp_flow_mod &optional &weaken; }; @@ -30,8 +31,13 @@ function openflow_name(p: PluginState) : string return fmt("Openflow - %s", p$of_controller$describe(p$of_controller$state)); } -function openflow_check_rule(c: OfConfig, r: Rule) : bool +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; @@ -183,9 +189,7 @@ function openflow_rule_to_flow_mod(p: PluginState, r: Rule) : OpenFlow::ofp_flow function openflow_add_rule(p: PluginState, r: Rule) : bool { - local c = p$of_config; - - if ( ! openflow_check_rule(c, r) ) + if ( ! openflow_check_rule(p, r) ) return F; local flow_mod = openflow_rule_to_flow_mod(p, r); @@ -202,7 +206,7 @@ function openflow_add_rule(p: PluginState, r: Rule) : bool function openflow_remove_rule(p: PluginState, r: Rule) : bool { - if ( ! openflow_check_rule(p$of_config, r) ) + if ( ! openflow_check_rule(p, r) ) return F; local flow_mod: OpenFlow::ofp_flow_mod = [ diff --git a/scripts/base/frameworks/pacf/types.bro b/scripts/base/frameworks/pacf/types.bro index b1663f19d9..08fa7bfeb8 100644 --- a/scripts/base/frameworks/pacf/types.bro +++ b/scripts/base/frameworks/pacf/types.bro @@ -21,7 +21,7 @@ export { conn: conn_id &optional; ##< Used with :bro:id:`CONNECTION` . flow: flow_id &optional; ##< Used with :bro:id:`FLOW` . ip: subnet &optional; ##< Used with :bro:id:`ORIGINATOR`/:bro:id:`RESPONDER`/:bro:id:`ADDRESS`; can specifiy a CIDR subnet. - mac: string &optional; ##< Used with :bro:id:`MAC`/:bro:id:`ORIGMAC`/:bro:id:`DESTMAC`. + mac: string &optional; ##< Used with :bro:id:`MAC`/:bro:id:`ORIGMAC`/:bro:id:`DESTMAC`/:bro:id:`MACFLOW`. dst_mac: string &optional; ##< Used with :bro:id:`MACFLOW`; specifies the destination for the flow. }; diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log index 6031a6cdc0..c43ddd9f85 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log @@ -3,10 +3,10 @@ #empty_field (empty) #unset_field - #path openflow -#open 2015-04-14-22-20-31 -#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_group flow_mod.flags flow_mod.out_ports -#types time count count string string count count count count count subnet subnet port port count count enum count count count count count vector[count] -1254722767.875996 42 - - - - - 2048 - 6 10.10.1.4/32 74.53.140.153/32 1470 25 2 - OpenFlow::OFPFC_ADD 60 30 0 - 0 (empty) -1254722767.875996 42 - - - - - 2048 - - 10.10.1.4/32 - - - 3 - OpenFlow::OFPFC_ADD 60 15 0 - 0 (empty) -1254722767.875996 42 - - - - - 2048 - - - 10.10.1.4/32 - - 3 - OpenFlow::OFPFC_ADD 60 15 0 - 0 (empty) -#close 2015-04-14-22-20-31 +#open 2015-04-15-19-15-14 +#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.out_ports +#types time count count string string count count count count count subnet subnet port port count count enum count count count count count count vector[count] +1254722767.875996 42 - - - - - 2048 - 6 10.10.1.4/32 74.53.140.153/32 1470 25 2 - OpenFlow::OFPFC_ADD 60 30 0 - - 0 (empty) +1254722767.875996 42 - - - - - 2048 - - 10.10.1.4/32 - - - 3 - OpenFlow::OFPFC_ADD 60 15 0 - - 0 (empty) +1254722767.875996 42 - - - - - 2048 - - - 10.10.1.4/32 - - 3 - OpenFlow::OFPFC_ADD 60 15 0 - - 0 (empty) +#close 2015-04-15-19-15-14 From a403dbd83ef80efd80a0df3c6338fe2cd719fc7f Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Mon, 20 Apr 2015 16:05:27 -0700 Subject: [PATCH 29/93] add broker output plugin for openflow (at the moment we more or less just send the flow_mod event along - there still is no feedback) and add a testcase for it. Also fix a few other small problems. --- .../frameworks/openflow/plugins/__load__.bro | 1 + .../frameworks/openflow/plugins/broker.bro | 64 +++++++++++ .../base/frameworks/openflow/plugins/log.bro | 12 +- .../base/frameworks/openflow/plugins/ryu.bro | 2 +- .../base/frameworks/pacf/plugins/openflow.bro | 4 +- .../recv.recv.out | 5 + .../send.send.out | 2 + .../openflow.log | 14 +-- .../base/frameworks/openflow/broker-basic.bro | 106 ++++++++++++++++++ 9 files changed, 195 insertions(+), 15 deletions(-) create mode 100644 scripts/base/frameworks/openflow/plugins/broker.bro create mode 100644 testing/btest/Baseline/scripts.base.frameworks.openflow.broker-basic/recv.recv.out create mode 100644 testing/btest/Baseline/scripts.base.frameworks.openflow.broker-basic/send.send.out create mode 100644 testing/btest/scripts/base/frameworks/openflow/broker-basic.bro diff --git a/scripts/base/frameworks/openflow/plugins/__load__.bro b/scripts/base/frameworks/openflow/plugins/__load__.bro index bf83a61648..e387132034 100644 --- a/scripts/base/frameworks/openflow/plugins/__load__.bro +++ b/scripts/base/frameworks/openflow/plugins/__load__.bro @@ -1,2 +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..9d0f55ad40 --- /dev/null +++ b/scripts/base/frameworks/openflow/plugins/broker.bro @@ -0,0 +1,64 @@ +@load base/frameworks/openflow + +module OpenFlow; + +export { + redef enum Plugin += { + BROKER, + }; + + ## Broker controller constructor. + ## + ## host: Controller ip. + ## + ## host_port: Controller listen port. + ## + ## dpid: OpenFlow switch datapath id. + ## + ## Returns: OpenFlow::Controller record + global broker_new: function(host: addr, host_port: port, 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; + }; + + global broker_flow_mod: event(dpid: count, match: ofp_match, flow_mod: ofp_flow_mod); + global broker_flow_clear: event(dpid: count); +} + +function broker_describe(state: ControllerState): string + { + return fmt("Broker Plugin - %s:%d - DPID: %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 + { + event OpenFlow::broker_flow_mod(state$broker_dpid, match, flow_mod); + + return T; + } + +function broker_flow_clear_fun(state: OpenFlow::ControllerState): bool + { + event OpenFlow::broker_flow_clear(state$broker_dpid); + + return T; + } + +# broker controller constructor +function broker_new(host: addr, host_port: port, dpid: count): OpenFlow::Controller + { + BrokerComm::enable(); + BrokerComm::auto_event("bro/event/openflow", broker_flow_mod); + BrokerComm::auto_event("bro/event/openflow", broker_flow_clear); + BrokerComm::connect(cat(host), host_port, 1sec); + + return [$state=[$broker_host=host, $broker_port=host_port, $broker_dpid=dpid, $_plugin=OpenFlow::BROKER], + $flow_mod=broker_flow_mod_fun, $flow_clear=broker_flow_clear_fun, $describe=broker_describe]; + } + diff --git a/scripts/base/frameworks/openflow/plugins/log.bro b/scripts/base/frameworks/openflow/plugins/log.bro index cef252b95d..ddfea6c593 100644 --- a/scripts/base/frameworks/openflow/plugins/log.bro +++ b/scripts/base/frameworks/openflow/plugins/log.bro @@ -1,16 +1,18 @@ ##! OpenFlow module that outputs flow-modification commands ##! to a Bro log file. -module OpenFlow; - @load base/frameworks/openflow @load base/frameworks/logging +module OpenFlow; + export { redef enum Plugin += { - LOG, + OFLOG, }; + redef enum Log::ID += { LOG }; + ## Log controller constructor. ## ## dpid: OpenFlow switch datapath id. @@ -42,12 +44,12 @@ export { event bro_init() &priority=5 { - Log::create_stream(LOG, [$columns=Info, $ev=log_openflow, $path="openflow"]); + 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(LOG, [$ts=network_time(), $dpid=state$log_dpid, $match=match, $flow_mod=flow_mod]); + Log::write(OpenFlow::LOG, [$ts=network_time(), $dpid=state$log_dpid, $match=match, $flow_mod=flow_mod]); return T; } diff --git a/scripts/base/frameworks/openflow/plugins/ryu.bro b/scripts/base/frameworks/openflow/plugins/ryu.bro index 2340ac4d60..b4ca157a7f 100644 --- a/scripts/base/frameworks/openflow/plugins/ryu.bro +++ b/scripts/base/frameworks/openflow/plugins/ryu.bro @@ -149,7 +149,7 @@ function ryu_flow_mod(state: OpenFlow::ControllerState, match: ofp_match, flow_m return T; } -function ryu_flow_clear(state: OpenFlow::ControllerState): bool +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); diff --git a/scripts/base/frameworks/pacf/plugins/openflow.bro b/scripts/base/frameworks/pacf/plugins/openflow.bro index 518f6cec28..fb7fd59bda 100644 --- a/scripts/base/frameworks/pacf/plugins/openflow.bro +++ b/scripts/base/frameworks/pacf/plugins/openflow.bro @@ -163,7 +163,7 @@ function openflow_rule_to_flow_mod(p: PluginState, r: Rule) : OpenFlow::ofp_flow 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; + flow_mod$table_id = c$table_id; if ( r$ty == DROP ) { @@ -181,7 +181,7 @@ function openflow_rule_to_flow_mod(p: PluginState, r: Rule) : OpenFlow::ofp_flow } else { - Reporter::error(fmt("Rule type %s not supported for openflow yet", cat(r$ty))); + Reporter::error(fmt("Rule type %s not supported for openflow yet", cat(r$ty))); } return openflow_flow_mod_pred(p, r, flow_mod); 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..4b0317a8c7 --- /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=1, table_id=, command=OpenFlow::OFPFC_ADD, idle_timeout=0, hard_timeout=0, priority=0, out_port=, out_group=, flags=0, out_ports=[3, 7]] +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/tcp, tp_dst=25/tcp], [cookie=42, table_id=, command=OpenFlow::OFPFC_ADD, idle_timeout=30, hard_timeout=0, priority=5, out_port=, out_group=, flags=0, out_ports=[]] +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/tcp, tp_dst=25/tcp], [cookie=42, table_id=, command=OpenFlow::OFPFC_ADD, idle_timeout=30, hard_timeout=0, priority=5, out_port=, out_group=, flags=0, out_ports=[]] 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..b283919533 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.openflow.broker-basic/send.send.out @@ -0,0 +1,2 @@ +BrokerComm::outgoing_connection_established, 127.0.0.1, 9999/tcp +connection established 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 index abfe8d961a..5a41312f18 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.openflow.log-basic/openflow.log +++ b/testing/btest/Baseline/scripts.base.frameworks.openflow.log-basic/openflow.log @@ -3,10 +3,10 @@ #empty_field (empty) #unset_field - #path openflow -#open 2015-04-14-21-58-29 -#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_group flow_mod.flags flow_mod.out_ports -#types time count count string string count count count count count subnet subnet port port count count enum count count count count count vector[count] -0.000000 42 - - - - - - - - - - - - 1 - OpenFlow::OFPFC_ADD 0 0 0 - 0 3,7 -1254722767.875996 42 - - - - - 2048 - 6 10.10.1.4/32 74.53.140.153/32 1470 25 42 - OpenFlow::OFPFC_ADD 30 0 5 - 0 (empty) -1254722767.875996 42 - - - - - 2048 - 6 74.53.140.153/32 10.10.1.4/32 25 25 42 - OpenFlow::OFPFC_ADD 30 0 5 - 0 (empty) -#close 2015-04-14-21-58-29 +#open 2015-04-20-20-22-44 +#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.out_ports +#types time count count string string count count count count count subnet subnet port port count count enum count count count count count count vector[count] +0.000000 42 - - - - - - - - - - - - 1 - OpenFlow::OFPFC_ADD 0 0 0 - - 0 3,7 +1254722767.875996 42 - - - - - 2048 - 6 10.10.1.4/32 74.53.140.153/32 1470 25 42 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) +1254722767.875996 42 - - - - - 2048 - 6 74.53.140.153/32 10.10.1.4/32 25 25 42 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) +#close 2015-04-20-20-22-44 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..3874d46f5a --- /dev/null +++ b/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro @@ -0,0 +1,106 @@ +# @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(127.0.0.1, broker_port, 42); + } + +event BrokerComm::outgoing_connection_established(peer_address: string, + peer_port: port, + peer_name: string) + { + print "BrokerComm::outgoing_connection_established", peer_address, peer_port; + continue_processing(); + OpenFlow::flow_clear(of_controller); + OpenFlow::flow_mod(of_controller, [], [$cookie=1, $command=OpenFlow::OFPFC_ADD, $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=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); + } + + +@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::subscribe_to_events("bro/event/test_event"); + 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(dpid: count, match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod) + { + print "got flow_mod", dpid, match, flow_mod; + got_message(); + } + +event OpenFlow::broker_flow_clear(dpid: count) + { + print "flow_clear", dpid; + got_message(); + } + + +@TEST-END-FILE + From ed65fdb6ba4d6a36471dc89bd730a48c09acd0bc Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 12 May 2015 13:37:16 -0700 Subject: [PATCH 30/93] Make Flow a separate, more flexible type in PACF. This allows the use of wildcards, etc. in rules and removes the need for a few entity types that were separate so far. --- scripts/base/frameworks/pacf/main.bro | 10 +- .../base/frameworks/pacf/plugins/openflow.bro | 112 +++++++++++------- scripts/base/frameworks/pacf/types.bro | 24 ++-- .../.stdout | 6 +- .../pacf.log | 12 +- .../pacf.log | 6 +- 6 files changed, 101 insertions(+), 69 deletions(-) diff --git a/scripts/base/frameworks/pacf/main.bro b/scripts/base/frameworks/pacf/main.bro index c3b696bec2..c77edec8ef 100644 --- a/scripts/base/frameworks/pacf/main.bro +++ b/scripts/base/frameworks/pacf/main.bro @@ -265,7 +265,7 @@ function entity_to_info(info: Info, e: Entity) info$entity_type = fmt("%s", e$ty); switch ( e$ty ) { - case ADDRESS, ORIGINATOR, RESPONDER: + case ADDRESS: info$entity = fmt("%s", e$ip); break; @@ -364,7 +364,13 @@ function drop_address(a: addr, t: interval, location: string &default="") : bool function shunt_flow(f: flow_id, t: interval, location: string &default="") : bool { - local e: Entity = [$ty=FLOW, $flow=f]; + local flow = Pacf::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); diff --git a/scripts/base/frameworks/pacf/plugins/openflow.bro b/scripts/base/frameworks/pacf/plugins/openflow.bro index fb7fd59bda..d87b83f7d6 100644 --- a/scripts/base/frameworks/pacf/plugins/openflow.bro +++ b/scripts/base/frameworks/pacf/plugins/openflow.bro @@ -63,6 +63,26 @@ function openflow_flow_mod_pred(p: PluginState, r: Rule, m: OpenFlow::ofp_flow_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(); @@ -74,49 +94,34 @@ function entity_to_match(p: PluginState, e: Entity): vector of OpenFlow::ofp_mat return openflow_match_pred(p, e, v); } - if ( e$ty == MAC || e$ty == ORIGMAC || e$ty == DESTMAC ) + if ( e$ty == MAC ) { - if ( e$ty == MAC || e$ty == ORIGMAC ) - v[|v|] = OpenFlow::ofp_match( - $dl_src=e$mac - ); - - if ( e$ty == MAC || e$ty == DESTMAC ) - v[|v|] = OpenFlow::ofp_match( - $dl_dst=e$mac - ); - - return openflow_match_pred(p, e, v); - } - - if ( e$ty == MACFLOW ) - { - v[|v|] = OpenFlow::ofp_match( - $dl_src=e$mac, - $dl_dst=e$dst_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 || e$ty == RESPONDER || e$ty == ORIGINATOR ) + if ( e$ty == ADDRESS ) { if ( is_v6_subnet(e$ip) ) dl_type = OpenFlow::ETH_IPv6; - if ( e$ty == ADDRESS || e$ty == ORIGINATOR ) - v[|v|] = OpenFlow::ofp_match( - $dl_type=dl_type, - $nw_src=e$ip - ); + v[|v|] = OpenFlow::ofp_match( + $dl_type=dl_type, + $nw_src=e$ip + ); - if ( e$ty == ADDRESS || e$ty == RESPONDER ) - v[|v|] = OpenFlow::ofp_match( - $dl_type=dl_type, - $nw_dst=e$ip - ); + v[|v|] = OpenFlow::ofp_match( + $dl_type=dl_type, + $nw_dst=e$ip + ); return openflow_match_pred(p, e, v); } @@ -125,22 +130,39 @@ function entity_to_match(p: PluginState, e: Entity): vector of OpenFlow::ofp_mat if ( e$ty == FLOW ) { - if ( is_v6_addr(e$flow$src_h) ) - dl_type = OpenFlow::ETH_IPv6; + local m = OpenFlow::ofp_match(); + local f = e$flow; - if ( is_udp_port(e$flow$src_p) ) - proto = OpenFlow::IP_UDP; - else if ( is_icmp_port(e$flow$src_p) ) - proto = OpenFlow::IP_ICMP; + if ( f?$src_m ) + m$dl_src=f$src_m; + if ( f?$dst_m ) + m$dl_dst=f$dst_m; - v[|v|] = OpenFlow::ofp_match( - $dl_type=dl_type, - $nw_proto=proto, - $nw_src=addr_to_subnet(e$flow$src_h), - $tp_src=e$flow$src_p, - $nw_dst=addr_to_subnet(e$flow$dst_h), - $tp_dst=e$flow$dst_p - ); + 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 = f$src_p; + } + + if ( f?$dst_p ) + { + m$nw_proto = determine_proto(f$dst_p); + m$tp_dst = f$dst_p; + } + + v[|v|] = m; return openflow_match_pred(p, e, v); } diff --git a/scripts/base/frameworks/pacf/types.bro b/scripts/base/frameworks/pacf/types.bro index 08fa7bfeb8..4870135624 100644 --- a/scripts/base/frameworks/pacf/types.bro +++ b/scripts/base/frameworks/pacf/types.bro @@ -5,24 +5,28 @@ export { ## Type of a :bro:id:`Entity` for defining an action. type EntityType: enum { ADDRESS, ##< Activity involving a specific IP address. - ORIGINATOR, ##< Activity *from* a source IP address. - RESPONDER, ##< Activity *to* a destination IP address. CONNECTION, ##< All of a bi-directional connection's activity. - FLOW, ##< All of a uni-directional flow's activity. + FLOW, ##< All of a uni-directional flow's activity. Can contain wildcards. MAC, ##< Activity involving a MAC address. - ORIGMAC, ##< Activity *from* a source MAC address. - DESTMAC, ##< Activity *to* a destination MAC adress. - MACFLOW ##< Activity involving a pair of MAC addresses. + }; + + ## 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_id &optional; ##< Used with :bro:id:`FLOW` . - ip: subnet &optional; ##< Used with :bro:id:`ORIGINATOR`/:bro:id:`RESPONDER`/:bro:id:`ADDRESS`; can specifiy a CIDR subnet. - mac: string &optional; ##< Used with :bro:id:`MAC`/:bro:id:`ORIGMAC`/:bro:id:`DESTMAC`/:bro:id:`MACFLOW`. - dst_mac: string &optional; ##< Used with :bro:id:`MACFLOW`; specifies the destination for the flow. + 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. diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout index 30e8520853..3968f4e091 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout @@ -1,4 +1,4 @@ -pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=10.10.1.4, src_p=1470/tcp, dst_h=74.53.140.153, dst_p=25/tcp], ip=, mac=], expire=30.0 secs, priority=0, location=, i=, d=, s=, id=2, _plugin=] +pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, i=, d=, s=, id=2, _plugin=] pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, i=, d=, s=, id=3, _plugin=] -pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, i=, d=, s=, id=3, _plugin=[config={^J^I[all] = 1^J}, _priority=0, plugin=[name=Pacf::debug_name^J{ ^Jreturn (fmt(Debug-%s, (Pacf::do_something(Pacf::p) ? All : None)));^J}, can_expire=F, init=Pacf::debug_init^J{ ^JPacf::debug_log(Pacf::p, init);^J}, done=Pacf::debug_done^J{ ^JPacf::debug_log(Pacf::p, init);^J}, add_rule=Pacf::debug_add_rule^J{ ^JPacf::s = fmt(add_rule: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jif (Pacf::do_something(Pacf::p)) ^J^I{ ^J^Ievent Pacf::rule_added(Pacf::r, Pacf::p, );^J^Ireturn (T);^J^I}^J^Jreturn (F);^J}, remove_rule=Pacf::debug_remove_rule^J{ ^JPacf::s = fmt(remove_rule: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jevent Pacf::rule_removed(Pacf::r, Pacf::p, );^Jreturn (T);^J}, add_notification=Pacf::debug_add_notification^J{ ^JPacf::s = fmt(add_notification: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jif (Pacf::do_something(Pacf::p)) ^J^I{ ^J^Ievent Pacf::notification_added(Pacf::r, Pacf::p, );^J^Ireturn (T);^J^I}^J^Jreturn (F);^J}, remove_notification=Pacf::debug_remove_notification^J{ ^JPacf::s = fmt(remove_notification: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jreturn (Pacf::do_something(Pacf::p));^J}, transaction_begin=Pacf::debug_transaction_begin^J{ ^JPacf::debug_log(Pacf::p, transaction_begin);^J}, transaction_end=Pacf::debug_transaction_end^J{ ^JPacf::debug_log(Pacf::p, transaction_end);^J}], of_controller=, of_config=]] -pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=10.10.1.4, src_p=1470/tcp, dst_h=74.53.140.153, dst_p=25/tcp], ip=, mac=], expire=30.0 secs, priority=0, location=, i=, d=, s=, id=2, _plugin=[config={^J^I[all] = 1^J}, _priority=0, plugin=[name=Pacf::debug_name^J{ ^Jreturn (fmt(Debug-%s, (Pacf::do_something(Pacf::p) ? All : None)));^J}, can_expire=F, init=Pacf::debug_init^J{ ^JPacf::debug_log(Pacf::p, init);^J}, done=Pacf::debug_done^J{ ^JPacf::debug_log(Pacf::p, init);^J}, add_rule=Pacf::debug_add_rule^J{ ^JPacf::s = fmt(add_rule: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jif (Pacf::do_something(Pacf::p)) ^J^I{ ^J^Ievent Pacf::rule_added(Pacf::r, Pacf::p, );^J^Ireturn (T);^J^I}^J^Jreturn (F);^J}, remove_rule=Pacf::debug_remove_rule^J{ ^JPacf::s = fmt(remove_rule: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jevent Pacf::rule_removed(Pacf::r, Pacf::p, );^Jreturn (T);^J}, add_notification=Pacf::debug_add_notification^J{ ^JPacf::s = fmt(add_notification: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jif (Pacf::do_something(Pacf::p)) ^J^I{ ^J^Ievent Pacf::notification_added(Pacf::r, Pacf::p, );^J^Ireturn (T);^J^I}^J^Jreturn (F);^J}, remove_notification=Pacf::debug_remove_notification^J{ ^JPacf::s = fmt(remove_notification: %s, Pacf::r);^JPacf::debug_log(Pacf::p, Pacf::s);^Jreturn (Pacf::do_something(Pacf::p));^J}, transaction_begin=Pacf::debug_transaction_begin^J{ ^JPacf::debug_log(Pacf::p, transaction_begin);^J}, transaction_end=Pacf::debug_transaction_end^J{ ^JPacf::debug_log(Pacf::p, transaction_end);^J}], of_controller=, of_config=]] +pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, i=, d=, s=, id=3, _plugin=[config={\x0a\x09[all] = 1\x0a}, _priority=0, plugin=[name=Pacf::debug_name\x0a{ \x0areturn (fmt(Debug-%s, (Pacf::do_something(Pacf::p) ? All : None)));\x0a}, can_expire=F, init=Pacf::debug_init\x0a{ \x0aPacf::debug_log(Pacf::p, init);\x0a}, done=Pacf::debug_done\x0a{ \x0aPacf::debug_log(Pacf::p, init);\x0a}, add_rule=Pacf::debug_add_rule\x0a{ \x0aPacf::s = fmt(add_rule: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0aif (Pacf::do_something(Pacf::p)) \x0a\x09{ \x0a\x09event Pacf::rule_added(Pacf::r, Pacf::p, );\x0a\x09return (T);\x0a\x09}\x0a\x0areturn (F);\x0a}, remove_rule=Pacf::debug_remove_rule\x0a{ \x0aPacf::s = fmt(remove_rule: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0aevent Pacf::rule_removed(Pacf::r, Pacf::p, );\x0areturn (T);\x0a}, add_notification=Pacf::debug_add_notification\x0a{ \x0aPacf::s = fmt(add_notification: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0aif (Pacf::do_something(Pacf::p)) \x0a\x09{ \x0a\x09event Pacf::notification_added(Pacf::r, Pacf::p, );\x0a\x09return (T);\x0a\x09}\x0a\x0areturn (F);\x0a}, remove_notification=Pacf::debug_remove_notification\x0a{ \x0aPacf::s = fmt(remove_notification: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0areturn (Pacf::do_something(Pacf::p));\x0a}, transaction_begin=Pacf::debug_transaction_begin\x0a{ \x0aPacf::debug_log(Pacf::p, transaction_begin);\x0a}, transaction_end=Pacf::debug_transaction_end\x0a{ \x0aPacf::debug_log(Pacf::p, transaction_end);\x0a}], of_controller=, of_config=]] +pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, i=, d=, s=, id=2, _plugin=[config={\x0a\x09[all] = 1\x0a}, _priority=0, plugin=[name=Pacf::debug_name\x0a{ \x0areturn (fmt(Debug-%s, (Pacf::do_something(Pacf::p) ? All : None)));\x0a}, can_expire=F, init=Pacf::debug_init\x0a{ \x0aPacf::debug_log(Pacf::p, init);\x0a}, done=Pacf::debug_done\x0a{ \x0aPacf::debug_log(Pacf::p, init);\x0a}, add_rule=Pacf::debug_add_rule\x0a{ \x0aPacf::s = fmt(add_rule: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0aif (Pacf::do_something(Pacf::p)) \x0a\x09{ \x0a\x09event Pacf::rule_added(Pacf::r, Pacf::p, );\x0a\x09return (T);\x0a\x09}\x0a\x0areturn (F);\x0a}, remove_rule=Pacf::debug_remove_rule\x0a{ \x0aPacf::s = fmt(remove_rule: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0aevent Pacf::rule_removed(Pacf::r, Pacf::p, );\x0areturn (T);\x0a}, add_notification=Pacf::debug_add_notification\x0a{ \x0aPacf::s = fmt(add_notification: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0aif (Pacf::do_something(Pacf::p)) \x0a\x09{ \x0a\x09event Pacf::notification_added(Pacf::r, Pacf::p, );\x0a\x09return (T);\x0a\x09}\x0a\x0areturn (F);\x0a}, remove_notification=Pacf::debug_remove_notification\x0a{ \x0aPacf::s = fmt(remove_notification: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0areturn (Pacf::do_something(Pacf::p));\x0a}, transaction_begin=Pacf::debug_transaction_begin\x0a{ \x0aPacf::debug_log(Pacf::p, transaction_begin);\x0a}, transaction_end=Pacf::debug_transaction_end\x0a{ \x0aPacf::debug_log(Pacf::p, transaction_end);\x0a}], of_controller=, of_config=]] diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/pacf.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/pacf.log index 100f5393f2..11ca981be1 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/pacf.log +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/pacf.log @@ -3,16 +3,16 @@ #empty_field (empty) #unset_field - #path pacf -#open 2015-04-13-23-44-49 +#open 2015-05-12-20-36-36 #fields ts category cmd state action target entity_type entity msg location plugin #types time enum string enum string enum string string string string string 0.000000 Pacf::MESSAGE - - - - - - activated plugin with priority 0 - Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/1470->74.53.140.153/25 - (empty) Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All 1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/1470->74.53.140.153/25 - (empty) Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All 1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All 1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/1470->74.53.140.153/25 - (empty) Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All 1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/1470->74.53.140.153/25 - (empty) Debug-All -#close 2015-04-13-23-44-49 +1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +#close 2015-05-12-20-36-36 diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/pacf.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/pacf.log index c0362c23c4..1180186ac3 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/pacf.log +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/pacf.log @@ -3,10 +3,10 @@ #empty_field (empty) #unset_field - #path pacf -#open 2015-04-14-22-20-31 +#open 2015-05-12-20-36-53 #fields ts category cmd state action target entity_type entity msg location plugin #types time enum string enum string enum string string string string string 0.000000 Pacf::MESSAGE - - - - - - activated plugin with priority 0 - Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/1470->74.53.140.153/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -#close 2015-04-14-22-20-31 +#close 2015-05-12-20-36-53 From 73d22a2dbd8d3e8245c31b37b0793cd9f9c69abb Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 12 May 2015 15:11:41 -0700 Subject: [PATCH 31/93] add Pacf plugin for the internal Bro PacketFilter (not BPF) --- .../base/frameworks/pacf/plugins/__load__.bro | 1 + .../frameworks/pacf/plugins/packetfilter.bro | 115 ++++++++++++++++++ .../conn.log | 12 ++ .../base/frameworks/pacf/packetfilter.bro | 18 +++ 4 files changed, 146 insertions(+) create mode 100644 scripts/base/frameworks/pacf/plugins/packetfilter.bro create mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.packetfilter/conn.log create mode 100644 testing/btest/scripts/base/frameworks/pacf/packetfilter.bro diff --git a/scripts/base/frameworks/pacf/plugins/__load__.bro b/scripts/base/frameworks/pacf/plugins/__load__.bro index 8eda6f9b97..f3468e0b83 100644 --- a/scripts/base/frameworks/pacf/plugins/__load__.bro +++ b/scripts/base/frameworks/pacf/plugins/__load__.bro @@ -1,2 +1,3 @@ @load ./debug @load ./openflow +@load ./packetfilter diff --git a/scripts/base/frameworks/pacf/plugins/packetfilter.bro b/scripts/base/frameworks/pacf/plugins/packetfilter.bro new file mode 100644 index 0000000000..dbf6ba1136 --- /dev/null +++ b/scripts/base/frameworks/pacf/plugins/packetfilter.bro @@ -0,0 +1,115 @@ +# PACF plugin for the PacketFilter handling 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 Pacf; + +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 "PACF plugin for the Bro 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 +# $add_notification = packetfilter_add_notification, +# $remove_notification = packetfilter_remove_notification, +# $transaction_begin = packetfilter_transaction_begin, +# $transaction_end = packetfilter_transaction_end + ); + +function create_packetfilter() : PluginState + { + local p: PluginState = [$plugin=packetfilter_plugin]; + + return p; + } + diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.packetfilter/conn.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.packetfilter/conn.log new file mode 100644 index 0000000000..1f51ecc2fd --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.packetfilter/conn.log @@ -0,0 +1,12 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open 2015-05-12-22-11-25 +#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) +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) +1254722776.690444 CCvvfg3TEfuqmmG4bh 10.10.1.20 138 10.10.1.255 138 udp - - - - S0 - - 0 D 1 229 0 0 (empty) +#close 2015-05-12-22-11-25 diff --git a/testing/btest/scripts/base/frameworks/pacf/packetfilter.bro b/testing/btest/scripts/base/frameworks/pacf/packetfilter.bro new file mode 100644 index 0000000000..9076fbbb1f --- /dev/null +++ b/testing/btest/scripts/base/frameworks/pacf/packetfilter.bro @@ -0,0 +1,18 @@ +# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT +# @TEST-EXEC: btest-diff conn.log + +@load base/frameworks/pacf + +event bro_init() + { + local pacf_packetfilter = Pacf::create_packetfilter(); + Pacf::activate(pacf_packetfilter, 0); + } + +event connection_established(c: connection) + { + local e = Pacf::Entity($ty=Pacf::ADDRESS, $ip=addr_to_subnet(c$id$orig_h)); + local r = Pacf::Rule($ty=Pacf::DROP, $target=Pacf::MONITOR, $entity=e, $expire=10min); + + Pacf::add_rule(r); + } From 208d150a0e05e1d337d1b4504ce8142c731a667f Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 13 May 2015 16:23:24 -0700 Subject: [PATCH 32/93] Change openflow plugin for broker and allow specification of topics per instance. --- .../base/frameworks/openflow/plugins/broker.bro | 17 ++++++++++------- .../base/frameworks/openflow/broker-basic.bro | 3 +-- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/scripts/base/frameworks/openflow/plugins/broker.bro b/scripts/base/frameworks/openflow/plugins/broker.bro index 9d0f55ad40..8e550b0642 100644 --- a/scripts/base/frameworks/openflow/plugins/broker.bro +++ b/scripts/base/frameworks/openflow/plugins/broker.bro @@ -1,4 +1,5 @@ @load base/frameworks/openflow +@load base/frameworks/broker module OpenFlow; @@ -13,10 +14,12 @@ export { ## ## 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(host: addr, host_port: port, dpid: count): OpenFlow::Controller; + global broker_new: function(host: addr, host_port: port, topic: string, dpid: count): OpenFlow::Controller; redef record ControllerState += { ## Controller ip. @@ -25,6 +28,8 @@ export { 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(dpid: count, match: ofp_match, flow_mod: ofp_flow_mod); @@ -38,27 +43,25 @@ function broker_describe(state: ControllerState): string function broker_flow_mod_fun(state: ControllerState, match: ofp_match, flow_mod: OpenFlow::ofp_flow_mod): bool { - event OpenFlow::broker_flow_mod(state$broker_dpid, match, flow_mod); + BrokerComm::event(state$broker_topic, BrokerComm::event_args(broker_flow_mod, state$broker_dpid, match, flow_mod)); return T; } function broker_flow_clear_fun(state: OpenFlow::ControllerState): bool { - event OpenFlow::broker_flow_clear(state$broker_dpid); + BrokerComm::event(state$broker_topic, BrokerComm::event_args(broker_flow_clear, state$broker_dpid)); return T; } # broker controller constructor -function broker_new(host: addr, host_port: port, dpid: count): OpenFlow::Controller +function broker_new(host: addr, host_port: port, topic: string, dpid: count): OpenFlow::Controller { BrokerComm::enable(); - BrokerComm::auto_event("bro/event/openflow", broker_flow_mod); - BrokerComm::auto_event("bro/event/openflow", broker_flow_clear); BrokerComm::connect(cat(host), host_port, 1sec); - return [$state=[$broker_host=host, $broker_port=host_port, $broker_dpid=dpid, $_plugin=OpenFlow::BROKER], + return [$state=[$broker_host=host, $broker_port=host_port, $broker_dpid=dpid, $broker_topic=topic, $_plugin=OpenFlow::BROKER], $flow_mod=broker_flow_mod_fun, $flow_clear=broker_flow_clear_fun, $describe=broker_describe]; } diff --git a/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro b/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro index 3874d46f5a..b31e47f2c1 100644 --- a/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro +++ b/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro @@ -20,7 +20,7 @@ global of_controller: OpenFlow::Controller; event bro_init() { suspend_processing(); - of_controller = OpenFlow::broker_new(127.0.0.1, broker_port, 42); + of_controller = OpenFlow::broker_new(127.0.0.1, broker_port, "bro/event/openflow", 42); } event BrokerComm::outgoing_connection_established(peer_address: string, @@ -72,7 +72,6 @@ event bro_init() { BrokerComm::enable(); BrokerComm::subscribe_to_events("bro/event/openflow"); - BrokerComm::subscribe_to_events("bro/event/test_event"); BrokerComm::listen(broker_port, "127.0.0.1"); } From 8c292ddd49affa54e134768e998cfe18df8b93ba Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Thu, 14 May 2015 08:15:43 -0700 Subject: [PATCH 33/93] Allow pacf openflow plugin to speficy a priority offset. --- scripts/base/frameworks/pacf/plugins/openflow.bro | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/base/frameworks/pacf/plugins/openflow.bro b/scripts/base/frameworks/pacf/plugins/openflow.bro index d87b83f7d6..cf9f9f3380 100644 --- a/scripts/base/frameworks/pacf/plugins/openflow.bro +++ b/scripts/base/frameworks/pacf/plugins/openflow.bro @@ -9,6 +9,7 @@ export { forward: bool &default=T; idle_timeout: count &default=60; 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 pacf priorities without having to write a filter function. check_pred: function(p: PluginState, r: Rule): bool &optional &weaken; match_pred: function(p: PluginState, e: Entity, m: vector of OpenFlow::ofp_match): vector of OpenFlow::ofp_match &optional &weaken; @@ -179,7 +180,7 @@ function openflow_rule_to_flow_mod(p: PluginState, r: Rule) : OpenFlow::ofp_flow $cookie=r$id, $command=OpenFlow::OFPFC_ADD, $idle_timeout=c$idle_timeout, - $priority=int_to_count(r$priority) + $priority=int_to_count(r$priority + c$priority_offset) ); if ( r?$expire ) From 6014b395b832b30507947692027bca9433a455b2 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Fri, 15 May 2015 11:22:50 -0700 Subject: [PATCH 34/93] handle the notification events correctly. Now if a rule is inserted correctly (or fails to be inserted) into openflow, we actually get the corresponding Pacf events that everything worked. --- scripts/base/frameworks/openflow/main.bro | 2 +- .../frameworks/openflow/plugins/broker.bro | 1 + .../base/frameworks/openflow/plugins/log.bro | 12 +++- .../base/frameworks/pacf/plugins/openflow.bro | 64 +++++++++++++++++-- .../send.send.out | 6 ++ .../.stdout | 3 + .../openflow.log | 10 +-- .../pacf.log | 6 +- .../base/frameworks/openflow/broker-basic.bro | 11 ++++ .../base/frameworks/openflow/ryu-basic.bro | 5 ++ 10 files changed, 105 insertions(+), 15 deletions(-) diff --git a/scripts/base/frameworks/openflow/main.bro b/scripts/base/frameworks/openflow/main.bro index 043bfdef28..5d6b61a9ec 100644 --- a/scripts/base/frameworks/openflow/main.bro +++ b/scripts/base/frameworks/openflow/main.bro @@ -38,7 +38,7 @@ export { ## ## flow_mod: The openflow flow_mod record which describes the action to take. ## - ## msg: An optional informational message by the plugin.. + ## msg: An optional informational message by the plugin. global flow_mod_success: event(match: ofp_match, flow_mod: ofp_flow_mod, msg: string &default=""); ## Reports an error while installing a flow Rule. diff --git a/scripts/base/frameworks/openflow/plugins/broker.bro b/scripts/base/frameworks/openflow/plugins/broker.bro index 8e550b0642..5af30fdf48 100644 --- a/scripts/base/frameworks/openflow/plugins/broker.bro +++ b/scripts/base/frameworks/openflow/plugins/broker.bro @@ -60,6 +60,7 @@ function broker_new(host: addr, host_port: port, topic: string, dpid: count): Op { BrokerComm::enable(); BrokerComm::connect(cat(host), host_port, 1sec); + BrokerComm::subscribe_to_events(topic); # openflow success and failure events are directly sent back via the other plugin via broker. return [$state=[$broker_host=host, $broker_port=host_port, $broker_dpid=dpid, $broker_topic=topic, $_plugin=OpenFlow::BROKER], $flow_mod=broker_flow_mod_fun, $flow_clear=broker_flow_clear_fun, $describe=broker_describe]; diff --git a/scripts/base/frameworks/openflow/plugins/log.bro b/scripts/base/frameworks/openflow/plugins/log.bro index ddfea6c593..5493bed5c7 100644 --- a/scripts/base/frameworks/openflow/plugins/log.bro +++ b/scripts/base/frameworks/openflow/plugins/log.bro @@ -17,12 +17,16 @@ export { ## ## 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): OpenFlow::Controller; + 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. @@ -50,6 +54,8 @@ event bro_init() &priority=5 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(match, flow_mod); return T; } @@ -59,8 +65,8 @@ function log_describe(state: ControllerState): string return fmt("OpenFlog Log Plugin - DPID %d", state$log_dpid); } -function log_new(dpid: count): OpenFlow::Controller +function log_new(dpid: count, success_event: bool &default=T): OpenFlow::Controller { - return [$state=[$log_dpid=dpid, $_plugin=OpenFlow::LOG], + return [$state=[$log_dpid=dpid, $log_success_event=success_event, $_plugin=OpenFlow::LOG], $flow_mod=log_flow_mod, $flow_clear=ryu_flow_clear, $describe=log_describe]; } diff --git a/scripts/base/frameworks/pacf/plugins/openflow.bro b/scripts/base/frameworks/pacf/plugins/openflow.bro index cf9f9f3380..61a8fd2dfd 100644 --- a/scripts/base/frameworks/pacf/plugins/openflow.bro +++ b/scripts/base/frameworks/pacf/plugins/openflow.bro @@ -23,10 +23,32 @@ export { of_config: OfConfig &optional; }; + type OfTable: record { + p: PluginState; + r: Rule; + }; + + ## the time interval after which an openflow message is considered to be timed out + ## and we delete it from our internal tracking. + const openflow_timeout = 20secs &redef; + ## Instantiates an openflow plugin for the PACF 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_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 Pacf::rule_error(r, p, "Timeout during rule insertion/removal"); + return 0secs; + }; + function openflow_name(p: PluginState) : string { return fmt("Openflow - %s", p$of_controller$describe(p$of_controller$state)); @@ -177,7 +199,7 @@ function openflow_rule_to_flow_mod(p: PluginState, r: Rule) : OpenFlow::ofp_flow local c = p$of_config; local flow_mod = OpenFlow::ofp_flow_mod( - $cookie=r$id, + $cookie=OpenFlow::generate_cookie(r$id), $command=OpenFlow::OFPFC_ADD, $idle_timeout=c$idle_timeout, $priority=int_to_count(r$priority + c$priority_offset) @@ -220,7 +242,9 @@ function openflow_add_rule(p: PluginState, r: Rule) : bool for ( i in matches ) { - if ( ! OpenFlow::flow_mod(p$of_controller, matches[i], flow_mod) ) + if ( OpenFlow::flow_mod(p$of_controller, matches[i], flow_mod) ) + of_messages[r$id, flow_mod$command] = OfTable($p=p, $r=r); + else event rule_error(r, p, "Error while executing OpenFlow::flow_mod"); } @@ -233,15 +257,47 @@ function openflow_remove_rule(p: PluginState, r: Rule) : bool return F; local flow_mod: OpenFlow::ofp_flow_mod = [ - $cookie=r$id, + $cookie=OpenFlow::generate_cookie(r$id), $command=OpenFlow::OFPFC_DELETE ]; - OpenFlow::flow_mod(p$of_controller, [], flow_mod); + if ( OpenFlow::flow_mod(p$of_controller, [], flow_mod) ) + of_messages[r$id, flow_mod$command] = OfTable($p=p, $r=r); + else + event rule_error(r, p, "Error while executing OpenFlow::flow_mod"); return T; } +event OpenFlow::flow_mod_success(match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) &priority=3 + { + local id = OpenFlow::get_cookie_uid(flow_mod$cookie); + 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]; + + if ( flow_mod$command == OpenFlow::OFPFC_ADD ) + event Pacf::rule_added(r, p, msg); + else if ( flow_mod$command == OpenFlow::OFPFC_DELETE || flow_mod$command == OpenFlow::OFPFC_DELETE_STRICT ) + event Pacf::rule_removed(r, p, msg); + } + +event OpenFlow::flow_mod_failure(match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) &priority=3 + { + local id = OpenFlow::get_cookie_uid(flow_mod$cookie); + 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 Pacf::rule_error(r, p, msg); + } + global openflow_plugin = Plugin( $name=openflow_name, $can_expire = T, 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 index b283919533..d81ed49aee 100644 --- 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 @@ -1,2 +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.ryu-basic/.stdout b/testing/btest/Baseline/scripts.base.frameworks.openflow.ryu-basic/.stdout index c5fecac835..efdb61aae8 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.openflow.ryu-basic/.stdout +++ b/testing/btest/Baseline/scripts.base.frameworks.openflow.ryu-basic/.stdout @@ -1,7 +1,10 @@ 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": 25, "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 diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log index c43ddd9f85..c97c95d84a 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log @@ -3,10 +3,10 @@ #empty_field (empty) #unset_field - #path openflow -#open 2015-04-15-19-15-14 +#open 2015-05-15-17-45-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.out_ports #types time count count string string count count count count count subnet subnet port port count count enum count count count count count count vector[count] -1254722767.875996 42 - - - - - 2048 - 6 10.10.1.4/32 74.53.140.153/32 1470 25 2 - OpenFlow::OFPFC_ADD 60 30 0 - - 0 (empty) -1254722767.875996 42 - - - - - 2048 - - 10.10.1.4/32 - - - 3 - OpenFlow::OFPFC_ADD 60 15 0 - - 0 (empty) -1254722767.875996 42 - - - - - 2048 - - - 10.10.1.4/32 - - 3 - OpenFlow::OFPFC_ADD 60 15 0 - - 0 (empty) -#close 2015-04-15-19-15-14 +1254722767.875996 42 - - - - - 2048 - 6 10.10.1.4/32 74.53.140.153/32 1470 25 4398046511106 - OpenFlow::OFPFC_ADD 60 30 0 - - 0 (empty) +1254722767.875996 42 - - - - - 2048 - - 10.10.1.4/32 - - - 4398046511107 - OpenFlow::OFPFC_ADD 60 15 0 - - 0 (empty) +1254722767.875996 42 - - - - - 2048 - - - 10.10.1.4/32 - - 4398046511107 - OpenFlow::OFPFC_ADD 60 15 0 - - 0 (empty) +#close 2015-05-15-17-45-53 diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/pacf.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/pacf.log index 1180186ac3..aa97127528 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/pacf.log +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/pacf.log @@ -3,10 +3,12 @@ #empty_field (empty) #unset_field - #path pacf -#open 2015-05-12-20-36-53 +#open 2015-05-15-18-21-40 #fields ts category cmd state action target entity_type entity msg location plugin #types time enum string enum string enum string string string string string 0.000000 Pacf::MESSAGE - - - - - - activated plugin with priority 0 - Openflow - OpenFlog Log Plugin - DPID 42 1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -#close 2015-05-12-20-36-53 +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +#close 2015-05-15-18-21-40 diff --git a/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro b/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro index b31e47f2c1..ef5cd0e8fe 100644 --- a/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro +++ b/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro @@ -56,6 +56,15 @@ event connection_established(c: connection) OpenFlow::flow_mod(of_controller, match_rev, flow_mod); } +event OpenFlow::flow_mod_success(match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) + { + print "Flow_mod_success"; + } + +event OpenFlow::flow_mod_failure(match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) + { + print "Flow_mod_failure"; + } @TEST-END-FILE @@ -91,6 +100,8 @@ function got_message() event OpenFlow::broker_flow_mod(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, match, flow_mod, "")); + BrokerComm::event("bro/event/openflow", BrokerComm::event_args(OpenFlow::flow_mod_failure, match, flow_mod, "")); got_message(); } diff --git a/testing/btest/scripts/base/frameworks/openflow/ryu-basic.bro b/testing/btest/scripts/base/frameworks/openflow/ryu-basic.bro index 319567fa6a..1924b4aba1 100644 --- a/testing/btest/scripts/base/frameworks/openflow/ryu-basic.bro +++ b/testing/btest/scripts/base/frameworks/openflow/ryu-basic.bro @@ -30,3 +30,8 @@ event connection_established(c: connection) OpenFlow::flow_mod(of_controller, match, flow_mod); OpenFlow::flow_mod(of_controller, match_rev, flow_mod); } + +event OpenFlow::flow_mod_success(match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) + { + print "Flow_mod_success"; + } From c0111bc4d22b4f318e6086797c2019e003054e79 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Fri, 15 May 2015 13:29:24 -0700 Subject: [PATCH 35/93] add flow modification to pacf and openflow. More or less untested, but there should not be any big problems. --- .../base/frameworks/openflow/plugins/ryu.bro | 4 +-- scripts/base/frameworks/openflow/types.bro | 31 +++++++++++++++++-- .../base/frameworks/pacf/plugins/openflow.bro | 28 +++++++++++++++-- scripts/base/frameworks/pacf/types.bro | 15 ++++++++- .../recv.recv.out | 6 ++-- .../openflow.log | 14 ++++----- .../.stdout | 8 ++--- .../openflow.log | 14 ++++----- .../base/frameworks/openflow/broker-basic.bro | 2 +- .../base/frameworks/openflow/log-basic.bro | 2 +- .../base/frameworks/openflow/ryu-basic.bro | 2 +- 11 files changed, 94 insertions(+), 32 deletions(-) diff --git a/scripts/base/frameworks/openflow/plugins/ryu.bro b/scripts/base/frameworks/openflow/plugins/ryu.bro index b4ca157a7f..f92c80ec08 100644 --- a/scripts/base/frameworks/openflow/plugins/ryu.bro +++ b/scripts/base/frameworks/openflow/plugins/ryu.bro @@ -85,8 +85,8 @@ function ryu_flow_mod(state: OpenFlow::ControllerState, match: ofp_match, flow_m # 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$out_ports ) - flow_actions[|flow_actions|] = ryu_flow_action($_type="OUTPUT", $_port=flow_mod$out_ports[i]); + 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( diff --git a/scripts/base/frameworks/openflow/types.bro b/scripts/base/frameworks/openflow/types.bro index 26862f6df3..0071b758ca 100644 --- a/scripts/base/frameworks/openflow/types.bro +++ b/scripts/base/frameworks/openflow/types.bro @@ -51,6 +51,33 @@ export { tp_dst: port &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. @@ -75,8 +102,8 @@ export { out_group: count &optional; ## Bitmap of the OFPFF_* flags flags: count &default=0; - ## Output ports to send data to. - out_ports: vector of count &default=vector(); + ## Actions to take on match + actions: ofp_flow_action &default=ofp_flow_action(); } &log; # Functionality using this is currently not implemented. At all. diff --git a/scripts/base/frameworks/pacf/plugins/openflow.bro b/scripts/base/frameworks/pacf/plugins/openflow.bro index 61a8fd2dfd..b567575683 100644 --- a/scripts/base/frameworks/pacf/plugins/openflow.bro +++ b/scripts/base/frameworks/pacf/plugins/openflow.bro @@ -217,12 +217,34 @@ function openflow_rule_to_flow_mod(p: PluginState, r: Rule) : OpenFlow::ofp_flow 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$out_ports = vector(OpenFlow::OFPP_NORMAL); + 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 i - flow_mod$out_ports = vector(int_to_count(r$i)); + # redirect to port c + flow_mod$actions$out_ports = vector(r$c); } else { diff --git a/scripts/base/frameworks/pacf/types.bro b/scripts/base/frameworks/pacf/types.bro index 4870135624..6166a63dc6 100644 --- a/scripts/base/frameworks/pacf/types.bro +++ b/scripts/base/frameworks/pacf/types.bro @@ -59,7 +59,7 @@ export { ## Begin redirecting all packets matching entity. ## ## .. todo:: - ## Define arguments. + ## c: output port to redirect traffic to. REDIRECT, ## Begin sampling all flows matching entity. @@ -74,6 +74,17 @@ export { 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 riles will be ignored. @@ -85,9 +96,11 @@ export { priority: int &default=+0; ##< Priority if multiple rules match an entity (larger value is higher priority). location: string &optional; ##< Optional string describing where/what installed the rule. + c: count &optional; ##< Argument for rule types requiring an count argument. i: int &optional; ##< Argument for rule types requiring an integer argument. d: double &optional; ##< Argument for rule types requiring a double argument. s: string &optional; ##< Argument for rule types requiring a string argument. + mod: FlowMod &optional; ##< Argument for :bro:id:`MODIFY` rules. id: count &default=0; ##< Internally determined unique ID for this rule. Will be set when added. }; 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 index 4b0317a8c7..3b370d6ac0 100644 --- 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 @@ -1,5 +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=1, table_id=, command=OpenFlow::OFPFC_ADD, idle_timeout=0, hard_timeout=0, priority=0, out_port=, out_group=, flags=0, out_ports=[3, 7]] -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/tcp, tp_dst=25/tcp], [cookie=42, table_id=, command=OpenFlow::OFPFC_ADD, idle_timeout=30, hard_timeout=0, priority=5, out_port=, out_group=, flags=0, out_ports=[]] -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/tcp, tp_dst=25/tcp], [cookie=42, table_id=, command=OpenFlow::OFPFC_ADD, idle_timeout=30, hard_timeout=0, priority=5, out_port=, out_group=, flags=0, out_ports=[]] +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=1, 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/tcp, tp_dst=25/tcp], [cookie=42, 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/tcp, tp_dst=25/tcp], [cookie=42, 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.log-basic/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.openflow.log-basic/openflow.log index 5a41312f18..3cd2ba20ba 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.openflow.log-basic/openflow.log +++ b/testing/btest/Baseline/scripts.base.frameworks.openflow.log-basic/openflow.log @@ -3,10 +3,10 @@ #empty_field (empty) #unset_field - #path openflow -#open 2015-04-20-20-22-44 -#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.out_ports -#types time count count string string count count count count count subnet subnet port port count count enum count count count count count count vector[count] -0.000000 42 - - - - - - - - - - - - 1 - OpenFlow::OFPFC_ADD 0 0 0 - - 0 3,7 -1254722767.875996 42 - - - - - 2048 - 6 10.10.1.4/32 74.53.140.153/32 1470 25 42 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) -1254722767.875996 42 - - - - - 2048 - 6 74.53.140.153/32 10.10.1.4/32 25 25 42 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) -#close 2015-04-20-20-22-44 +#open 2015-05-15-20-20-25 +#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 port port count count enum count count count count count count vector[count] count count bool string string count addr addr count count +0.000000 42 - - - - - - - - - - - - 1 - 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 42 - 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 25 42 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) - - F - - - - - - - +#close 2015-05-15-20-20-25 diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout index 3968f4e091..e01d62243e 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout @@ -1,4 +1,4 @@ -pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, i=, d=, s=, id=2, _plugin=] -pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, i=, d=, s=, id=3, _plugin=] -pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, i=, d=, s=, id=3, _plugin=[config={\x0a\x09[all] = 1\x0a}, _priority=0, plugin=[name=Pacf::debug_name\x0a{ \x0areturn (fmt(Debug-%s, (Pacf::do_something(Pacf::p) ? All : None)));\x0a}, can_expire=F, init=Pacf::debug_init\x0a{ \x0aPacf::debug_log(Pacf::p, init);\x0a}, done=Pacf::debug_done\x0a{ \x0aPacf::debug_log(Pacf::p, init);\x0a}, add_rule=Pacf::debug_add_rule\x0a{ \x0aPacf::s = fmt(add_rule: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0aif (Pacf::do_something(Pacf::p)) \x0a\x09{ \x0a\x09event Pacf::rule_added(Pacf::r, Pacf::p, );\x0a\x09return (T);\x0a\x09}\x0a\x0areturn (F);\x0a}, remove_rule=Pacf::debug_remove_rule\x0a{ \x0aPacf::s = fmt(remove_rule: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0aevent Pacf::rule_removed(Pacf::r, Pacf::p, );\x0areturn (T);\x0a}, add_notification=Pacf::debug_add_notification\x0a{ \x0aPacf::s = fmt(add_notification: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0aif (Pacf::do_something(Pacf::p)) \x0a\x09{ \x0a\x09event Pacf::notification_added(Pacf::r, Pacf::p, );\x0a\x09return (T);\x0a\x09}\x0a\x0areturn (F);\x0a}, remove_notification=Pacf::debug_remove_notification\x0a{ \x0aPacf::s = fmt(remove_notification: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0areturn (Pacf::do_something(Pacf::p));\x0a}, transaction_begin=Pacf::debug_transaction_begin\x0a{ \x0aPacf::debug_log(Pacf::p, transaction_begin);\x0a}, transaction_end=Pacf::debug_transaction_end\x0a{ \x0aPacf::debug_log(Pacf::p, transaction_end);\x0a}], of_controller=, of_config=]] -pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, i=, d=, s=, id=2, _plugin=[config={\x0a\x09[all] = 1\x0a}, _priority=0, plugin=[name=Pacf::debug_name\x0a{ \x0areturn (fmt(Debug-%s, (Pacf::do_something(Pacf::p) ? All : None)));\x0a}, can_expire=F, init=Pacf::debug_init\x0a{ \x0aPacf::debug_log(Pacf::p, init);\x0a}, done=Pacf::debug_done\x0a{ \x0aPacf::debug_log(Pacf::p, init);\x0a}, add_rule=Pacf::debug_add_rule\x0a{ \x0aPacf::s = fmt(add_rule: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0aif (Pacf::do_something(Pacf::p)) \x0a\x09{ \x0a\x09event Pacf::rule_added(Pacf::r, Pacf::p, );\x0a\x09return (T);\x0a\x09}\x0a\x0areturn (F);\x0a}, remove_rule=Pacf::debug_remove_rule\x0a{ \x0aPacf::s = fmt(remove_rule: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0aevent Pacf::rule_removed(Pacf::r, Pacf::p, );\x0areturn (T);\x0a}, add_notification=Pacf::debug_add_notification\x0a{ \x0aPacf::s = fmt(add_notification: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0aif (Pacf::do_something(Pacf::p)) \x0a\x09{ \x0a\x09event Pacf::notification_added(Pacf::r, Pacf::p, );\x0a\x09return (T);\x0a\x09}\x0a\x0areturn (F);\x0a}, remove_notification=Pacf::debug_remove_notification\x0a{ \x0aPacf::s = fmt(remove_notification: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0areturn (Pacf::do_something(Pacf::p));\x0a}, transaction_begin=Pacf::debug_transaction_begin\x0a{ \x0aPacf::debug_log(Pacf::p, transaction_begin);\x0a}, transaction_end=Pacf::debug_transaction_end\x0a{ \x0aPacf::debug_log(Pacf::p, transaction_end);\x0a}], of_controller=, of_config=]] +pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=2, _plugin=] +pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=3, _plugin=] +pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=3, _plugin=[config={\x0a\x09[all] = 1\x0a}, _priority=0, plugin=[name=Pacf::debug_name\x0a{ \x0areturn (fmt(Debug-%s, (Pacf::do_something(Pacf::p) ? All : None)));\x0a}, can_expire=F, init=Pacf::debug_init\x0a{ \x0aPacf::debug_log(Pacf::p, init);\x0a}, done=Pacf::debug_done\x0a{ \x0aPacf::debug_log(Pacf::p, init);\x0a}, add_rule=Pacf::debug_add_rule\x0a{ \x0aPacf::s = fmt(add_rule: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0aif (Pacf::do_something(Pacf::p)) \x0a\x09{ \x0a\x09event Pacf::rule_added(Pacf::r, Pacf::p, );\x0a\x09return (T);\x0a\x09}\x0a\x0areturn (F);\x0a}, remove_rule=Pacf::debug_remove_rule\x0a{ \x0aPacf::s = fmt(remove_rule: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0aevent Pacf::rule_removed(Pacf::r, Pacf::p, );\x0areturn (T);\x0a}, add_notification=Pacf::debug_add_notification\x0a{ \x0aPacf::s = fmt(add_notification: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0aif (Pacf::do_something(Pacf::p)) \x0a\x09{ \x0a\x09event Pacf::notification_added(Pacf::r, Pacf::p, );\x0a\x09return (T);\x0a\x09}\x0a\x0areturn (F);\x0a}, remove_notification=Pacf::debug_remove_notification\x0a{ \x0aPacf::s = fmt(remove_notification: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0areturn (Pacf::do_something(Pacf::p));\x0a}, transaction_begin=Pacf::debug_transaction_begin\x0a{ \x0aPacf::debug_log(Pacf::p, transaction_begin);\x0a}, transaction_end=Pacf::debug_transaction_end\x0a{ \x0aPacf::debug_log(Pacf::p, transaction_end);\x0a}], of_controller=, of_config=]] +pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=2, _plugin=[config={\x0a\x09[all] = 1\x0a}, _priority=0, plugin=[name=Pacf::debug_name\x0a{ \x0areturn (fmt(Debug-%s, (Pacf::do_something(Pacf::p) ? All : None)));\x0a}, can_expire=F, init=Pacf::debug_init\x0a{ \x0aPacf::debug_log(Pacf::p, init);\x0a}, done=Pacf::debug_done\x0a{ \x0aPacf::debug_log(Pacf::p, init);\x0a}, add_rule=Pacf::debug_add_rule\x0a{ \x0aPacf::s = fmt(add_rule: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0aif (Pacf::do_something(Pacf::p)) \x0a\x09{ \x0a\x09event Pacf::rule_added(Pacf::r, Pacf::p, );\x0a\x09return (T);\x0a\x09}\x0a\x0areturn (F);\x0a}, remove_rule=Pacf::debug_remove_rule\x0a{ \x0aPacf::s = fmt(remove_rule: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0aevent Pacf::rule_removed(Pacf::r, Pacf::p, );\x0areturn (T);\x0a}, add_notification=Pacf::debug_add_notification\x0a{ \x0aPacf::s = fmt(add_notification: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0aif (Pacf::do_something(Pacf::p)) \x0a\x09{ \x0a\x09event Pacf::notification_added(Pacf::r, Pacf::p, );\x0a\x09return (T);\x0a\x09}\x0a\x0areturn (F);\x0a}, remove_notification=Pacf::debug_remove_notification\x0a{ \x0aPacf::s = fmt(remove_notification: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0areturn (Pacf::do_something(Pacf::p));\x0a}, transaction_begin=Pacf::debug_transaction_begin\x0a{ \x0aPacf::debug_log(Pacf::p, transaction_begin);\x0a}, transaction_end=Pacf::debug_transaction_end\x0a{ \x0aPacf::debug_log(Pacf::p, transaction_end);\x0a}], of_controller=, of_config=]] diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log index c97c95d84a..2b776d1db0 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log @@ -3,10 +3,10 @@ #empty_field (empty) #unset_field - #path openflow -#open 2015-05-15-17-45-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.out_ports -#types time count count string string count count count count count subnet subnet port port count count enum count count count count count count vector[count] -1254722767.875996 42 - - - - - 2048 - 6 10.10.1.4/32 74.53.140.153/32 1470 25 4398046511106 - OpenFlow::OFPFC_ADD 60 30 0 - - 0 (empty) -1254722767.875996 42 - - - - - 2048 - - 10.10.1.4/32 - - - 4398046511107 - OpenFlow::OFPFC_ADD 60 15 0 - - 0 (empty) -1254722767.875996 42 - - - - - 2048 - - - 10.10.1.4/32 - - 4398046511107 - OpenFlow::OFPFC_ADD 60 15 0 - - 0 (empty) -#close 2015-05-15-17-45-53 +#open 2015-05-15-20-22-55 +#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 port port 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 4398046511106 - OpenFlow::OFPFC_ADD 60 30 0 - - 0 (empty) - - F - - - - - - - +1254722767.875996 42 - - - - - 2048 - - 10.10.1.4/32 - - - 4398046511107 - OpenFlow::OFPFC_ADD 60 15 0 - - 0 (empty) - - F - - - - - - - +1254722767.875996 42 - - - - - 2048 - - - 10.10.1.4/32 - - 4398046511107 - OpenFlow::OFPFC_ADD 60 15 0 - - 0 (empty) - - F - - - - - - - +#close 2015-05-15-20-22-55 diff --git a/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro b/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro index ef5cd0e8fe..c8e5c03667 100644 --- a/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro +++ b/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro @@ -30,7 +30,7 @@ event BrokerComm::outgoing_connection_established(peer_address: string, print "BrokerComm::outgoing_connection_established", peer_address, peer_port; continue_processing(); OpenFlow::flow_clear(of_controller); - OpenFlow::flow_mod(of_controller, [], [$cookie=1, $command=OpenFlow::OFPFC_ADD, $out_ports=vector(3, 7)]); + OpenFlow::flow_mod(of_controller, [], [$cookie=1, $command=OpenFlow::OFPFC_ADD, $actions=[$out_ports=vector(3, 7)]]); } event BrokerComm::outgoing_connection_broken(peer_address: string, diff --git a/testing/btest/scripts/base/frameworks/openflow/log-basic.bro b/testing/btest/scripts/base/frameworks/openflow/log-basic.bro index ea18acb8ce..212a3c2fec 100644 --- a/testing/btest/scripts/base/frameworks/openflow/log-basic.bro +++ b/testing/btest/scripts/base/frameworks/openflow/log-basic.bro @@ -10,7 +10,7 @@ event bro_init() { of_controller = OpenFlow::log_new(42); - OpenFlow::flow_mod(of_controller, [], [$cookie=1, $command=OpenFlow::OFPFC_ADD, $out_ports=vector(3, 7)]); + OpenFlow::flow_mod(of_controller, [], [$cookie=1, $command=OpenFlow::OFPFC_ADD, $actions=[$out_ports=vector(3, 7)]]); } event connection_established(c: connection) diff --git a/testing/btest/scripts/base/frameworks/openflow/ryu-basic.bro b/testing/btest/scripts/base/frameworks/openflow/ryu-basic.bro index 1924b4aba1..3c8eb8f0d8 100644 --- a/testing/btest/scripts/base/frameworks/openflow/ryu-basic.bro +++ b/testing/btest/scripts/base/frameworks/openflow/ryu-basic.bro @@ -12,7 +12,7 @@ event bro_init() of_controller$state$ryu_debug=T; OpenFlow::flow_clear(of_controller); - OpenFlow::flow_mod(of_controller, [], [$cookie=1, $command=OpenFlow::OFPFC_ADD, $out_ports=vector(3, 7)]); + OpenFlow::flow_mod(of_controller, [], [$cookie=1, $command=OpenFlow::OFPFC_ADD, $actions=[$out_ports=vector(3, 7)]]); } event connection_established(c: connection) From 5f0a630116259bb498ac3c1ddc0a915820c4b5a0 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Mon, 18 May 2015 13:38:38 -0700 Subject: [PATCH 36/93] add support for switches notifying openflow and pacf about flow removal. I just noticed - the OpenFlow events also really should send the instance of openflow that they are with them. That is a... tad complicated though due to a number of reasons (among others how the events are currently generated), so this will have to wait for a bit. --- scripts/base/frameworks/openflow/main.bro | 19 ++++++++++++++ .../frameworks/openflow/plugins/broker.bro | 2 +- .../base/frameworks/openflow/plugins/log.bro | 2 +- .../base/frameworks/openflow/plugins/ryu.bro | 2 +- scripts/base/frameworks/openflow/types.bro | 2 ++ scripts/base/frameworks/pacf/main.bro | 8 +++--- .../base/frameworks/pacf/plugins/openflow.bro | 26 +++++++++++++++++-- scripts/base/frameworks/pacf/types.bro | 10 +++++++ 8 files changed, 63 insertions(+), 8 deletions(-) diff --git a/scripts/base/frameworks/openflow/main.bro b/scripts/base/frameworks/openflow/main.bro index 5d6b61a9ec..36992d3fe0 100644 --- a/scripts/base/frameworks/openflow/main.bro +++ b/scripts/base/frameworks/openflow/main.bro @@ -50,6 +50,25 @@ export { ## msg: Message to describe the event. global flow_mod_failure: event(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. + ## + ## 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(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. ## diff --git a/scripts/base/frameworks/openflow/plugins/broker.bro b/scripts/base/frameworks/openflow/plugins/broker.bro index 5af30fdf48..3b721ad5a0 100644 --- a/scripts/base/frameworks/openflow/plugins/broker.bro +++ b/scripts/base/frameworks/openflow/plugins/broker.bro @@ -63,6 +63,6 @@ function broker_new(host: addr, host_port: port, topic: string, dpid: count): Op BrokerComm::subscribe_to_events(topic); # openflow success and failure events are directly sent back via the other plugin via broker. return [$state=[$broker_host=host, $broker_port=host_port, $broker_dpid=dpid, $broker_topic=topic, $_plugin=OpenFlow::BROKER], - $flow_mod=broker_flow_mod_fun, $flow_clear=broker_flow_clear_fun, $describe=broker_describe]; + $flow_mod=broker_flow_mod_fun, $flow_clear=broker_flow_clear_fun, $describe=broker_describe, $supports_flow_removed=T]; } diff --git a/scripts/base/frameworks/openflow/plugins/log.bro b/scripts/base/frameworks/openflow/plugins/log.bro index 5493bed5c7..a7009e474a 100644 --- a/scripts/base/frameworks/openflow/plugins/log.bro +++ b/scripts/base/frameworks/openflow/plugins/log.bro @@ -68,5 +68,5 @@ function log_describe(state: ControllerState): string function log_new(dpid: count, success_event: bool &default=T): OpenFlow::Controller { return [$state=[$log_dpid=dpid, $log_success_event=success_event, $_plugin=OpenFlow::LOG], - $flow_mod=log_flow_mod, $flow_clear=ryu_flow_clear, $describe=log_describe]; + $flow_mod=log_flow_mod, $flow_clear=ryu_flow_clear, $describe=log_describe, $supports_flow_removed=F]; } diff --git a/scripts/base/frameworks/openflow/plugins/ryu.bro b/scripts/base/frameworks/openflow/plugins/ryu.bro index f92c80ec08..490d10ac07 100644 --- a/scripts/base/frameworks/openflow/plugins/ryu.bro +++ b/scripts/base/frameworks/openflow/plugins/ryu.bro @@ -180,5 +180,5 @@ function ryu_describe(state: ControllerState): string function ryu_new(host: addr, host_port: count, dpid: count): OpenFlow::Controller { return [$state=[$ryu_host=host, $ryu_port=host_port, $ryu_dpid=dpid, $_plugin=OpenFlow::RYU], - $flow_mod=ryu_flow_mod, $flow_clear=ryu_flow_clear, $describe=ryu_describe]; + $flow_mod=ryu_flow_mod, $flow_clear=ryu_flow_clear, $describe=ryu_describe, $supports_flow_removed=F]; } diff --git a/scripts/base/frameworks/openflow/types.bro b/scripts/base/frameworks/openflow/types.bro index 0071b758ca..e3bc32ee84 100644 --- a/scripts/base/frameworks/openflow/types.bro +++ b/scripts/base/frameworks/openflow/types.bro @@ -139,6 +139,8 @@ export { 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; ## flow_mod function diff --git a/scripts/base/frameworks/pacf/main.bro b/scripts/base/frameworks/pacf/main.bro index c77edec8ef..ec649b422d 100644 --- a/scripts/base/frameworks/pacf/main.bro +++ b/scripts/base/frameworks/pacf/main.bro @@ -118,11 +118,13 @@ export { ## ## r: The rule now removed. ## + ## i: Additional flow information, if supported by the protocol. + ## ## plugin: The name of 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, p: PluginState); + global rule_timeout: event(r: Rule, i: FlowInfo, p: PluginState); ## Reports an error when operating on a rule. ## @@ -428,7 +430,7 @@ event rule_expire(r: Rule, p: PluginState) # Remove already. return; - event rule_timeout(r, p); + event rule_timeout(r, FlowInfo(), p); remove_rule(r$id); } @@ -448,7 +450,7 @@ event rule_removed(r: Rule, p: PluginState, msg: string &default="") log_rule(r, "REMOVE", SUCCEEDED, p); } -event rule_timeout(r: Rule, p: PluginState) +event rule_timeout(r: Rule, i: FlowInfo, p: PluginState) { delete rules[r$id]; log_rule(r, "EXPIRE", TIMEOUT, p); diff --git a/scripts/base/frameworks/pacf/plugins/openflow.bro b/scripts/base/frameworks/pacf/plugins/openflow.bro index b567575683..5349a1c1e4 100644 --- a/scripts/base/frameworks/pacf/plugins/openflow.bro +++ b/scripts/base/frameworks/pacf/plugins/openflow.bro @@ -30,13 +30,18 @@ export { ## the time interval after which an openflow message is considered to be timed out ## and we delete it from our internal tracking. - const openflow_timeout = 20secs &redef; + 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 PACF 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_timeout +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; @@ -49,6 +54,8 @@ global of_messages: table[count, OpenFlow::ofp_flow_mod_command] of OfTable &cre return 0secs; }; +global of_flows: table[count] of OfTable &create_expire=openflow_flow_timeout; + function openflow_name(p: PluginState) : string { return fmt("Openflow - %s", p$of_controller$describe(p$of_controller$state)); @@ -301,6 +308,9 @@ event OpenFlow::flow_mod_success(match: OpenFlow::ofp_match, flow_mod: OpenFlow: local p = of_messages[id,flow_mod$command]$p; 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 Pacf::rule_added(r, p, msg); else if ( flow_mod$command == OpenFlow::OFPFC_DELETE || flow_mod$command == OpenFlow::OFPFC_DELETE_STRICT ) @@ -320,6 +330,18 @@ event OpenFlow::flow_mod_failure(match: OpenFlow::ofp_match, flow_mod: OpenFlow: event Pacf::rule_error(r, p, msg); } +event OpenFlow::flow_removed(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); + if ( id !in of_flows ) + return; + + local r = of_flows[id]$r; + local p = of_flows[id]$p; + + event Pacf::rule_timeout(r, FlowInfo($duration=double_to_interval(duration_sec+0.0), $packet_count=packet_count, $byte_count=byte_count), p); + } + global openflow_plugin = Plugin( $name=openflow_name, $can_expire = T, diff --git a/scripts/base/frameworks/pacf/types.bro b/scripts/base/frameworks/pacf/types.bro index 6166a63dc6..ac8bb06a35 100644 --- a/scripts/base/frameworks/pacf/types.bro +++ b/scripts/base/frameworks/pacf/types.bro @@ -105,6 +105,16 @@ export { id: count &default=0; ##< Internally determined unique ID for this rule. Will be 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 + }; + ## Type of notifications that the framework supports. Each type lists the ## :bro:id:`Notification` argument(s) it uses, if any. ## From b9953e7048dc25c55045a57e995f4757f15f6f2e Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Fri, 22 May 2015 13:37:57 -0700 Subject: [PATCH 37/93] change type of flow_mod entries to count - the type is defined in other records and this leads to unfortunate problems with external scripts that would have to convert values into bro port types themseves. --- scripts/base/frameworks/openflow/main.bro | 4 ++-- scripts/base/frameworks/openflow/types.bro | 4 ++-- scripts/base/frameworks/pacf/plugins/openflow.bro | 4 ++-- .../recv.recv.out | 4 ++-- .../scripts.base.frameworks.openflow.log-basic/openflow.log | 6 +++--- .../scripts.base.frameworks.pacf.openflow/openflow.log | 6 +++--- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/scripts/base/frameworks/openflow/main.bro b/scripts/base/frameworks/openflow/main.bro index 36992d3fe0..7158cf3812 100644 --- a/scripts/base/frameworks/openflow/main.bro +++ b/scripts/base/frameworks/openflow/main.bro @@ -160,9 +160,9 @@ function match_conn(id: conn_id, reverse: bool &default=F): ofp_match $dl_type=dl_type, $nw_proto=proto, $nw_src=addr_to_subnet(orig_h), - $tp_src=orig_p, + $tp_src=port_to_count(orig_p), $nw_dst=addr_to_subnet(resp_h), - $tp_dst=resp_p + $tp_dst=port_to_count(resp_p) ); } diff --git a/scripts/base/frameworks/openflow/types.bro b/scripts/base/frameworks/openflow/types.bro index e3bc32ee84..e35b675680 100644 --- a/scripts/base/frameworks/openflow/types.bro +++ b/scripts/base/frameworks/openflow/types.bro @@ -46,9 +46,9 @@ export { # IP destination address. nw_dst: subnet &optional; # TCP/UDP source port. - tp_src: port &optional; + tp_src: count &optional; # TCP/UDP destination port. - tp_dst: port &optional; + tp_dst: count &optional; } &log; ## The actions that can be taken in a flow. diff --git a/scripts/base/frameworks/pacf/plugins/openflow.bro b/scripts/base/frameworks/pacf/plugins/openflow.bro index 5349a1c1e4..20d62e06f3 100644 --- a/scripts/base/frameworks/pacf/plugins/openflow.bro +++ b/scripts/base/frameworks/pacf/plugins/openflow.bro @@ -183,13 +183,13 @@ function entity_to_match(p: PluginState, e: Entity): vector of OpenFlow::ofp_mat if ( f?$src_p ) { m$nw_proto = determine_proto(f$src_p); - m$tp_src = 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 = f$dst_p; + m$tp_dst = port_to_count(f$dst_p); } v[|v|] = m; 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 index 3b370d6ac0..08c50b5caa 100644 --- 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 @@ -1,5 +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=1, 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/tcp, tp_dst=25/tcp], [cookie=42, 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/tcp, tp_dst=25/tcp], [cookie=42, 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=10.10.1.4/32, nw_dst=74.53.140.153/32, tp_src=1470, tp_dst=25], [cookie=42, 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=25], [cookie=42, 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.log-basic/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.openflow.log-basic/openflow.log index 3cd2ba20ba..3e65c82baf 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.openflow.log-basic/openflow.log +++ b/testing/btest/Baseline/scripts.base.frameworks.openflow.log-basic/openflow.log @@ -3,10 +3,10 @@ #empty_field (empty) #unset_field - #path openflow -#open 2015-05-15-20-20-25 +#open 2015-05-22-20-37-23 #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 port port count count enum count count count count count count vector[count] count count bool string string count addr addr count count +#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 - - - - - - - - - - - - 1 - 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 42 - 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 25 42 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) - - F - - - - - - - -#close 2015-05-15-20-20-25 +#close 2015-05-22-20-37-23 diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log index 2b776d1db0..00baa60d23 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log @@ -3,10 +3,10 @@ #empty_field (empty) #unset_field - #path openflow -#open 2015-05-15-20-22-55 +#open 2015-05-22-20-37-34 #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 port port count count enum count count count count count count vector[count] count count bool string string count addr addr count count +#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 4398046511106 - OpenFlow::OFPFC_ADD 60 30 0 - - 0 (empty) - - F - - - - - - - 1254722767.875996 42 - - - - - 2048 - - 10.10.1.4/32 - - - 4398046511107 - OpenFlow::OFPFC_ADD 60 15 0 - - 0 (empty) - - F - - - - - - - 1254722767.875996 42 - - - - - 2048 - - - 10.10.1.4/32 - - 4398046511107 - OpenFlow::OFPFC_ADD 60 15 0 - - 0 (empty) - - F - - - - - - - -#close 2015-05-15-20-22-55 +#close 2015-05-22-20-37-34 From 93b79c87bd6447d5d18f7741eea37d00bd513b56 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Fri, 22 May 2015 18:07:57 -0700 Subject: [PATCH 38/93] it makes much more sense for the high level api to still return rule numbers. --- scripts/base/frameworks/pacf/main.bro | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/scripts/base/frameworks/pacf/main.bro b/scripts/base/frameworks/pacf/main.bro index ec649b422d..aa2eb742f5 100644 --- a/scripts/base/frameworks/pacf/main.bro +++ b/scripts/base/frameworks/pacf/main.bro @@ -43,8 +43,8 @@ export { ## ## location: An optional string describing where the drop was triggered. ## - ## Returns: True if a plugin accepted the rule for carrying it out. - global drop_address: function(a: addr, t: interval, location: string &default="") : bool; + ## Returns: The id of the inserted rule on succes and zero on failure. + global drop_address: function(a: addr, t: interval, location: string &default="") : count; ## Stops forwarding a uni-directional flow's packets to Bro. ## @@ -54,8 +54,8 @@ export { ## ## location: An optional string describing where the shunt was triggered. ## - ## Returns: True if a plugin accepted the rule for carrying it out. - global shunt_flow: function(f: flow_id, t: interval, location: string &default="") : bool; + ## 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="") : count; ## Removes all rules and notifications for an entity. ## @@ -355,16 +355,15 @@ function activate(p: PluginState, priority: int) log_msg(fmt("activated plugin with priority %d", priority), p); } -function drop_address(a: addr, t: interval, location: string &default="") : bool +function drop_address(a: addr, t: interval, location: string &default="") : count { 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); - return id > 0; + return add_rule(r); } -function shunt_flow(f: flow_id, t: interval, location: string &default="") : bool +function shunt_flow(f: flow_id, t: interval, location: string &default="") : count { local flow = Pacf::Flow( $src_h=addr_to_subnet(f$src_h), @@ -375,8 +374,7 @@ function shunt_flow(f: flow_id, t: interval, location: string &default="") : boo 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); - return id > 0; + return add_rule(r); } function reset(e: Entity) From 870acea8a9e180de2eba1013a79a810e7a6106b1 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Fri, 22 May 2015 18:59:40 -0700 Subject: [PATCH 39/93] deal with the fact that some pacf rules create two openflow messages and that the return events need to unify them again... More or less untested. --- .../base/frameworks/pacf/plugins/openflow.bro | 52 ++++++++++++++++--- .../openflow.log | 10 ++-- 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/scripts/base/frameworks/pacf/plugins/openflow.bro b/scripts/base/frameworks/pacf/plugins/openflow.bro index 20d62e06f3..73a3b7fac0 100644 --- a/scripts/base/frameworks/pacf/plugins/openflow.bro +++ b/scripts/base/frameworks/pacf/plugins/openflow.bro @@ -26,6 +26,10 @@ export { 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 @@ -206,7 +210,7 @@ function openflow_rule_to_flow_mod(p: PluginState, r: Rule) : OpenFlow::ofp_flow local c = p$of_config; local flow_mod = OpenFlow::ofp_flow_mod( - $cookie=OpenFlow::generate_cookie(r$id), + $cookie=OpenFlow::generate_cookie(r$id*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) @@ -272,7 +276,11 @@ function openflow_add_rule(p: PluginState, r: Rule) : bool for ( i in matches ) { if ( OpenFlow::flow_mod(p$of_controller, matches[i], flow_mod) ) + { of_messages[r$id, 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"); } @@ -293,19 +301,39 @@ function openflow_remove_rule(p: PluginState, r: Rule) : bool if ( OpenFlow::flow_mod(p$of_controller, [], flow_mod) ) of_messages[r$id, 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(match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) &priority=3 { - local id = OpenFlow::get_cookie_uid(flow_mod$cookie); + 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 ) @@ -319,7 +347,7 @@ event OpenFlow::flow_mod_success(match: OpenFlow::ofp_match, flow_mod: OpenFlow: event OpenFlow::flow_mod_failure(match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) &priority=3 { - local id = OpenFlow::get_cookie_uid(flow_mod$cookie); + local id = OpenFlow::get_cookie_uid(flow_mod$cookie)/2; if ( [id, flow_mod$command] !in of_messages ) return; @@ -332,12 +360,24 @@ event OpenFlow::flow_mod_failure(match: OpenFlow::ofp_match, flow_mod: OpenFlow: event OpenFlow::flow_removed(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); + local id = OpenFlow::get_cookie_uid(cookie)/2; if ( id !in of_flows ) return; - local r = of_flows[id]$r; - local p = of_flows[id]$p; + 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 Pacf::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 Pacf::rule_timeout(r, FlowInfo($duration=double_to_interval(duration_sec+0.0), $packet_count=packet_count, $byte_count=byte_count), p); } diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log index 00baa60d23..fc81807f6d 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log @@ -3,10 +3,10 @@ #empty_field (empty) #unset_field - #path openflow -#open 2015-05-22-20-37-34 +#open 2015-05-23-01-58-18 #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 4398046511106 - OpenFlow::OFPFC_ADD 60 30 0 - - 0 (empty) - - F - - - - - - - -1254722767.875996 42 - - - - - 2048 - - 10.10.1.4/32 - - - 4398046511107 - OpenFlow::OFPFC_ADD 60 15 0 - - 0 (empty) - - F - - - - - - - -1254722767.875996 42 - - - - - 2048 - - - 10.10.1.4/32 - - 4398046511107 - OpenFlow::OFPFC_ADD 60 15 0 - - 0 (empty) - - F - - - - - - - -#close 2015-05-22-20-37-34 +1254722767.875996 42 - - - - - 2048 - 6 10.10.1.4/32 74.53.140.153/32 1470 25 4398046511108 - OpenFlow::OFPFC_ADD 60 30 0 - - 0 (empty) - - F - - - - - - - +1254722767.875996 42 - - - - - 2048 - - 10.10.1.4/32 - - - 4398046511110 - OpenFlow::OFPFC_ADD 60 15 0 - - 0 (empty) - - F - - - - - - - +1254722767.875996 42 - - - - - 2048 - - - 10.10.1.4/32 - - 4398046511111 - OpenFlow::OFPFC_ADD 60 15 0 - - 0 (empty) - - F - - - - - - - +#close 2015-05-23-01-58-18 From 30e305cf4bcf0f4317fe534f11471a65fe224b40 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Fri, 22 May 2015 19:19:11 -0700 Subject: [PATCH 40/93] we also really want to get notifications upon flow removal --- scripts/base/frameworks/pacf/plugins/openflow.bro | 3 ++- .../scripts.base.frameworks.pacf.openflow/openflow.log | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/scripts/base/frameworks/pacf/plugins/openflow.bro b/scripts/base/frameworks/pacf/plugins/openflow.bro index 73a3b7fac0..d0acb398db 100644 --- a/scripts/base/frameworks/pacf/plugins/openflow.bro +++ b/scripts/base/frameworks/pacf/plugins/openflow.bro @@ -213,7 +213,8 @@ function openflow_rule_to_flow_mod(p: PluginState, r: Rule) : OpenFlow::ofp_flow $cookie=OpenFlow::generate_cookie(r$id*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) + $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 ) diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log index fc81807f6d..345dded742 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log @@ -3,10 +3,10 @@ #empty_field (empty) #unset_field - #path openflow -#open 2015-05-23-01-58-18 +#open 2015-05-23-02-19-04 #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 60 30 0 - - 0 (empty) - - F - - - - - - - -1254722767.875996 42 - - - - - 2048 - - 10.10.1.4/32 - - - 4398046511110 - OpenFlow::OFPFC_ADD 60 15 0 - - 0 (empty) - - F - - - - - - - -1254722767.875996 42 - - - - - 2048 - - - 10.10.1.4/32 - - 4398046511111 - OpenFlow::OFPFC_ADD 60 15 0 - - 0 (empty) - - F - - - - - - - -#close 2015-05-23-01-58-18 +1254722767.875996 42 - - - - - 2048 - 6 10.10.1.4/32 74.53.140.153/32 1470 25 4398046511108 - OpenFlow::OFPFC_ADD 60 30 0 - - 1 (empty) - - F - - - - - - - +1254722767.875996 42 - - - - - 2048 - - 10.10.1.4/32 - - - 4398046511110 - OpenFlow::OFPFC_ADD 60 15 0 - - 1 (empty) - - F - - - - - - - +1254722767.875996 42 - - - - - 2048 - - - 10.10.1.4/32 - - 4398046511111 - OpenFlow::OFPFC_ADD 60 15 0 - - 1 (empty) - - F - - - - - - - +#close 2015-05-23-02-19-04 From 94fbd492ca796869f042b1142aaff8c75d72fbea Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Sat, 23 May 2015 12:17:56 -0700 Subject: [PATCH 41/93] update a few consts to openflow 1.3 - we downconvert them to the less common 1.0 in the controller when necessary. --- scripts/base/frameworks/openflow/consts.bro | 24 +++++++++++---------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/scripts/base/frameworks/openflow/consts.bro b/scripts/base/frameworks/openflow/consts.bro index c2e890ea48..83cedb4de5 100644 --- a/scripts/base/frameworks/openflow/consts.bro +++ b/scripts/base/frameworks/openflow/consts.bro @@ -123,29 +123,27 @@ export { ## from the bro openflow framework const INVALID_COOKIE = 0xffffffffffffffff; # Openflow pysical port definitions - ## Maximum number of physical switch ports. - const OFPP_MAX = 0xff00; ## 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 = 0xfff8; + 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 = 0xfff9; + const OFPP_TABLE = 0xfffffff9; ## Process with normal L2/L3 switching. - const OFPP_NORMAL = 0xfffa; + const OFPP_NORMAL = 0xfffffffa; ## All pysical ports except input port and ## those disabled by STP. - const OFPP_FLOOD = 0xfffb; + const OFPP_FLOOD = 0xfffffffb; ## All pysical ports except input port. - const OFPP_ALL = 0xfffc; + const OFPP_ALL = 0xfffffffc; ## Send to controller. - const OFPP_CONTROLLER = 0xfffd; + const OFPP_CONTROLLER = 0xfffffffd; ## Local openflow "port". - const OFPP_LOCAL = 0xfffe; - ## Not associated with a pysical port. - const OFPP_NONE = 0xffff; + 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 @@ -158,6 +156,10 @@ export { ## 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 From 0a49b8cdf6f29b8d6becba058d7e0038de34ca36 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 26 May 2015 11:19:55 -0700 Subject: [PATCH 42/93] add pacf plugin that directly outputs messages to broker. Also fix a few problems in pacf in the process of doing this. --- scripts/base/frameworks/pacf/main.bro | 26 +++- scripts/base/frameworks/pacf/plugin.bro | 3 + .../base/frameworks/pacf/plugins/__load__.bro | 1 + .../base/frameworks/pacf/plugins/broker.bro | 142 ++++++++++++++++++ .../frameworks/pacf/plugins/packetfilter.bro | 2 + scripts/base/frameworks/pacf/types.bro | 6 +- .../.stdout | 8 +- .../recv.recv.out | 5 + .../send.send.out | 7 + .../scripts/base/frameworks/pacf/broker.bro | 102 +++++++++++++ 10 files changed, 288 insertions(+), 14 deletions(-) create mode 100644 scripts/base/frameworks/pacf/plugins/broker.bro create mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.broker/recv.recv.out create mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.broker/send.send.out create mode 100644 testing/btest/scripts/base/frameworks/pacf/broker.bro diff --git a/scripts/base/frameworks/pacf/main.bro b/scripts/base/frameworks/pacf/main.bro index aa2eb742f5..abc50fe428 100644 --- a/scripts/base/frameworks/pacf/main.bro +++ b/scripts/base/frameworks/pacf/main.bro @@ -250,11 +250,13 @@ export { redef record Rule += { ##< Internally set to the plugin handling the rule. - _plugin: PluginState &optional; + _plugin_id: count &optional; }; global plugins: vector of PluginState; +global plugin_ids: table[count] of PluginState; global rule_counter: count = 1; +global plugin_counter: count = 1; global rules: table[count] of Rule; event bro_init() &priority=5 @@ -352,6 +354,10 @@ function activate(p: PluginState, priority: int) 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; + log_msg(fmt("activated plugin with priority %d", priority), p); } @@ -395,9 +401,11 @@ function add_rule(r: Rule) : count { local p = plugins[i]; + # set before, in case the plugins sends and regenerates the plugin record later. + r$_plugin_id = p$_id; + if ( p$plugin$add_rule(p, r) ) { - r$_plugin = p; log_rule(r, "ADD", REQUESTED, p); return r$id; } @@ -409,10 +417,16 @@ function add_rule(r: Rule) : count function remove_rule(id: count) : bool { - local r = rules[id]; - local p = r$_plugin; + if ( id !in rules ) + { + Reporter::error(fmt("Rule %d does not exist in Pacf::remove_rule", id)); + return F; + } - if ( ! p$plugin$remove_rule(r$_plugin, r) ) + local r = rules[id]; + local p = plugin_ids[r$_plugin_id]; + + if ( ! p$plugin$remove_rule(p, r) ) { log_rule_error(r, "remove failed", p); return F; @@ -425,7 +439,7 @@ function remove_rule(id: count) : bool event rule_expire(r: Rule, p: PluginState) { if ( r$id !in rules ) - # Remove already. + # Removed already. return; event rule_timeout(r, FlowInfo(), p); diff --git a/scripts/base/frameworks/pacf/plugin.bro b/scripts/base/frameworks/pacf/plugin.bro index 6c33462a99..cc1b1f0ee6 100644 --- a/scripts/base/frameworks/pacf/plugin.bro +++ b/scripts/base/frameworks/pacf/plugin.bro @@ -9,6 +9,9 @@ export { ## 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; }; diff --git a/scripts/base/frameworks/pacf/plugins/__load__.bro b/scripts/base/frameworks/pacf/plugins/__load__.bro index f3468e0b83..11e8723478 100644 --- a/scripts/base/frameworks/pacf/plugins/__load__.bro +++ b/scripts/base/frameworks/pacf/plugins/__load__.bro @@ -1,3 +1,4 @@ @load ./debug @load ./openflow @load ./packetfilter +@load ./broker diff --git a/scripts/base/frameworks/pacf/plugins/broker.bro b/scripts/base/frameworks/pacf/plugins/broker.bro new file mode 100644 index 0000000000..386d1d2373 --- /dev/null +++ b/scripts/base/frameworks/pacf/plugins/broker.bro @@ -0,0 +1,142 @@ +# Broker plugin for the pacf framework. Sends the raw data structures +# used in pacf on to Broker to allow for easy handling, e.g., of +# command-line scripts. + +module Pacf; + +@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 pacf_broker_topics: set[string] = set(); +global pacf_broker_id: table[count] of PluginState = table(); +global pacf_broker_current_id: count = 0; + +event Pacf::broker_rule_added(id: count, r: Rule, msg: string) + { + if ( id !in pacf_broker_id ) + { + Reporter::error(fmt("Pacf broker plugin with id %d not found, aborting", id)); + return; + } + + local p = pacf_broker_id[id]; + + event Pacf::rule_added(r, p, msg); + } + +event Pacf::broker_rule_removed(id: count, r: Rule, msg: string) + { + if ( id !in pacf_broker_id ) + { + Reporter::error(fmt("Pacf broker plugin with id %d not found, aborting", id)); + return; + } + + local p = pacf_broker_id[id]; + + event Pacf::rule_removed(r, p, msg); + } + +event Pacf::broker_rule_error(id: count, r: Rule, msg: string) + { + if ( id !in pacf_broker_id ) + { + Reporter::error(fmt("Pacf broker plugin with id %d not found, aborting", id)); + return; + } + + local p = pacf_broker_id[id]; + + event Pacf::rule_error(r, p, msg); + } + +event Pacf::broker_rule_timeout(id: count, r: Rule, i: FlowInfo) + { + if ( id !in pacf_broker_id ) + { + Reporter::error(fmt("Pacf broker plugin with id %d not found, aborting", id)); + return; + } + + local p = pacf_broker_id[id]; + + event Pacf::rule_timeout(r, i, p); + } + +function broker_name(p: PluginState) : string + { + return fmt("PACF Broker plugin - topic %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; + } + +global broker_plugin = Plugin( + $name=broker_name, + $can_expire = F, + $add_rule = broker_add_rule_fun, + $remove_rule = broker_remove_rule_fun + ); + +global broker_plugin_can_expire = Plugin( + $name=broker_name, + $can_expire = T, + $add_rule = broker_add_rule_fun, + $remove_rule = broker_remove_rule_fun + ); + +function create_broker(host: addr, host_port: port, topic: string, can_expire: bool &default=F) : PluginState + { + if ( topic in pacf_broker_topics ) + Reporter::warning(fmt("Topic %s was added to Pacf broker plugin twice. Possible duplication of commands", topic)); + else + add pacf_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=pacf_broker_current_id]; + + pacf_broker_id[pacf_broker_current_id] = p; + ++pacf_broker_current_id; + + BrokerComm::enable(); + BrokerComm::connect(cat(host), host_port, 1sec); + BrokerComm::subscribe_to_events(topic); + + return p; + } diff --git a/scripts/base/frameworks/pacf/plugins/packetfilter.bro b/scripts/base/frameworks/pacf/plugins/packetfilter.bro index dbf6ba1136..116151eeb4 100644 --- a/scripts/base/frameworks/pacf/plugins/packetfilter.bro +++ b/scripts/base/frameworks/pacf/plugins/packetfilter.bro @@ -5,6 +5,8 @@ module Pacf; +@load ../plugin + export { ## Instantiates the packetfilter plugin. global create_packetfilter: function() : PluginState; diff --git a/scripts/base/frameworks/pacf/types.bro b/scripts/base/frameworks/pacf/types.bro index ac8bb06a35..723ac788c5 100644 --- a/scripts/base/frameworks/pacf/types.bro +++ b/scripts/base/frameworks/pacf/types.bro @@ -87,7 +87,7 @@ export { ## 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 riles will be ignored. + ## further rules will be ignored. type Rule: record { ty: RuleType; ##< Type of rule. target: TargetType; ##< Where to apply rule. @@ -146,8 +146,6 @@ export { id: count &default=0; ##< Internally determined unique ID for this notification. Will be set when added. }; + } - - - diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout index e01d62243e..da1794833d 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout @@ -1,4 +1,4 @@ -pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=2, _plugin=] -pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=3, _plugin=] -pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=3, _plugin=[config={\x0a\x09[all] = 1\x0a}, _priority=0, plugin=[name=Pacf::debug_name\x0a{ \x0areturn (fmt(Debug-%s, (Pacf::do_something(Pacf::p) ? All : None)));\x0a}, can_expire=F, init=Pacf::debug_init\x0a{ \x0aPacf::debug_log(Pacf::p, init);\x0a}, done=Pacf::debug_done\x0a{ \x0aPacf::debug_log(Pacf::p, init);\x0a}, add_rule=Pacf::debug_add_rule\x0a{ \x0aPacf::s = fmt(add_rule: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0aif (Pacf::do_something(Pacf::p)) \x0a\x09{ \x0a\x09event Pacf::rule_added(Pacf::r, Pacf::p, );\x0a\x09return (T);\x0a\x09}\x0a\x0areturn (F);\x0a}, remove_rule=Pacf::debug_remove_rule\x0a{ \x0aPacf::s = fmt(remove_rule: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0aevent Pacf::rule_removed(Pacf::r, Pacf::p, );\x0areturn (T);\x0a}, add_notification=Pacf::debug_add_notification\x0a{ \x0aPacf::s = fmt(add_notification: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0aif (Pacf::do_something(Pacf::p)) \x0a\x09{ \x0a\x09event Pacf::notification_added(Pacf::r, Pacf::p, );\x0a\x09return (T);\x0a\x09}\x0a\x0areturn (F);\x0a}, remove_notification=Pacf::debug_remove_notification\x0a{ \x0aPacf::s = fmt(remove_notification: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0areturn (Pacf::do_something(Pacf::p));\x0a}, transaction_begin=Pacf::debug_transaction_begin\x0a{ \x0aPacf::debug_log(Pacf::p, transaction_begin);\x0a}, transaction_end=Pacf::debug_transaction_end\x0a{ \x0aPacf::debug_log(Pacf::p, transaction_end);\x0a}], of_controller=, of_config=]] -pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=2, _plugin=[config={\x0a\x09[all] = 1\x0a}, _priority=0, plugin=[name=Pacf::debug_name\x0a{ \x0areturn (fmt(Debug-%s, (Pacf::do_something(Pacf::p) ? All : None)));\x0a}, can_expire=F, init=Pacf::debug_init\x0a{ \x0aPacf::debug_log(Pacf::p, init);\x0a}, done=Pacf::debug_done\x0a{ \x0aPacf::debug_log(Pacf::p, init);\x0a}, add_rule=Pacf::debug_add_rule\x0a{ \x0aPacf::s = fmt(add_rule: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0aif (Pacf::do_something(Pacf::p)) \x0a\x09{ \x0a\x09event Pacf::rule_added(Pacf::r, Pacf::p, );\x0a\x09return (T);\x0a\x09}\x0a\x0areturn (F);\x0a}, remove_rule=Pacf::debug_remove_rule\x0a{ \x0aPacf::s = fmt(remove_rule: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0aevent Pacf::rule_removed(Pacf::r, Pacf::p, );\x0areturn (T);\x0a}, add_notification=Pacf::debug_add_notification\x0a{ \x0aPacf::s = fmt(add_notification: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0aif (Pacf::do_something(Pacf::p)) \x0a\x09{ \x0a\x09event Pacf::notification_added(Pacf::r, Pacf::p, );\x0a\x09return (T);\x0a\x09}\x0a\x0areturn (F);\x0a}, remove_notification=Pacf::debug_remove_notification\x0a{ \x0aPacf::s = fmt(remove_notification: %s, Pacf::r);\x0aPacf::debug_log(Pacf::p, Pacf::s);\x0areturn (Pacf::do_something(Pacf::p));\x0a}, transaction_begin=Pacf::debug_transaction_begin\x0a{ \x0aPacf::debug_log(Pacf::p, transaction_begin);\x0a}, transaction_end=Pacf::debug_transaction_end\x0a{ \x0aPacf::debug_log(Pacf::p, transaction_end);\x0a}], of_controller=, of_config=]] +pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=2, _plugin_id=] +pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=3, _plugin_id=] +pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=3, _plugin_id=1] +pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=2, _plugin_id=1] diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/recv.recv.out b/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/recv.recv.out new file mode 100644 index 0000000000..922b649a98 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/recv.recv.out @@ -0,0 +1,5 @@ +BrokerComm::incoming_connection_established +add_rule, 0, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, _plugin_id=1] +add_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, _plugin_id=1] +remove_rule, 0, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, _plugin_id=1] +remove_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, _plugin_id=1] diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/send.send.out b/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/send.send.out new file mode 100644 index 0000000000..dab0129d5d --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/send.send.out @@ -0,0 +1,7 @@ +BrokerComm::outgoing_connection_established, 127.0.0.1, 9999/tcp +rule added, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, _plugin_id=1] +rule added, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, _plugin_id=1] +ruke timeout, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, _plugin_id=1], [duration=, packet_count=, byte_count=] +rule removed, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, _plugin_id=1] +ruke timeout, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, _plugin_id=1], [duration=, packet_count=, byte_count=] +rule removed, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, _plugin_id=1] diff --git a/testing/btest/scripts/base/frameworks/pacf/broker.bro b/testing/btest/scripts/base/frameworks/pacf/broker.bro new file mode 100644 index 0000000000..a3a59e5acb --- /dev/null +++ b/testing/btest/scripts/base/frameworks/pacf/broker.bro @@ -0,0 +1,102 @@ +# @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/frameworks/pacf + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +event bro_init() + { + suspend_processing(); + local pacf_broker = Pacf::create_broker(127.0.0.1, broker_port, "bro/event/pacftest", T); + Pacf::activate(pacf_broker, 0); + } + +event BrokerComm::outgoing_connection_established(peer_address: string, + peer_port: port, + peer_name: string) + { + print "BrokerComm::outgoing_connection_established", peer_address, peer_port; + continue_processing(); + } + +event BrokerComm::outgoing_connection_broken(peer_address: string, + peer_port: port) + { + terminate(); + } + +event connection_established(c: connection) + { + local id = c$id; + Pacf::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 10hrs); + Pacf::drop_address(id$orig_h, 10hrs); + } + +event Pacf::rule_added(r: Pacf::Rule, p: Pacf::PluginState, msg: string) + { + print "rule added", r; + Pacf::remove_rule(r$id); + } + +event Pacf::rule_removed(r: Pacf::Rule, p: Pacf::PluginState, msg: string) + { + print "rule removed", r; + } + +event Pacf::rule_timeout(r: Pacf::Rule, i: Pacf::FlowInfo, p: Pacf::PluginState) + { + print "ruke timeout", r, i; + } + +@TEST-END-FILE + +@TEST-START-FILE recv.bro + +@load base/frameworks/pacf +@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/pacftest"); + BrokerComm::listen(broker_port, "127.0.0.1"); + } + +event BrokerComm::incoming_connection_established(peer_name: string) + { + print "BrokerComm::incoming_connection_established"; + } + +event Pacf::broker_add_rule(id: count, r: Pacf::Rule) + { + print "add_rule", id, r; + + BrokerComm::event("bro/event/pacftest", BrokerComm::event_args(Pacf::broker_rule_added, id, r, "")); + } + +event Pacf::broker_remove_rule(id: count, r: Pacf::Rule) + { + print "remove_rule", id, r; + + BrokerComm::event("bro/event/pacftest", BrokerComm::event_args(Pacf::broker_rule_timeout, id, r, Pacf::FlowInfo())); + BrokerComm::event("bro/event/pacftest", BrokerComm::event_args(Pacf::broker_rule_removed, id, r, "")); + + if ( r$id == 3 ) + terminate(); + } + +@TEST-END-FILE + From f2be226a5ad2a6fa5e3d245a63947cac1f987254 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 26 May 2015 13:55:16 -0700 Subject: [PATCH 43/93] make openflow framework work in clusters. --- scripts/base/frameworks/openflow/__load__.bro | 9 ++ scripts/base/frameworks/openflow/cluster.bro | 94 +++++++++++++++++++ scripts/base/frameworks/openflow/main.bro | 30 +++--- .../base/frameworks/openflow/non-cluster.bro | 29 ++++++ .../frameworks/openflow/plugins/broker.bro | 23 +++-- .../base/frameworks/openflow/plugins/log.bro | 8 +- .../base/frameworks/openflow/plugins/ryu.bro | 8 +- scripts/base/frameworks/openflow/types.bro | 8 +- scripts/base/frameworks/pacf/plugin.bro | 2 +- .../manager-1.openflow.log | 11 +++ .../base/frameworks/openflow/broker-basic.bro | 2 +- .../base/frameworks/openflow/log-cluster.bro | 54 +++++++++++ 12 files changed, 243 insertions(+), 35 deletions(-) create mode 100644 scripts/base/frameworks/openflow/cluster.bro create mode 100644 scripts/base/frameworks/openflow/non-cluster.bro create mode 100644 testing/btest/Baseline/scripts.base.frameworks.openflow.log-cluster/manager-1.openflow.log create mode 100644 testing/btest/scripts/base/frameworks/openflow/log-cluster.bro diff --git a/scripts/base/frameworks/openflow/__load__.bro b/scripts/base/frameworks/openflow/__load__.bro index 64d6840c4d..bd9128b5aa 100644 --- a/scripts/base/frameworks/openflow/__load__.bro +++ b/scripts/base/frameworks/openflow/__load__.bro @@ -2,3 +2,12 @@ @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..6f08e6839a --- /dev/null +++ b/scripts/base/frameworks/openflow/cluster.bro @@ -0,0 +1,94 @@ +@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)/; + +global name_to_controller: table[string] of Controller; + +# 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?$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?$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; + + if ( controller$state$_name in name_to_controller ) + { + Reporter::error("OpenFlow Controller %s was already registered. Ignored duplicate registration"); + return; + } + + name_to_controller[controller$state$_name] = controller; + + if ( controller?$init ) + controller$init(controller$state); + } diff --git a/scripts/base/frameworks/openflow/main.bro b/scripts/base/frameworks/openflow/main.bro index 7158cf3812..139d932e0d 100644 --- a/scripts/base/frameworks/openflow/main.bro +++ b/scripts/base/frameworks/openflow/main.bro @@ -80,7 +80,7 @@ export { global match_conn: function(id: conn_id, reverse: bool &default=F): ofp_match; # ### - # ### Low-level functions for cookie handling. + # ### Low-level functions for cookie handling and plugin registration. # ### ## Function to get the unique id out of a given cookie. @@ -103,26 +103,18 @@ export { ## ## 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); } - -# the flow_mod function wrapper -function flow_mod(controller: Controller, match: ofp_match, flow_mod: ofp_flow_mod): bool - { - if ( controller?$flow_mod ) - return controller$flow_mod(controller$state, match, flow_mod); - else - return F; - } - -function flow_clear(controller: Controller): bool - { - if ( controller?$flow_clear ) - return controller$flow_clear(controller$state); - else - return F; - } - function match_conn(id: conn_id, reverse: bool &default=F): ofp_match { local dl_type = ETH_IPv4; diff --git a/scripts/base/frameworks/openflow/non-cluster.bro b/scripts/base/frameworks/openflow/non-cluster.bro new file mode 100644 index 0000000000..efadbe56b6 --- /dev/null +++ b/scripts/base/frameworks/openflow/non-cluster.bro @@ -0,0 +1,29 @@ +@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?$flow_mod ) + return controller$flow_mod(controller$state, match, flow_mod); + else + return F; + } + +function flow_clear(controller: Controller): bool + { + 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; + + if ( controller?$init ) + controller$init(controller$state); + } diff --git a/scripts/base/frameworks/openflow/plugins/broker.bro b/scripts/base/frameworks/openflow/plugins/broker.bro index 3b721ad5a0..55505fd3eb 100644 --- a/scripts/base/frameworks/openflow/plugins/broker.bro +++ b/scripts/base/frameworks/openflow/plugins/broker.bro @@ -19,7 +19,7 @@ export { ## dpid: OpenFlow switch datapath id. ## ## Returns: OpenFlow::Controller record - global broker_new: function(host: addr, host_port: port, topic: string, dpid: count): OpenFlow::Controller; + global broker_new: function(name: string, host: addr, host_port: port, topic: string, dpid: count): OpenFlow::Controller; redef record ControllerState += { ## Controller ip. @@ -55,14 +55,21 @@ function broker_flow_clear_fun(state: OpenFlow::ControllerState): bool return T; } -# broker controller constructor -function broker_new(host: addr, host_port: port, topic: string, dpid: count): OpenFlow::Controller +function broker_init(state: OpenFlow::ControllerState) { BrokerComm::enable(); - BrokerComm::connect(cat(host), host_port, 1sec); - BrokerComm::subscribe_to_events(topic); # openflow success and failure events are directly sent back via the other plugin via broker. - - return [$state=[$broker_host=host, $broker_port=host_port, $broker_dpid=dpid, $broker_topic=topic, $_plugin=OpenFlow::BROKER], - $flow_mod=broker_flow_mod_fun, $flow_clear=broker_flow_clear_fun, $describe=broker_describe, $supports_flow_removed=T]; + 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. + } + +# 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); + + return c; } diff --git a/scripts/base/frameworks/openflow/plugins/log.bro b/scripts/base/frameworks/openflow/plugins/log.bro index a7009e474a..3780dfd3c0 100644 --- a/scripts/base/frameworks/openflow/plugins/log.bro +++ b/scripts/base/frameworks/openflow/plugins/log.bro @@ -67,6 +67,10 @@ function log_describe(state: ControllerState): string function log_new(dpid: count, success_event: bool &default=T): OpenFlow::Controller { - return [$state=[$log_dpid=dpid, $log_success_event=success_event, $_plugin=OpenFlow::LOG], - $flow_mod=log_flow_mod, $flow_clear=ryu_flow_clear, $describe=log_describe, $supports_flow_removed=F]; + local c = OpenFlow::Controller($state=OpenFlow::ControllerState($log_dpid=dpid, $log_success_event=success_event), + $flow_mod=log_flow_mod, $flow_clear=ryu_flow_clear, $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 index 490d10ac07..8d2d59e5e5 100644 --- a/scripts/base/frameworks/openflow/plugins/ryu.bro +++ b/scripts/base/frameworks/openflow/plugins/ryu.bro @@ -179,6 +179,10 @@ function ryu_describe(state: ControllerState): string # Ryu controller constructor function ryu_new(host: addr, host_port: count, dpid: count): OpenFlow::Controller { - return [$state=[$ryu_host=host, $ryu_port=host_port, $ryu_dpid=dpid, $_plugin=OpenFlow::RYU], - $flow_mod=ryu_flow_mod, $flow_clear=ryu_flow_clear, $describe=ryu_describe, $supports_flow_removed=F]; + 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 index e35b675680..9faed67f9c 100644 --- a/scripts/base/frameworks/openflow/types.bro +++ b/scripts/base/frameworks/openflow/types.bro @@ -13,8 +13,10 @@ export { ## Can be redefined by plugins to ## add state. type ControllerState: record { - ## Internally set to the plugin used. - _plugin: Plugin; + ## Internally set to the type of plugin used. + _plugin: Plugin &optional; + ## Internally set to the unique name of the controller. + _name: string &optional; } &redef; ## Openflow match definition. @@ -143,6 +145,8 @@ export { supports_flow_removed: bool; ## function that describes the controller. Has to be implemented. describe: function(state: ControllerState): string; + ## one-time initialization function. + init: 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 diff --git a/scripts/base/frameworks/pacf/plugin.bro b/scripts/base/frameworks/pacf/plugin.bro index cc1b1f0ee6..3e89ebd25d 100644 --- a/scripts/base/frameworks/pacf/plugin.bro +++ b/scripts/base/frameworks/pacf/plugin.bro @@ -39,7 +39,7 @@ export { ## framework will manage rule expiration. can_expire: bool; - # One-time initialization functionl called when plugin gets registered, and + # One-time initialization function called when plugin gets registered, and # before any other methods are called. init: function(state: PluginState) &optional; 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..9d5f2f39c8 --- /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 2015-05-26-20-51-55 +#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 +1432673515.912626 42 - - - - - 2048 - 6 10.10.1.4/32 74.53.140.153/32 1470 25 42 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) - - F - - - - - - - +1432673515.912626 42 - - - - - 2048 - 6 74.53.140.153/32 10.10.1.4/32 25 25 42 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) - - F - - - - - - - +#close 2015-05-26-20-52-05 diff --git a/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro b/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro index c8e5c03667..6f75f82081 100644 --- a/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro +++ b/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro @@ -20,7 +20,7 @@ global of_controller: OpenFlow::Controller; event bro_init() { suspend_processing(); - of_controller = OpenFlow::broker_new(127.0.0.1, broker_port, "bro/event/openflow", 42); + of_controller = OpenFlow::broker_new("broker1", 127.0.0.1, broker_port, "bro/event/openflow", 42); } event BrokerComm::outgoing_connection_established(peer_address: string, 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..f015e20875 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/openflow/log-cluster.bro @@ -0,0 +1,54 @@ +# @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); + #OpenFlow::flow_mod(of_controller, [], [$cookie=1, $command=OpenFlow::OFPFC_ADD, $actions=[$out_ports=vector(3, 7)]]); + } + +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=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 terminate_me() { + terminate(); +} + +event remote_connection_closed(p: event_peer) { + schedule 1sec { terminate_me() }; +} + From ad2361b7ac13a8935b7c2491a6cf324b7c8bae48 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 27 May 2015 07:37:25 -0700 Subject: [PATCH 44/93] remove (disfunctional) notifications from pacf --- scripts/base/frameworks/pacf/main.bro | 95 +------------------ scripts/base/frameworks/pacf/plugin.bro | 18 +--- .../base/frameworks/pacf/plugins/debug.bro | 24 ----- .../base/frameworks/pacf/plugins/openflow.bro | 2 - .../frameworks/pacf/plugins/packetfilter.bro | 4 - scripts/base/frameworks/pacf/types.bro | 32 ------- .../.stdout | 4 +- .../base/frameworks/openflow/log-cluster.bro | 1 - 8 files changed, 7 insertions(+), 173 deletions(-) diff --git a/scripts/base/frameworks/pacf/main.bro b/scripts/base/frameworks/pacf/main.bro index abc50fe428..362a9a1ca8 100644 --- a/scripts/base/frameworks/pacf/main.bro +++ b/scripts/base/frameworks/pacf/main.bro @@ -57,10 +57,10 @@ export { ## 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="") : count; - ## Removes all rules and notifications for an entity. + ## Removes all rules for an entity. ## ## e: The entity. Note that this will be directly to entities of existing - ## notifications and notifications, which must match exactly field by field. + ## rules, which must match exactly field by field. global reset: function(e: Entity); ## Flushes all state. @@ -135,67 +135,6 @@ export { ## msg: An optional informational message by the plugin. global rule_error: event(r: Rule, p: PluginState, msg: string &default=""); - ## Installs a notification. - ## - ## n: The notification to install. - ## - ## Returns: If succesful, returns an ID string unique to the notification 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 notification", 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_notification: function(n: Notification) : string; - - ## Removes a notification. - ## - ## id: The notification to remove, specified as the ID returned by :bro:id:`add_notification` . - ## - ## Returns: True if succesful, the relevant plugin indicated that ity 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_notification: function(id: count) : bool; - - ###### Asynchronous feedback on notifications. - - ## Confirms that a notification was put in place. - ## - ## n: The notification now in place. - ## - ## plugin: The name of the plugin that put it into place. - ## - ## msg: An optional informational message by the plugin. - global notification_added: event(n: Notification, p: PluginState, msg: string &default=""); - - ## Reports that a notification was removed due to a remove: function() call. - ## - ## n: The notification now removed. - ## - ## plugin: The name of the plugin that had the notification in place and now - ## removed it. - ## - ## msg: An optional informational message by the plugin. - global notification_removed: event(n: Notification, p: PluginState, msg: string &default=""); - - ## Reports that a notification was removed internally due to a timeout. - ## - ## n: The notification now removed. - ## - ## plugin: The name of the plugin that had the notification in place and now - ## removed it. - ## - ## msg: An optional informational message by the plugin. - global notification_timeout: event(n: Notification, p: PluginState); - - ## Reports an error when operating on a notification. - ## - ## n: The notification that encountered an error. - ## - ## plugin: The name of the plugin that reported the error. - ## - ## msg: An optional informational message by the plugin. - global notification_error: event(n: Notification, p: PluginState, msg: string &default=""); - ## Type of an entry in the PACF log. type InfoCategory: enum { ## A log entry reflecting a framework message. @@ -203,9 +142,7 @@ export { ## A log entry reflecting a framework message. ERROR, ## A log entry about about a rule. - RULE, - ## A log entry about about a notification. - NOTIFICATION + RULE }; ## State of an entry in the PACF log. @@ -472,29 +409,3 @@ event rule_error(r: Rule, p: PluginState, msg: string &default="") { log_rule_error(r, msg, p); } - -function add_notification(n: Notification) : string - { - print "Pacf::add_notification not implemented yet"; - } - -function remove_notification(id: count) : bool - { - print "Pacf::remove_notification not implemented yet"; - } - -event notification_added(n: Notification, p: PluginState, msg: string &default="") - { - } - -event notification_removed(n: Notification, p: PluginState, msg: string &default="") - { - } - -event notification_timeout(n: Notification, p: PluginState) - { - } - -event notification_error(n: Notification, p: PluginState, msg: string &default="") - { - } diff --git a/scripts/base/frameworks/pacf/plugin.bro b/scripts/base/frameworks/pacf/plugin.bro index 3e89ebd25d..501befed76 100644 --- a/scripts/base/frameworks/pacf/plugin.bro +++ b/scripts/base/frameworks/pacf/plugin.bro @@ -28,14 +28,13 @@ export { # 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. The same applies to notifications, - # with the corresponding ``notification_*`` events. + # 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/notifications itself. If false, + ## If true, plugin can expire rules itself. If false, ## framework will manage rule expiration. can_expire: bool; @@ -60,19 +59,6 @@ export { # remove_rule(). remove_rule: function(state: PluginState, r: Rule) : bool &optional; - # Implements the add_notification() operation. If the plugin accepts the notification, - # it returns true, false otherwise. The notification will already have its - # ``id`` field set, which the plugin may use for identification - # purposes. - add_notification: function(state: PluginState, r: Notification) : bool &optional; - - # Implements the remove_notification() operation. This will only be called for - # notifications that the plugins has previously accepted with add_notification(). - # The ``id`` field will match that of the add_notification() call. Generally, - # a plugin that accepts an add_notification() should also accept the - # remove_notification(). - remove_notification: function(state: PluginState, r: Notification) : 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. diff --git a/scripts/base/frameworks/pacf/plugins/debug.bro b/scripts/base/frameworks/pacf/plugins/debug.bro index 09fb87ef3f..f032a22a37 100644 --- a/scripts/base/frameworks/pacf/plugins/debug.bro +++ b/scripts/base/frameworks/pacf/plugins/debug.bro @@ -60,28 +60,6 @@ function debug_remove_rule(p: PluginState, r: Rule) : bool return T; } -function debug_add_notification(p: PluginState, r: Notification) : bool - { - local s = fmt("add_notification: %s", r); - debug_log(p, s); - - if ( do_something(p) ) - { - event Pacf::notification_added(r, p); - return T; - } - - return F; - } - -function debug_remove_notification(p: PluginState, r: Notification) : bool - { - local s = fmt("remove_notification: %s", r); - debug_log(p, s); - - return do_something(p); - } - function debug_transaction_begin(p: PluginState) { debug_log(p, "transaction_begin"); @@ -99,8 +77,6 @@ global debug_plugin = Plugin( $done = debug_done, $add_rule = debug_add_rule, $remove_rule = debug_remove_rule, - $add_notification = debug_add_notification, - $remove_notification = debug_remove_notification, $transaction_begin = debug_transaction_begin, $transaction_end = debug_transaction_end ); diff --git a/scripts/base/frameworks/pacf/plugins/openflow.bro b/scripts/base/frameworks/pacf/plugins/openflow.bro index d0acb398db..ba77af7922 100644 --- a/scripts/base/frameworks/pacf/plugins/openflow.bro +++ b/scripts/base/frameworks/pacf/plugins/openflow.bro @@ -390,8 +390,6 @@ global openflow_plugin = Plugin( # $done = openflow_done, $add_rule = openflow_add_rule, $remove_rule = openflow_remove_rule -# $add_notification = openflow_add_notification, -# $remove_notification = openflow_remove_notification, # $transaction_begin = openflow_transaction_begin, # $transaction_end = openflow_transaction_end ); diff --git a/scripts/base/frameworks/pacf/plugins/packetfilter.bro b/scripts/base/frameworks/pacf/plugins/packetfilter.bro index 116151eeb4..d2f2841790 100644 --- a/scripts/base/frameworks/pacf/plugins/packetfilter.bro +++ b/scripts/base/frameworks/pacf/plugins/packetfilter.bro @@ -102,10 +102,6 @@ global packetfilter_plugin = Plugin( # $done = packetfilter_done, $add_rule = packetfilter_add_rule, $remove_rule = packetfilter_remove_rule -# $add_notification = packetfilter_add_notification, -# $remove_notification = packetfilter_remove_notification, -# $transaction_begin = packetfilter_transaction_begin, -# $transaction_end = packetfilter_transaction_end ); function create_packetfilter() : PluginState diff --git a/scripts/base/frameworks/pacf/types.bro b/scripts/base/frameworks/pacf/types.bro index 723ac788c5..b76ab06d3c 100644 --- a/scripts/base/frameworks/pacf/types.bro +++ b/scripts/base/frameworks/pacf/types.bro @@ -115,37 +115,5 @@ export { byte_count: count &optional; ##< total bytes exchanged over connections matched by the rule }; - ## Type of notifications that the framework supports. Each type lists the - ## :bro:id:`Notification` argument(s) it uses, if any. - ## - ## Plugins may extend this type to define their own. - type NotificationType: enum { - ## Notify if threshold of packets has been reached by entity. - ## - ## i: Number of packets. - NUM_PACKETS, - - ## Notify if threshold of bytes has been reached by entity. - ## - ## i: Number of bytes. - NUM_BYTES, - }; - - ## A notification for the framework to raise when a condition has been reached. - ## Different than with rules, all matching conditions will be reported, not only - ## the first match. - type Notification: record { - ty: NotificationType; ##< Type of notification. - entity: Entity; ##< Entity to apply notification to. - expire: interval &optional; ##< Timeout after which to expire the notification. - src: string &optional; ##< Optional string describing where/what installed the notification. - - i: int; ##< Argument for notification types requiring an integer argument. - d: double; ##< Argument for notification types requiring a double argument. - s: string; ##< Argument for notification types requiring a string argument. - - id: count &default=0; ##< Internally determined unique ID for this notification. Will be set when added. - }; - } diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout index da1794833d..f9a3a61220 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout @@ -1,4 +1,4 @@ -pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=2, _plugin_id=] -pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=3, _plugin_id=] +pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=2, _plugin_id=1] +pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=3, _plugin_id=1] pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=3, _plugin_id=1] pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=2, _plugin_id=1] diff --git a/testing/btest/scripts/base/frameworks/openflow/log-cluster.bro b/testing/btest/scripts/base/frameworks/openflow/log-cluster.bro index f015e20875..0859e18571 100644 --- a/testing/btest/scripts/base/frameworks/openflow/log-cluster.bro +++ b/testing/btest/scripts/base/frameworks/openflow/log-cluster.bro @@ -24,7 +24,6 @@ global of_controller: OpenFlow::Controller; event bro_init() { of_controller = OpenFlow::log_new(42); - #OpenFlow::flow_mod(of_controller, [], [$cookie=1, $command=OpenFlow::OFPFC_ADD, $actions=[$out_ports=vector(3, 7)]]); } event connection_established(c: connection) From 99dcb40c67810f11ea0c057fcd421b647f4e918a Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 27 May 2015 18:00:56 -0700 Subject: [PATCH 45/93] Clusterize pacf This changes the type of user-exposed IDs from counts to strings. Also makes the init functions work for the first time. --- scripts/base/frameworks/pacf/__load__.bro | 9 +++ scripts/base/frameworks/pacf/cluster.bro | 66 +++++++++++++++++++ scripts/base/frameworks/pacf/main.bro | 59 ++++++++++------- scripts/base/frameworks/pacf/non-cluster.bro | 18 +++++ .../base/frameworks/pacf/plugins/broker.bro | 17 +++-- .../base/frameworks/pacf/plugins/openflow.bro | 8 +-- scripts/base/frameworks/pacf/types.bro | 3 +- .../manager-1.pacf.log | 32 +++++++++ .../worker-1..stdout | 4 ++ .../worker-2..stdout | 2 + .../.stdout | 9 +-- .../pacf.log | 8 +-- .../recv.recv.out | 8 +-- .../send.send.out | 12 ++-- .../base/frameworks/pacf/basic-cluster.bro | 50 ++++++++++++++ .../scripts/base/frameworks/pacf/broker.bro | 4 +- 16 files changed, 253 insertions(+), 56 deletions(-) create mode 100644 scripts/base/frameworks/pacf/cluster.bro create mode 100644 scripts/base/frameworks/pacf/non-cluster.bro create mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.basic-cluster/manager-1.pacf.log create mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.basic-cluster/worker-1..stdout create mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.basic-cluster/worker-2..stdout create mode 100644 testing/btest/scripts/base/frameworks/pacf/basic-cluster.bro diff --git a/scripts/base/frameworks/pacf/__load__.bro b/scripts/base/frameworks/pacf/__load__.bro index e2c97f6959..033c30f9a0 100644 --- a/scripts/base/frameworks/pacf/__load__.bro +++ b/scripts/base/frameworks/pacf/__load__.bro @@ -1,3 +1,12 @@ @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/pacf/cluster.bro b/scripts/base/frameworks/pacf/cluster.bro new file mode 100644 index 0000000000..aea6e832e8 --- /dev/null +++ b/scripts/base/frameworks/pacf/cluster.bro @@ -0,0 +1,66 @@ +@load ./main +@load base/frameworks/cluster + +module Pacf; + +export { + ## This is the event used to transport add_rule calls to the manager. + global cluster_pacf_add_rule: event(r: Rule); + + ## This is the event used to transport remove_rule calls to the manager. + global cluster_pacf_remove_rule: event(id: string); +} + +## Workers need ability to forward commands to manager. +redef Cluster::worker2manager_events += /Pacf::cluster_pacf_(add|remove)_rule/; +## Workers need to see the result events from the manager. +redef Cluster::manager2worker_events += /Pacf::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 Pacf::cluster_pacf_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 Pacf::cluster_pacf_remove_rule(id); + return T; # well, we can't know here. So - just hope... + } + } + +@if ( Cluster::local_node_type() == Cluster::MANAGER ) +event Pacf::cluster_pacf_add_rule(r: Rule) + { + add_rule_impl(r); + } + +event Pacf::cluster_pacf_remove_rule(id: string) + { + remove_rule_impl(id); + } +@endif diff --git a/scripts/base/frameworks/pacf/main.bro b/scripts/base/frameworks/pacf/main.bro index 362a9a1ca8..2fa04c6b24 100644 --- a/scripts/base/frameworks/pacf/main.bro +++ b/scripts/base/frameworks/pacf/main.bro @@ -44,7 +44,7 @@ export { ## 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="") : count; + global drop_address: function(a: addr, t: interval, location: string &default="") : string; ## Stops forwarding a uni-directional flow's packets to Bro. ## @@ -55,7 +55,7 @@ export { ## 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="") : count; + global shunt_flow: function(f: flow_id, t: interval, location: string &default="") : string; ## Removes all rules for an entity. ## @@ -81,7 +81,7 @@ export { ## 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) : count; + global add_rule: function(r: Rule) : string; ## Removes a rule. ## @@ -91,7 +91,7 @@ export { ## 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: count) : bool; + global remove_rule: function(id: string) : bool; ###### Asynchronous feedback on rules. @@ -194,7 +194,7 @@ global plugins: vector of PluginState; global plugin_ids: table[count] of PluginState; global rule_counter: count = 1; global plugin_counter: count = 1; -global rules: table[count] of Rule; +global rules: table[string] of Rule; event bro_init() &priority=5 { @@ -285,20 +285,7 @@ function log_rule_no_plugin(r: Rule, state: InfoState, msg: string) Log::write(LOG, info); } -function activate(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; - - log_msg(fmt("activated plugin with priority %d", priority), p); - } - -function drop_address(a: addr, t: interval, location: string &default="") : count +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]; @@ -306,7 +293,7 @@ function drop_address(a: addr, t: interval, location: string &default="") : coun return add_rule(r); } -function shunt_flow(f: flow_id, t: interval, location: string &default="") : count +function shunt_flow(f: flow_id, t: interval, location: string &default="") : string { local flow = Pacf::Flow( $src_h=addr_to_subnet(f$src_h), @@ -330,9 +317,31 @@ function clear() print "Pacf::clear not implemented yet"; } -function add_rule(r: Rule) : count +# Low-level functions that only runs on the manager (or standalone) Bro node. + +function activate_impl(p: PluginState, priority: int) { - r$id = ++rule_counter; + 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-timi initialization + if ( p$plugin?$init ) + p$plugin$init(p); + + log_msg(fmt("activated plugin with priority %d", priority), p); + } + +function add_rule_impl(r: Rule) : string + { + r$cid = ++rule_counter; # numeric id that can be used by plugins for their rules. + + if ( ! r?$id ) + r$id = cat(r$cid); for ( i in plugins ) { @@ -349,14 +358,14 @@ function add_rule(r: Rule) : count } log_rule_no_plugin(r, FAILED, "not supported"); - return 0; + return ""; } -function remove_rule(id: count) : bool +function remove_rule_impl(id: string) : bool { if ( id !in rules ) { - Reporter::error(fmt("Rule %d does not exist in Pacf::remove_rule", id)); + Reporter::error(fmt("Rule %s does not exist in Pacf::remove_rule", id)); return F; } diff --git a/scripts/base/frameworks/pacf/non-cluster.bro b/scripts/base/frameworks/pacf/non-cluster.bro new file mode 100644 index 0000000000..aa642ca20f --- /dev/null +++ b/scripts/base/frameworks/pacf/non-cluster.bro @@ -0,0 +1,18 @@ +module Pacf; + +@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); + } diff --git a/scripts/base/frameworks/pacf/plugins/broker.bro b/scripts/base/frameworks/pacf/plugins/broker.bro index 386d1d2373..0f47641018 100644 --- a/scripts/base/frameworks/pacf/plugins/broker.bro +++ b/scripts/base/frameworks/pacf/plugins/broker.bro @@ -104,18 +104,27 @@ function broker_remove_rule_fun(p: PluginState, r: Rule) : bool 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); + } + global broker_plugin = Plugin( $name=broker_name, $can_expire = F, $add_rule = broker_add_rule_fun, - $remove_rule = broker_remove_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 + $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 @@ -134,9 +143,5 @@ function create_broker(host: addr, host_port: port, topic: string, can_expire: b pacf_broker_id[pacf_broker_current_id] = p; ++pacf_broker_current_id; - BrokerComm::enable(); - BrokerComm::connect(cat(host), host_port, 1sec); - BrokerComm::subscribe_to_events(topic); - return p; } diff --git a/scripts/base/frameworks/pacf/plugins/openflow.bro b/scripts/base/frameworks/pacf/plugins/openflow.bro index ba77af7922..1bfd001c00 100644 --- a/scripts/base/frameworks/pacf/plugins/openflow.bro +++ b/scripts/base/frameworks/pacf/plugins/openflow.bro @@ -210,7 +210,7 @@ function openflow_rule_to_flow_mod(p: PluginState, r: Rule) : OpenFlow::ofp_flow local c = p$of_config; local flow_mod = OpenFlow::ofp_flow_mod( - $cookie=OpenFlow::generate_cookie(r$id*2), # leave one space for the cases in which we need two rules. + $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), @@ -278,7 +278,7 @@ function openflow_add_rule(p: PluginState, r: Rule) : bool { if ( OpenFlow::flow_mod(p$of_controller, matches[i], flow_mod) ) { - of_messages[r$id, flow_mod$command] = OfTable($p=p, $r=r); + of_messages[r$cid, flow_mod$command] = OfTable($p=p, $r=r); flow_mod = copy(flow_mod); ++flow_mod$cookie; } @@ -295,12 +295,12 @@ function openflow_remove_rule(p: PluginState, r: Rule) : bool return F; local flow_mod: OpenFlow::ofp_flow_mod = [ - $cookie=OpenFlow::generate_cookie(r$id), + $cookie=OpenFlow::generate_cookie(r$cid), $command=OpenFlow::OFPFC_DELETE ]; if ( OpenFlow::flow_mod(p$of_controller, [], flow_mod) ) - of_messages[r$id, flow_mod$command] = OfTable($p=p, $r=r); + of_messages[r$cid, flow_mod$command] = OfTable($p=p, $r=r); else { event rule_error(r, p, "Error while executing OpenFlow::flow_mod"); diff --git a/scripts/base/frameworks/pacf/types.bro b/scripts/base/frameworks/pacf/types.bro index b76ab06d3c..9b186b5af2 100644 --- a/scripts/base/frameworks/pacf/types.bro +++ b/scripts/base/frameworks/pacf/types.bro @@ -102,7 +102,8 @@ export { s: string &optional; ##< Argument for rule types requiring a string argument. mod: FlowMod &optional; ##< Argument for :bro:id:`MODIFY` rules. - id: count &default=0; ##< Internally determined unique ID for this rule. Will be set when added. + 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. diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic-cluster/manager-1.pacf.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic-cluster/manager-1.pacf.log new file mode 100644 index 0000000000..81fecc2fd3 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic-cluster/manager-1.pacf.log @@ -0,0 +1,32 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path pacf +#open 2015-05-28-00-59-14 +#fields ts category cmd state action target entity_type entity msg location plugin +#types time enum string enum string enum string string string string string +1432774754.087659 Pacf::MESSAGE - - - - - - activated plugin with priority 0 - Debug-All +1432774756.519062 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1432774756.519062 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1432774756.519062 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1432774756.519062 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1432774758.581184 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1432774758.581184 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1432774758.581184 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1432774758.581184 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1432774756.036263 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1432774756.036263 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1432774757.774649 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1432774757.774649 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1432774758.070948 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1432774758.070948 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1432774766.388890 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1432774766.388890 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1432774766.388890 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1432774766.388890 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1432774766.388890 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1432774766.388890 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1432774766.388890 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1432774766.388890 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +#close 2015-05-28-00-59-26 diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic-cluster/worker-1..stdout b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic-cluster/worker-1..stdout new file mode 100644 index 0000000000..52871d66f0 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic-cluster/worker-1..stdout @@ -0,0 +1,4 @@ +Rule added, worker-1:2, 2 +Rule added, worker-1:3, 3 +Rule added, worker-2:2, 4 +Rule added, worker-2:3, 5 diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic-cluster/worker-2..stdout b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic-cluster/worker-2..stdout new file mode 100644 index 0000000000..938eac9557 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic-cluster/worker-2..stdout @@ -0,0 +1,2 @@ +Rule added, worker-2:2, 4 +Rule added, worker-2:3, 5 diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout index f9a3a61220..d107b8c09c 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout @@ -1,4 +1,5 @@ -pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=2, _plugin_id=1] -pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=3, _plugin_id=1] -pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=3, _plugin_id=1] -pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=2, _plugin_id=1] +pacf debug (Debug-All): init +pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=2, _plugin_id=1] +pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=3, _plugin_id=1] +pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=3, _plugin_id=1] +pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=3, _plugin_id=1] diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/pacf.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/pacf.log index 11ca981be1..7544264219 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/pacf.log +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/pacf.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path pacf -#open 2015-05-12-20-36-36 +#open 2015-05-28-00-27-54 #fields ts category cmd state action target entity_type entity msg location plugin #types time enum string enum string enum string string string string string 0.000000 Pacf::MESSAGE - - - - - - activated plugin with priority 0 - Debug-All @@ -12,7 +12,7 @@ 1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All 1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All 1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All 1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -#close 2015-05-12-20-36-36 +1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +#close 2015-05-28-00-27-54 diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/recv.recv.out b/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/recv.recv.out index 922b649a98..927e9e101a 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/recv.recv.out +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/recv.recv.out @@ -1,5 +1,5 @@ BrokerComm::incoming_connection_established -add_rule, 0, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, _plugin_id=1] -add_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, _plugin_id=1] -remove_rule, 0, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, _plugin_id=1] -remove_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, _plugin_id=1] +add_rule, 0, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=2, _plugin_id=1] +add_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=3, _plugin_id=1] +remove_rule, 0, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=2, _plugin_id=1] +remove_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=3, _plugin_id=1] diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/send.send.out b/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/send.send.out index dab0129d5d..9b4e35e2be 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/send.send.out +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/send.send.out @@ -1,7 +1,7 @@ BrokerComm::outgoing_connection_established, 127.0.0.1, 9999/tcp -rule added, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, _plugin_id=1] -rule added, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, _plugin_id=1] -ruke timeout, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, _plugin_id=1], [duration=, packet_count=, byte_count=] -rule removed, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, _plugin_id=1] -ruke timeout, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, _plugin_id=1], [duration=, packet_count=, byte_count=] -rule removed, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, _plugin_id=1] +rule added, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=2, _plugin_id=1] +rule added, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=3, _plugin_id=1] +rule timeout, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=2, _plugin_id=1], [duration=, packet_count=, byte_count=] +rule removed, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=2, _plugin_id=1] +rule timeout, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=3, _plugin_id=1], [duration=, packet_count=, byte_count=] +rule removed, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=3, _plugin_id=1] diff --git a/testing/btest/scripts/base/frameworks/pacf/basic-cluster.bro b/testing/btest/scripts/base/frameworks/pacf/basic-cluster.bro new file mode 100644 index 0000000000..73be268394 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/pacf/basic-cluster.bro @@ -0,0 +1,50 @@ +# @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: sleep 1 +# @TEST-EXEC: btest-bg-run worker-2 "cp ../cluster-layout.bro . && CLUSTER_NODE=worker-2 bro --pseudo-realtime -C -r $TRACES/smtp.trace %INPUT" +# @TEST-EXEC: btest-bg-wait 20 +# @TEST-EXEC: btest-diff manager-1/pacf.log +# @TEST-EXEC: btest-diff worker-1/.stdout +# @TEST-EXEC: btest-diff worker-2/.stdout + +@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/pacf + +event bro_init() + { + local pacf_debug = Pacf::create_debug(T); + Pacf::activate(pacf_debug, 0); + } + +event connection_established(c: connection) + { + local id = c$id; + Pacf::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 30sec); + Pacf::drop_address(id$orig_h, 15sec); + } + +event terminate_me() { + terminate(); +} + +event remote_connection_closed(p: event_peer) { + schedule 1sec { terminate_me() }; +} + +event Pacf::rule_added(r: Pacf::Rule, p: Pacf::PluginState, msg: string &default="") + { + print "Rule added", r$id, r$cid; + } diff --git a/testing/btest/scripts/base/frameworks/pacf/broker.bro b/testing/btest/scripts/base/frameworks/pacf/broker.bro index a3a59e5acb..9e5caa8864 100644 --- a/testing/btest/scripts/base/frameworks/pacf/broker.bro +++ b/testing/btest/scripts/base/frameworks/pacf/broker.bro @@ -55,7 +55,7 @@ event Pacf::rule_removed(r: Pacf::Rule, p: Pacf::PluginState, msg: string) event Pacf::rule_timeout(r: Pacf::Rule, i: Pacf::FlowInfo, p: Pacf::PluginState) { - print "ruke timeout", r, i; + print "rule timeout", r, i; } @TEST-END-FILE @@ -94,7 +94,7 @@ event Pacf::broker_remove_rule(id: count, r: Pacf::Rule) BrokerComm::event("bro/event/pacftest", BrokerComm::event_args(Pacf::broker_rule_timeout, id, r, Pacf::FlowInfo())); BrokerComm::event("bro/event/pacftest", BrokerComm::event_args(Pacf::broker_rule_removed, id, r, "")); - if ( r$id == 3 ) + if ( r$cid == 3 ) terminate(); } From 3bd513785fe68d032b0a7799d30d460171fefc69 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Thu, 28 May 2015 16:58:55 -0700 Subject: [PATCH 46/93] make rule id generation in non-cluster mode work again --- scripts/base/frameworks/pacf/main.bro | 2 +- .../scripts.base.frameworks.pacf.basic/.stdout | 8 ++++---- .../scripts.base.frameworks.pacf.basic/pacf.log | 8 ++++---- .../recv.recv.out | 8 ++++---- .../send.send.out | 12 ++++++------ 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/scripts/base/frameworks/pacf/main.bro b/scripts/base/frameworks/pacf/main.bro index 2fa04c6b24..f1f234f9d9 100644 --- a/scripts/base/frameworks/pacf/main.bro +++ b/scripts/base/frameworks/pacf/main.bro @@ -340,7 +340,7 @@ function add_rule_impl(r: Rule) : string { r$cid = ++rule_counter; # numeric id that can be used by plugins for their rules. - if ( ! r?$id ) + if ( ! r?$id || r$id == "" ) r$id = cat(r$cid); for ( i in plugins ) diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout index d107b8c09c..987f5e4cd1 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout @@ -1,5 +1,5 @@ pacf debug (Debug-All): init -pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=2, _plugin_id=1] -pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=3, _plugin_id=1] -pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=3, _plugin_id=1] -pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=3, _plugin_id=1] +pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] +pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] +pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] +pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/pacf.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/pacf.log index 7544264219..46bc612b3b 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/pacf.log +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/pacf.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path pacf -#open 2015-05-28-00-27-54 +#open 2015-05-28-23-57-41 #fields ts category cmd state action target entity_type entity msg location plugin #types time enum string enum string enum string string string string string 0.000000 Pacf::MESSAGE - - - - - - activated plugin with priority 0 - Debug-All @@ -12,7 +12,7 @@ 1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All 1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All 1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All 1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -#close 2015-05-28-00-27-54 +1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +#close 2015-05-28-23-57-41 diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/recv.recv.out b/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/recv.recv.out index 927e9e101a..2d4118e6f2 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/recv.recv.out +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/recv.recv.out @@ -1,5 +1,5 @@ BrokerComm::incoming_connection_established -add_rule, 0, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=2, _plugin_id=1] -add_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=3, _plugin_id=1] -remove_rule, 0, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=2, _plugin_id=1] -remove_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=3, _plugin_id=1] +add_rule, 0, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] +add_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] +remove_rule, 0, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] +remove_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/send.send.out b/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/send.send.out index 9b4e35e2be..c1da86ad6e 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/send.send.out +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/send.send.out @@ -1,7 +1,7 @@ BrokerComm::outgoing_connection_established, 127.0.0.1, 9999/tcp -rule added, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=2, _plugin_id=1] -rule added, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=3, _plugin_id=1] -rule timeout, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=2, _plugin_id=1], [duration=, packet_count=, byte_count=] -rule removed, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=2, _plugin_id=1] -rule timeout, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=3, _plugin_id=1], [duration=, packet_count=, byte_count=] -rule removed, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=, cid=3, _plugin_id=1] +rule added, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] +rule added, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] +rule timeout, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1], [duration=, packet_count=, byte_count=] +rule removed, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] +rule timeout, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1], [duration=, packet_count=, byte_count=] +rule removed, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] From 2f1ebed2e984e7252f034c21ce5fddf86678b720 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Mon, 1 Jun 2015 10:45:56 -0700 Subject: [PATCH 47/93] set the default idle timeout to 0 (= disable), because pacf actually does not directly support this concept. If someone wants idle timeouts, they can just re-enable them with a redef. --- scripts/base/frameworks/pacf/plugins/openflow.bro | 2 +- .../scripts.base.frameworks.pacf.openflow/openflow.log | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/base/frameworks/pacf/plugins/openflow.bro b/scripts/base/frameworks/pacf/plugins/openflow.bro index 1bfd001c00..3a28a36dfe 100644 --- a/scripts/base/frameworks/pacf/plugins/openflow.bro +++ b/scripts/base/frameworks/pacf/plugins/openflow.bro @@ -7,7 +7,7 @@ export { type OfConfig: record { monitor: bool &default=T; forward: bool &default=T; - idle_timeout: count &default=60; + 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 pacf priorities without having to write a filter function. diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log index 345dded742..ffc195ed09 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log @@ -3,10 +3,10 @@ #empty_field (empty) #unset_field - #path openflow -#open 2015-05-23-02-19-04 +#open 2015-06-01-17-45-48 #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 60 30 0 - - 1 (empty) - - F - - - - - - - -1254722767.875996 42 - - - - - 2048 - - 10.10.1.4/32 - - - 4398046511110 - OpenFlow::OFPFC_ADD 60 15 0 - - 1 (empty) - - F - - - - - - - -1254722767.875996 42 - - - - - 2048 - - - 10.10.1.4/32 - - 4398046511111 - OpenFlow::OFPFC_ADD 60 15 0 - - 1 (empty) - - F - - - - - - - -#close 2015-05-23-02-19-04 +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 - - 10.10.1.4/32 - - - 4398046511110 - OpenFlow::OFPFC_ADD 0 15 0 - - 1 (empty) - - F - - - - - - - +1254722767.875996 42 - - - - - 2048 - - - 10.10.1.4/32 - - 4398046511111 - OpenFlow::OFPFC_ADD 0 15 0 - - 1 (empty) - - F - - - - - - - +#close 2015-06-01-17-45-48 From ae180627617b247e0c7359dabef3dea9b643e333 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Mon, 1 Jun 2015 15:57:58 -0700 Subject: [PATCH 48/93] add whitelist and redirect high-level functions --- scripts/base/frameworks/pacf/main.bro | 46 +++++++++++++++++++ scripts/base/frameworks/pacf/types.bro | 17 ++----- .../.stdout | 4 ++ .../pacf.log | 12 ++++- .../scripts/base/frameworks/pacf/basic.bro | 2 + 5 files changed, 66 insertions(+), 15 deletions(-) diff --git a/scripts/base/frameworks/pacf/main.bro b/scripts/base/frameworks/pacf/main.bro index f1f234f9d9..2faa13e74d 100644 --- a/scripts/base/frameworks/pacf/main.bro +++ b/scripts/base/frameworks/pacf/main.bro @@ -57,6 +57,30 @@ export { ## 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; + ## Allows all traffic involving a specific IP address from being forwarded. + ## + ## a: The address to be whitelistet. + ## + ## t: How long to whitelist 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 whitelist_address: function(a: addr, 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 shunt 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; + ## Removes all rules for an entity. ## ## e: The entity. Note that this will be directly to entities of existing @@ -293,6 +317,14 @@ function drop_address(a: addr, t: interval, location: string &default="") : stri return add_rule(r); } +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 shunt_flow(f: flow_id, t: interval, location: string &default="") : string { local flow = Pacf::Flow( @@ -307,6 +339,20 @@ function shunt_flow(f: flow_id, t: interval, location: string &default="") : str return add_rule(r); } +function redirect_flow(f: flow_id, out_port: count, t: interval, location: string &default="") : string + { + local flow = Pacf::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, $c=out_port]; + + return add_rule(r); + } + function reset(e: Entity) { print "Pacf::reset not implemented yet"; diff --git a/scripts/base/frameworks/pacf/types.bro b/scripts/base/frameworks/pacf/types.bro index 9b186b5af2..fc15323e1b 100644 --- a/scripts/base/frameworks/pacf/types.bro +++ b/scripts/base/frameworks/pacf/types.bro @@ -2,6 +2,9 @@ module Pacf; 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. @@ -45,11 +48,6 @@ export { ## No arguments. DROP, - ## Begin rate-limiting flows matching entity. - ## - ## d: Percent of available bandwidth. - LIMIT, - ## Begin modifying all packets matching entity. ## ## .. todo:: @@ -62,11 +60,6 @@ export { ## c: output port to redirect traffic to. REDIRECT, - ## Begin sampling all flows matching entity. - ## - ## d: Probability to include a flow between 0 and 1. - SAMPLE, - ## 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 @@ -93,7 +86,7 @@ export { 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=+0; ##< Priority if multiple rules match an entity (larger value is higher priority). + 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. c: count &optional; ##< Argument for rule types requiring an count argument. @@ -115,6 +108,4 @@ export { 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/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout index 987f5e4cd1..b0a30033d0 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout @@ -1,5 +1,9 @@ pacf debug (Debug-All): init pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] +pacf debug (Debug-All): add_rule: [ty=Pacf::WHITELIST, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=5, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1] +pacf debug (Debug-All): add_rule: [ty=Pacf::REDIRECT, target=Pacf::FORWARD, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, c=5, i=, d=, s=, mod=, id=5, cid=5, _plugin_id=1] pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] +pacf debug (Debug-All): remove_rule: [ty=Pacf::WHITELIST, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=5, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1] +pacf debug (Debug-All): remove_rule: [ty=Pacf::REDIRECT, target=Pacf::FORWARD, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, c=5, i=, d=, s=, mod=, id=5, cid=5, _plugin_id=1] pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/pacf.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/pacf.log index 46bc612b3b..28d5a8c9d8 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/pacf.log +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/pacf.log @@ -3,16 +3,24 @@ #empty_field (empty) #unset_field - #path pacf -#open 2015-05-28-23-57-41 +#open 2015-06-01-22-57-07 #fields ts category cmd state action target entity_type entity msg location plugin #types time enum string enum string enum string string string string string 0.000000 Pacf::MESSAGE - - - - - - activated plugin with priority 0 - Debug-All 1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All 1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::WHITELIST Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All 1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All 1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::WHITELIST Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All 1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::WHITELIST Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All 1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All 1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::WHITELIST Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All 1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -#close 2015-05-28-23-57-41 +#close 2015-06-01-22-57-07 diff --git a/testing/btest/scripts/base/frameworks/pacf/basic.bro b/testing/btest/scripts/base/frameworks/pacf/basic.bro index 76bcd992ee..45ed9e65cc 100644 --- a/testing/btest/scripts/base/frameworks/pacf/basic.bro +++ b/testing/btest/scripts/base/frameworks/pacf/basic.bro @@ -15,4 +15,6 @@ event connection_established(c: connection) local id = c$id; Pacf::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 30sec); Pacf::drop_address(id$orig_h, 15sec); + Pacf::whitelist_address(id$orig_h, 15sec); + Pacf::redirect_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 5, 30sec); } From 269e80b3e19228c4a61fa9e89aee81a9d234ed7b Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Mon, 1 Jun 2015 18:57:16 -0700 Subject: [PATCH 49/93] make pacf logging deal with wildcards in flows. --- scripts/base/frameworks/pacf/main.bro | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/scripts/base/frameworks/pacf/main.bro b/scripts/base/frameworks/pacf/main.bro index 2faa13e74d..efb5cd60d0 100644 --- a/scripts/base/frameworks/pacf/main.bro +++ b/scripts/base/frameworks/pacf/main.bro @@ -241,9 +241,21 @@ function entity_to_info(info: Info, e: Entity) break; case FLOW: - info$entity = fmt("%s/%d->%s/%d", - e$flow$src_h, e$flow$src_p, - e$flow$dst_h, e$flow$dst_p); + local ffrom_ip = "*"; + local ffrom_port = "*"; + local fto_ip = "*"; + local fto_port = "*"; + 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); break; case MAC: From ed40855152a321f2c8360cd9f2add4722ec85a64 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 2 Jun 2015 12:34:44 -0700 Subject: [PATCH 50/93] add support for multiple backends with same priority --- scripts/base/frameworks/pacf/main.bro | 97 ++++++++++++++++--- .../pacf.log | 36 +++++++ .../scripts/base/frameworks/pacf/multiple.bro | 24 +++++ 3 files changed, 142 insertions(+), 15 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.multiple/pacf.log create mode 100644 testing/btest/scripts/base/frameworks/pacf/multiple.bro diff --git a/scripts/base/frameworks/pacf/main.bro b/scripts/base/frameworks/pacf/main.bro index efb5cd60d0..93e835bc29 100644 --- a/scripts/base/frameworks/pacf/main.bro +++ b/scripts/base/frameworks/pacf/main.bro @@ -218,7 +218,8 @@ global plugins: vector of PluginState; global plugin_ids: table[count] of PluginState; global rule_counter: count = 1; global plugin_counter: count = 1; -global rules: table[string] of Rule; +global rules: table[string,count] of Rule; # Rules indexed by id and cid +global id_to_cids: table[string] of set[count]; # id to cid event bro_init() &priority=5 { @@ -394,42 +395,63 @@ function activate_impl(p: PluginState, priority: int) log_msg(fmt("activated plugin with priority %d", priority), p); } -function add_rule_impl(r: Rule) : string +function add_rule_impl(rule: Rule) : string { - r$cid = ++rule_counter; # numeric id that can be used by plugins for their rules. + rule$cid = ++rule_counter; # numeric id that can be used by plugins for their rules. - if ( ! r?$id || r$id == "" ) - r$id = cat(r$cid); + if ( ! rule?$id || rule$id == "" ) + rule$id = cat(rule$cid); + + local accepted = F; + local priority: int = +0; + local r = rule; for ( i in plugins ) { local p = plugins[i]; + # in this case, rule was accepted by earlier plugin and thus plugin has same + # priority. accept, but give out new rule id. + if ( accepted == T && p$_priority == priority ) + { + r = copy(rule); + r$cid = ++rule_counter; + } + else if ( accepted == T ) + # in this case, rule was accepted by earlier plugin and this plugin has a lower + # priority. Abort and do not send there... + break; + # set before, in case the plugins sends and regenerates the plugin record later. r$_plugin_id = p$_id; if ( p$plugin$add_rule(p, r) ) { + accepted = T; + priority = p$_priority; log_rule(r, "ADD", REQUESTED, p); - return r$id; } } + if ( accepted ) + return rule$id; + log_rule_no_plugin(r, FAILED, "not supported"); return ""; } -function remove_rule_impl(id: string) : bool +function remove_single_rule(id: string, cid: count) : bool { - if ( id !in rules ) + if ( [id,cid] !in rules ) { - Reporter::error(fmt("Rule %s does not exist in Pacf::remove_rule", id)); + Reporter::error(fmt("Rule %s -- %d does not exist in Pacf::remove_single_rule", id, cid)); return F; } - local r = rules[id]; + local r = rules[id,cid]; local p = plugin_ids[r$_plugin_id]; + # remove the respective rules from its plugins.. if ( ! p$plugin$remove_rule(p, r) ) { log_rule_error(r, "remove failed", p); @@ -440,21 +462,52 @@ function remove_rule_impl(id: string) : bool return T; } +function remove_rule_impl(id: string) : bool + { + if ( id !in id_to_cids ) + { + Reporter::error(fmt("Rule %s does not exist in Pacf::remove_rule", id)); + return F; + } + + local cids = id_to_cids[id]; + + local success = T; + for ( cid in cids ) + { + if ( [id,cid] !in rules ) + { + Reporter::error(fmt("Internal error in pacf::remove_rule - cid %d does not belong to rule %s", cid, id)); + delete cids[cid]; + next; + } + + if ( ! remove_single_rule(id, cid) ) + success = F; + } + + return success; + } + event rule_expire(r: Rule, p: PluginState) { - if ( r$id !in rules ) + if ( [r$id,r$cid] !in rules ) # Removed already. return; event rule_timeout(r, FlowInfo(), p); - remove_rule(r$id); + remove_single_rule(r$id, r$cid); } event rule_added(r: Rule, p: PluginState, msg: string &default="") { log_rule(r, "ADD", SUCCEEDED, p); - rules[r$id] = r; + rules[r$id,r$cid] = r; + if ( r$id !in id_to_cids ) + id_to_cids[r$id] = set(); + + add id_to_cids[r$id][r$cid]; if ( r?$expire && ! p$plugin$can_expire ) schedule r$expire { rule_expire(r, p) }; @@ -462,17 +515,31 @@ event rule_added(r: Rule, p: PluginState, msg: string &default="") event rule_removed(r: Rule, p: PluginState, msg: string &default="") { - delete rules[r$id]; + delete rules[r$id,r$cid]; + delete id_to_cids[r$id][r$cid]; + if ( |id_to_cids[r$id]| == 0 ) + delete id_to_cids[r$id]; + log_rule(r, "REMOVE", SUCCEEDED, p); } event rule_timeout(r: Rule, i: FlowInfo, p: PluginState) { - delete rules[r$id]; + delete rules[r$id,r$cid]; + delete id_to_cids[r$id][r$cid]; + if ( |id_to_cids[r$id]| == 0 ) + delete id_to_cids[r$id]; + log_rule(r, "EXPIRE", TIMEOUT, p); } event rule_error(r: Rule, p: PluginState, msg: string &default="") { log_rule_error(r, msg, p); + # errors can occur during deletion. Since this probably means we wo't hear + # from it again, let's just remove it if it exists... + delete rules[r$id,r$cid]; + delete id_to_cids[r$id][r$cid]; + if ( |id_to_cids[r$id]| == 0 ) + delete id_to_cids[r$id]; } diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.multiple/pacf.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.multiple/pacf.log new file mode 100644 index 0000000000..588c014285 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.multiple/pacf.log @@ -0,0 +1,36 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path pacf +#open 2015-06-02-19-34-04 +#fields ts category cmd state action target entity_type entity msg location plugin +#types time enum string enum string enum string string string string string +0.000000 Pacf::MESSAGE - - - - - - activated plugin with priority 10 - Debug-All +0.000000 Pacf::MESSAGE - - - - - - activated plugin with priority 10 - Openflow - OpenFlog Log Plugin - DPID 42 +0.000000 Pacf::MESSAGE - - - - - - activated plugin with priority 0 - Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::WHITELIST Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::WHITELIST Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::WHITELIST Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::WHITELIST Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::WHITELIST Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::WHITELIST Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +#close 2015-06-02-19-34-04 diff --git a/testing/btest/scripts/base/frameworks/pacf/multiple.bro b/testing/btest/scripts/base/frameworks/pacf/multiple.bro new file mode 100644 index 0000000000..eda66b1a93 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/pacf/multiple.bro @@ -0,0 +1,24 @@ +# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT +# @TEST-EXEC: btest-diff pacf.log + +@load base/frameworks/pacf + +event bro_init() + { + local pacf_debug = Pacf::create_debug(T); + local pacf_debug_2 = Pacf::create_debug(T); + local of_controller = OpenFlow::log_new(42); + local pacf_of = Pacf::create_openflow(of_controller); + Pacf::activate(pacf_debug, 10); + Pacf::activate(pacf_of, 10); + Pacf::activate(pacf_debug_2, 0); + } + +event connection_established(c: connection) + { + local id = c$id; + Pacf::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 30sec); + Pacf::drop_address(id$orig_h, 15sec); + Pacf::whitelist_address(id$orig_h, 15sec); + Pacf::redirect_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 5, 30sec); + } From 1439c244fc06f7e5fbd655d39a846f57622a5567 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 2 Jun 2015 14:23:25 -0700 Subject: [PATCH 51/93] add hook to pacf that allows users to modify all rules or implement whitelists or similar. --- scripts/base/frameworks/pacf/main.bro | 10 +++++++ .../pacf.log | 18 +++++++++++++ .../scripts/base/frameworks/pacf/hook.bro | 27 +++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.hook/pacf.log create mode 100644 testing/btest/scripts/base/frameworks/pacf/hook.bro diff --git a/scripts/base/frameworks/pacf/main.bro b/scripts/base/frameworks/pacf/main.bro index 93e835bc29..dc21b99665 100644 --- a/scripts/base/frameworks/pacf/main.bro +++ b/scripts/base/frameworks/pacf/main.bro @@ -159,6 +159,13 @@ export { ## 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 Pacf::rule_policy: hook(r: Rule); + ## Type of an entry in the PACF log. type InfoCategory: enum { ## A log entry reflecting a framework message. @@ -402,6 +409,9 @@ function add_rule_impl(rule: Rule) : string if ( ! rule?$id || rule$id == "" ) rule$id = cat(rule$cid); + if ( ! hook Pacf::rule_policy(rule) ) + return ""; + local accepted = F; local priority: int = +0; local r = rule; diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.hook/pacf.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.hook/pacf.log new file mode 100644 index 0000000000..1725aa4918 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.hook/pacf.log @@ -0,0 +1,18 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path pacf +#open 2015-06-02-21-23-05 +#fields ts category cmd state action target entity_type entity msg location plugin +#types time enum string enum string enum string string string string string +0.000000 Pacf::MESSAGE - - - - - - activated plugin with priority 0 - Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All +#close 2015-06-02-21-23-05 diff --git a/testing/btest/scripts/base/frameworks/pacf/hook.bro b/testing/btest/scripts/base/frameworks/pacf/hook.bro new file mode 100644 index 0000000000..e31237d934 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/pacf/hook.bro @@ -0,0 +1,27 @@ +# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT +# @TEST-EXEC: btest-diff pacf.log + +@load base/frameworks/pacf + +event bro_init() + { + local pacf_debug = Pacf::create_debug(T); + Pacf::activate(pacf_debug, 0); + } + +event connection_established(c: connection) + { + local id = c$id; + Pacf::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 30sec); + Pacf::drop_address(id$orig_h, 15sec); + Pacf::whitelist_address(id$orig_h, 15sec); + Pacf::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 Pacf::rule_policy(r: Pacf::Rule) + { + if ( r$expire == 15sec ) + break; + + r$entity$flow$src_h = 0.0.0.0/0; + } From f88a1337c0bdad349d0c8844f38238129a2f596a Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 2 Jun 2015 15:03:34 -0700 Subject: [PATCH 52/93] add basic catch-and-release functionality (without own logging so far). --- scripts/base/frameworks/pacf/__load__.bro | 1 + .../frameworks/pacf/catch-and-release.bro | 99 +++++++++++++++++++ .../.stdout | 11 +++ .../pacf.log | 30 ++++++ .../scripts/base/frameworks/pacf/basic.bro | 4 +- .../frameworks/pacf/catch-and-release.bro | 32 ++++++ .../scripts/base/frameworks/pacf/multiple.bro | 2 +- 7 files changed, 176 insertions(+), 3 deletions(-) create mode 100644 scripts/base/frameworks/pacf/catch-and-release.bro create mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.catch-and-release/.stdout create mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.catch-and-release/pacf.log create mode 100644 testing/btest/scripts/base/frameworks/pacf/catch-and-release.bro diff --git a/scripts/base/frameworks/pacf/__load__.bro b/scripts/base/frameworks/pacf/__load__.bro index 033c30f9a0..7bfd6aed7e 100644 --- a/scripts/base/frameworks/pacf/__load__.bro +++ b/scripts/base/frameworks/pacf/__load__.bro @@ -1,6 +1,7 @@ @load ./types @load ./main @load ./plugins +@load ./catch-and-release # The cluster framework must be loaded first. @load base/frameworks/cluster diff --git a/scripts/base/frameworks/pacf/catch-and-release.bro b/scripts/base/frameworks/pacf/catch-and-release.bro new file mode 100644 index 0000000000..fceefadb5c --- /dev/null +++ b/scripts/base/frameworks/pacf/catch-and-release.bro @@ -0,0 +1,99 @@ +##! Implementation of catch-and-release functionality for Pacf + +module Pacf; + +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; + + 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/testing/btest/Baseline/scripts.base.frameworks.pacf.catch-and-release/.stdout b/testing/btest/Baseline/scripts.base.frameworks.pacf.catch-and-release/.stdout new file mode 100644 index 0000000000..d7f55a9556 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.catch-and-release/.stdout @@ -0,0 +1,11 @@ +pacf debug (Debug-All): init +pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=10.0 mins, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] +pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=1.0 hr, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] +pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=1.0 day, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1] +pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=7.0 days, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=5, cid=5, _plugin_id=1] +pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=7.0 days, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=6, cid=6, _plugin_id=1] +pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=10.0 mins, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] +pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=1.0 hr, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] +pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=1.0 day, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1] +pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=7.0 days, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=6, cid=6, _plugin_id=1] +pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=7.0 days, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=5, cid=5, _plugin_id=1] diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.catch-and-release/pacf.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.catch-and-release/pacf.log new file mode 100644 index 0000000000..31a7c7dff4 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.catch-and-release/pacf.log @@ -0,0 +1,30 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path pacf +#open 2015-06-02-22-02-42 +#fields ts category cmd state action target entity_type entity msg location plugin +#types time enum string enum string enum string string string string string +0.000000 Pacf::MESSAGE - - - - - - activated plugin with priority 0 - Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +#close 2015-06-02-22-02-42 diff --git a/testing/btest/scripts/base/frameworks/pacf/basic.bro b/testing/btest/scripts/base/frameworks/pacf/basic.bro index 45ed9e65cc..0684daaecd 100644 --- a/testing/btest/scripts/base/frameworks/pacf/basic.bro +++ b/testing/btest/scripts/base/frameworks/pacf/basic.bro @@ -1,6 +1,6 @@ # @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT -# @TEST-EXEC: btest-diff pacf.log -# @TEST-EXEC: btest-diff .stdout +# @TEST-EXEC: TEST_DIFF_CANONIFIER='grep -v ^# | $SCRIPTS/diff-sort' btest-diff pacf.log +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff .stdout @load base/frameworks/pacf diff --git a/testing/btest/scripts/base/frameworks/pacf/catch-and-release.bro b/testing/btest/scripts/base/frameworks/pacf/catch-and-release.bro new file mode 100644 index 0000000000..df6850ac3d --- /dev/null +++ b/testing/btest/scripts/base/frameworks/pacf/catch-and-release.bro @@ -0,0 +1,32 @@ +# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT +# @TEST-EXEC: TEST_DIFF_CANONIFIER='grep -v ^# | $SCRIPTS/diff-sort' btest-diff pacf.log +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff .stdout + +@load base/frameworks/pacf + +event bro_init() + { + local pacf_debug = Pacf::create_debug(T); + Pacf::activate(pacf_debug, 0); + } + +module Pacf; + +event connection_established(c: connection) + { + local id = c$id; + Pacf::drop_address_catch_release(id$orig_h); + # second one should be ignored because duplicate + Pacf::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/pacf/multiple.bro b/testing/btest/scripts/base/frameworks/pacf/multiple.bro index eda66b1a93..baa8c5822e 100644 --- a/testing/btest/scripts/base/frameworks/pacf/multiple.bro +++ b/testing/btest/scripts/base/frameworks/pacf/multiple.bro @@ -1,5 +1,5 @@ # @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT -# @TEST-EXEC: btest-diff pacf.log +# @TEST-EXEC: TEST_DIFF_CANONIFIER='grep -v ^# | $SCRIPTS/diff-sort' btest-diff pacf.log @load base/frameworks/pacf From ee645dfce9f0a160880eda2130f58fd25f1e1412 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 3 Jun 2015 11:05:04 -0700 Subject: [PATCH 53/93] Acld implementation for Pacf - Bro side. Still needs a few small fixes to deal with the fact that acld does not always accept subnets. --- .../base/frameworks/pacf/plugins/__load__.bro | 1 + scripts/base/frameworks/pacf/plugins/acld.bro | 215 ++++++++++++++++++ .../recv.recv.out | 7 + .../send.send.out | 7 + .../scripts/base/frameworks/pacf/acld.bro | 111 +++++++++ 5 files changed, 341 insertions(+) create mode 100644 scripts/base/frameworks/pacf/plugins/acld.bro create mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.acld/recv.recv.out create mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.acld/send.send.out create mode 100644 testing/btest/scripts/base/frameworks/pacf/acld.bro diff --git a/scripts/base/frameworks/pacf/plugins/__load__.bro b/scripts/base/frameworks/pacf/plugins/__load__.bro index 11e8723478..255cee5f69 100644 --- a/scripts/base/frameworks/pacf/plugins/__load__.bro +++ b/scripts/base/frameworks/pacf/plugins/__load__.bro @@ -2,3 +2,4 @@ @load ./openflow @load ./packetfilter @load ./broker +@load ./acld diff --git a/scripts/base/frameworks/pacf/plugins/acld.bro b/scripts/base/frameworks/pacf/plugins/acld.bro new file mode 100644 index 0000000000..25218ce470 --- /dev/null +++ b/scripts/base/frameworks/pacf/plugins/acld.bro @@ -0,0 +1,215 @@ +# Acld plugin for the pacf framework. + +module Pacf; + +@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; + ## Function that can decide weather to accept add request + add_pred: function(p: PluginState, r: Rule, ar: AclRule): bool &optional &weaken; + }; + + ## 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; + }; + + global acld_add_rule: event(id: count, r: Rule, ar: AclRule); + global acld_remove_rule: event(id: count, r: Rule, ar: AclRule); + + 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 pacf_acld_topics: set[string] = set(); +global pacf_acld_id: table[count] of PluginState = table(); +global pacf_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 Pacf::acld_rule_added(id: count, r: Rule, msg: string) + { + if ( id !in pacf_acld_id ) + { + Reporter::error(fmt("Pacf acld plugin with id %d not found, aborting", id)); + return; + } + + local p = pacf_acld_id[id]; + + event Pacf::rule_added(r, p, msg); + } + +event Pacf::acld_rule_removed(id: count, r: Rule, msg: string) + { + if ( id !in pacf_acld_id ) + { + Reporter::error(fmt("Pacf acld plugin with id %d not found, aborting", id)); + return; + } + + local p = pacf_acld_id[id]; + + event Pacf::rule_removed(r, p, msg); + } + +event Pacf::acld_rule_error(id: count, r: Rule, msg: string) + { + if ( id !in pacf_acld_id ) + { + Reporter::error(fmt("Pacf acld plugin with id %d not found, aborting", id)); + return; + } + + local p = pacf_acld_id[id]; + + event Pacf::rule_error(r, p, msg); + } + +function acld_name(p: PluginState) : string + { + return fmt("PACF acld plugin - using broker topic %s", p$acld_config$acld_topic); + } + +function rule_to_acl_rule(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 ) ) + { + # fixme - check if address is not a subnet + 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", 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 ( r$ty == DROP ) + command = "blockhosthost"; + arg = fmt("%s %s", f$src_h, 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; + return ar; + } + +function acld_add_rule_fun(p: PluginState, r: Rule) : bool + { + local ar = rule_to_acl_rule(r); + + if ( p$acld_config?$add_pred ) + if ( ! p$acld_config$add_pred(p, r, ar) ) + return F; + + 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 + { + local ar = rule_to_acl_rule(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); + } + +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 pacf_acld_topics ) + Reporter::warning(fmt("Topic %s was added to Pacf acld plugin twice. Possible duplication of commands", config$acld_topic)); + else + add pacf_acld_topics[config$acld_topic]; + + local p: PluginState = [$acld_config=config, $plugin=acld_plugin, $acld_id=pacf_acld_current_id]; + + pacf_acld_id[pacf_acld_current_id] = p; + ++pacf_acld_current_id; + + return p; + } + diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.acld/recv.recv.out b/testing/btest/Baseline/scripts.base.frameworks.pacf.acld/recv.recv.out new file mode 100644 index 0000000000..92ccbc6257 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.acld/recv.recv.out @@ -0,0 +1,7 @@ +BrokerComm::incoming_connection_established +add_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=, dst_h=74.53.140.153/32, dst_p=, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1], [command=blockhosthost, cookie=2, arg=10.10.1.4/32 74.53.140.153/32, comment=here] +add_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1], [command=droptcpport, cookie=3, arg=25, comment=here] +add_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1], [command=drop, cookie=4, arg=10.10.1.4/32, comment=] +remove_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=, dst_h=74.53.140.153/32, dst_p=, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1], [command=restorehosthost, cookie=2, arg=10.10.1.4/32 74.53.140.153/32, comment=here] +remove_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1], [command=restoretcpport, cookie=3, arg=25, comment=here] +remove_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1], [command=restore, cookie=4, arg=10.10.1.4/32, comment=] diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.acld/send.send.out b/testing/btest/Baseline/scripts.base.frameworks.pacf.acld/send.send.out new file mode 100644 index 0000000000..1f7e952357 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.acld/send.send.out @@ -0,0 +1,7 @@ +BrokerComm::outgoing_connection_established, 127.0.0.1, 9999/tcp +rule added, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=, dst_h=74.53.140.153/32, dst_p=, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] +rule added, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] +rule added, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1] +rule removed, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=, dst_h=74.53.140.153/32, dst_p=, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] +rule removed, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] +rule removed, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1] diff --git a/testing/btest/scripts/base/frameworks/pacf/acld.bro b/testing/btest/scripts/base/frameworks/pacf/acld.bro new file mode 100644 index 0000000000..bf10138a6a --- /dev/null +++ b/testing/btest/scripts/base/frameworks/pacf/acld.bro @@ -0,0 +1,111 @@ +# @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/frameworks/pacf + +const broker_port: port &redef; +redef exit_only_after_terminate = T; + +event bro_init() + { + suspend_processing(); + local pacf_acld = Pacf::create_acld(Pacf::AcldConfig($acld_host=127.0.0.1, $acld_port=broker_port, $acld_topic="bro/event/pacftest")); + Pacf::activate(pacf_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; + 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 = Pacf::Flow( + $src_h=addr_to_subnet(c$id$orig_h), + $dst_h=addr_to_subnet(c$id$resp_h) + ); + local e1: Pacf::Entity = [$ty=Pacf::FLOW, $flow=flow1]; + local r1: Pacf::Rule = [$ty=Pacf::DROP, $target=Pacf::FORWARD, $entity=e1, $expire=10hrs, $location="here"]; + + local flow2 = Pacf::Flow( + $dst_p=c$id$resp_p + ); + local e2: Pacf::Entity = [$ty=Pacf::FLOW, $flow=flow2]; + local r2: Pacf::Rule = [$ty=Pacf::DROP, $target=Pacf::FORWARD, $entity=e2, $expire=10hrs, $location="here"]; + + Pacf::add_rule(r1); + Pacf::add_rule(r2); + Pacf::drop_address(id$orig_h, 10hrs); + } + +event Pacf::rule_added(r: Pacf::Rule, p: Pacf::PluginState, msg: string) + { + print "rule added", r; + Pacf::remove_rule(r$id); + } + +event Pacf::rule_removed(r: Pacf::Rule, p: Pacf::PluginState, msg: string) + { + print "rule removed", r; + } + +@TEST-END-FILE + +@TEST-START-FILE recv.bro + +@load base/frameworks/pacf +@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/pacftest"); + BrokerComm::listen(broker_port, "127.0.0.1"); + } + +event BrokerComm::incoming_connection_established(peer_name: string) + { + print "BrokerComm::incoming_connection_established"; + } + +event Pacf::acld_add_rule(id: count, r: Pacf::Rule, ar: Pacf::AclRule) + { + print "add_rule", id, r, ar; + + BrokerComm::event("bro/event/pacftest", BrokerComm::event_args(Pacf::acld_rule_added, id, r, ar$command)); + } + +event Pacf::acld_remove_rule(id: count, r: Pacf::Rule, ar: Pacf::AclRule) + { + print "remove_rule", id, r, ar; + + BrokerComm::event("bro/event/pacftest", BrokerComm::event_args(Pacf::acld_rule_removed, id, r, ar$command)); + + if ( r$cid == 4 ) + terminate(); + } + +@TEST-END-FILE + From e6834367fd78ed1128e086bfdef832ee8357c538 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Thu, 4 Jun 2015 11:16:42 -0700 Subject: [PATCH 54/93] miscelaneous missing bits and pieces --- scripts/base/frameworks/pacf/main.bro | 45 ++++++++++++++++----------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/scripts/base/frameworks/pacf/main.bro b/scripts/base/frameworks/pacf/main.bro index dc21b99665..3d5041661e 100644 --- a/scripts/base/frameworks/pacf/main.bro +++ b/scripts/base/frameworks/pacf/main.bro @@ -46,6 +46,17 @@ export { ## 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; + ## Stops forwarding a uni-directional flow's packets to Bro. ## ## f: The flow to shunt. @@ -63,7 +74,7 @@ export { ## ## t: How long to whitelist it, with 0 being indefinitly. ## - ## location: An optional string describing where the drop was triggered. + ## 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; @@ -76,17 +87,11 @@ export { ## ## t: How long to leave the redirect in place, with 0 being indefinitly. ## - ## location: An optional string describing where the shunt was triggered. + ## 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; - ## Removes all rules for an entity. - ## - ## e: The entity. Note that this will be directly to entities of existing - ## rules, which must match exactly field by field. - global reset: function(e: Entity); - ## Flushes all state. global clear: function(); @@ -329,6 +334,14 @@ function log_rule_no_plugin(r: Rule, state: InfoState, msg: string) Log::write(LOG, info); } +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]; + + return add_rule(r); + } + function drop_address(a: addr, t: interval, location: string &default="") : string { local e: Entity = [$ty=ADDRESS, $ip=addr_to_subnet(a)]; @@ -373,16 +386,6 @@ function redirect_flow(f: flow_id, out_port: count, t: interval, location: strin return add_rule(r); } -function reset(e: Entity) - { - print "Pacf::reset not implemented yet"; - } - -function clear() - { - print "Pacf::clear not implemented yet"; - } - # Low-level functions that only runs on the manager (or standalone) Bro node. function activate_impl(p: PluginState, priority: int) @@ -553,3 +556,9 @@ event rule_error(r: Rule, p: PluginState, msg: string &default="") if ( |id_to_cids[r$id]| == 0 ) delete id_to_cids[r$id]; } + +function clear() + { + for ( [id,cid] in rules ) + remove_single_rule(id, cid); + } From cedb80ff7444ef1192ddd1137068f0f62420e74d Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Thu, 4 Jun 2015 16:21:22 -0700 Subject: [PATCH 55/93] implement quarantine --- scripts/base/frameworks/pacf/main.bro | 59 ++++++++++++++++++- .../openflow.log | 13 ++++ .../pacf.log | 18 ++++++ .../frameworks/pacf/quarantine-openflow.bro | 19 ++++++ 4 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.quarantine-openflow/openflow.log create mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.quarantine-openflow/pacf.log create mode 100644 testing/btest/scripts/base/frameworks/pacf/quarantine-openflow.bro diff --git a/scripts/base/frameworks/pacf/main.bro b/scripts/base/frameworks/pacf/main.bro index 3d5041661e..3ba941e4da 100644 --- a/scripts/base/frameworks/pacf/main.bro +++ b/scripts/base/frameworks/pacf/main.bro @@ -68,7 +68,7 @@ export { ## 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; - ## Allows all traffic involving a specific IP address from being forwarded. + ## Allows all traffic involving a specific IP address to be forwarded. ## ## a: The address to be whitelistet. ## @@ -79,6 +79,17 @@ export { ## 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. @@ -92,6 +103,21 @@ export { ## 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) : vector of string; + ## Flushes all state. global clear: function(); @@ -358,6 +384,14 @@ function whitelist_address(a: addr, t: interval, location: string &default="") : 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 shunt_flow(f: flow_id, t: interval, location: string &default="") : string { local flow = Pacf::Flow( @@ -386,6 +420,29 @@ function redirect_flow(f: flow_id, out_port: count, t: interval, location: strin 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; + } + + # Low-level functions that only runs on the manager (or standalone) Bro node. function activate_impl(p: PluginState, priority: int) diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.quarantine-openflow/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.quarantine-openflow/openflow.log new file mode 100644 index 0000000000..1b4081a31d --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.quarantine-openflow/openflow.log @@ -0,0 +1,13 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path openflow +#open 2015-06-04-23-21-03 +#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 - - 10.10.1.4/32 - - - 4398046511108 - OpenFlow::OFPFC_ADD 0 36000 0 - - 1 (empty) - - F - - - - - - - +1254722767.875996 42 - - - - - 2048 - 17 10.10.1.4/32 8.8.8.8/32 - 53 4398046511110 - OpenFlow::OFPFC_ADD 0 36000 5 - - 1 4294967290 - - F - - - - 192.169.18.1 - - +1254722767.875996 42 - - - - - 2048 - 17 8.8.8.8/32 10.10.1.4/32 53 - 4398046511112 - OpenFlow::OFPFC_ADD 0 36000 5 - - 1 4294967290 - - F - - - 8.8.8.8 - - - +1254722767.875996 42 - - - - - 2048 - 6 10.10.1.4/32 192.169.18.1/32 - 80 4398046511114 - OpenFlow::OFPFC_ADD 0 36000 5 - - 1 4294967290 - - F - - - - - - - +#close 2015-06-04-23-21-03 diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.quarantine-openflow/pacf.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.quarantine-openflow/pacf.log new file mode 100644 index 0000000000..0bcb99fd48 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.quarantine-openflow/pacf.log @@ -0,0 +1,18 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path pacf +#open 2015-06-04-23-18-56 +#fields ts category cmd state action target entity_type entity msg location plugin +#types time enum string enum string enum string string string string string +0.000000 Pacf::MESSAGE - - - - - - activated plugin with priority 0 - Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/*->*/* - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::MODIFY Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/*->8.8.8.8/32/53 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::MODIFY Pacf::FORWARD Pacf::FLOW 8.8.8.8/32/53->10.10.1.4/32/* - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::WHITELIST Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/*->192.169.18.1/32/80 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/*->*/* - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::MODIFY Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/*->8.8.8.8/32/53 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::MODIFY Pacf::FORWARD Pacf::FLOW 8.8.8.8/32/53->10.10.1.4/32/* - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::WHITELIST Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/*->192.169.18.1/32/80 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +#close 2015-06-04-23-18-56 diff --git a/testing/btest/scripts/base/frameworks/pacf/quarantine-openflow.bro b/testing/btest/scripts/base/frameworks/pacf/quarantine-openflow.bro new file mode 100644 index 0000000000..eff863b684 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/pacf/quarantine-openflow.bro @@ -0,0 +1,19 @@ +# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT +# @TEST-EXEC: btest-diff pacf.log +# @TEST-EXEC: btest-diff openflow.log + +@load base/frameworks/pacf + +global of_controller: OpenFlow::Controller; + +event bro_init() + { + of_controller = OpenFlow::log_new(42); + local pacf_of = Pacf::create_openflow(of_controller); + Pacf::activate(pacf_of, 0); + } + +event connection_established(c: connection) + { + Pacf::quarantine_host(c$id$orig_h, 8.8.8.8, 192.169.18.1, 10hrs); + } From 17796182c6a24c2bc80e3aa96d7aa1cf22ca67f3 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Fri, 5 Jun 2015 00:00:20 -0700 Subject: [PATCH 56/93] fix acld plugin to use address instead of subnet (and add functions for conversion) --- scripts/base/frameworks/pacf/plugins/acld.bro | 25 +++++++++++++---- src/bro.bif | 27 ++++++++++++++++++- .../btest/Baseline/bifs.subnet_to_addr/error | 0 .../btest/Baseline/bifs.subnet_to_addr/output | 3 +++ .../recv.recv.out | 4 +-- testing/btest/bifs/subnet_to_addr.bro | 14 ++++++++++ 6 files changed, 65 insertions(+), 8 deletions(-) create mode 100644 testing/btest/Baseline/bifs.subnet_to_addr/error create mode 100644 testing/btest/Baseline/bifs.subnet_to_addr/output create mode 100644 testing/btest/bifs/subnet_to_addr.bro diff --git a/scripts/base/frameworks/pacf/plugins/acld.bro b/scripts/base/frameworks/pacf/plugins/acld.bro index 25218ce470..95d8d5abed 100644 --- a/scripts/base/frameworks/pacf/plugins/acld.bro +++ b/scripts/base/frameworks/pacf/plugins/acld.bro @@ -102,6 +102,18 @@ function acld_name(p: PluginState) : string return fmt("PACF acld plugin - using broker topic %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(r: Rule) : AclRule { local e = r$entity; @@ -122,8 +134,9 @@ function rule_to_acl_rule(r: Rule) : AclRule local f = e$flow; if ( ( ! f?$src_h ) && ( ! f?$src_p ) && f?$dst_h && f?$dst_p && ( ! f?$src_m ) && ( ! f?$dst_m ) ) { - # fixme - check if address is not a subnet - if ( is_tcp_port(f$dst_p) && r$ty == DROP ) + 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"; @@ -132,13 +145,15 @@ function rule_to_acl_rule(r: Rule) : AclRule else if ( is_udp_port(f$dst_p) && r$ty == WHITELIST) command = "permitucpdsthostport"; - arg = fmt("%s %d", f$dst_h, f$dst_p); + 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 ( r$ty == DROP ) + if ( !check_sn(f$src_h) || !check_sn(f$dst_h) ) + command = ""; + else if ( r$ty == DROP ) command = "blockhosthost"; - arg = fmt("%s %s", f$src_h, f$dst_h); + 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 ) ) { diff --git a/src/bro.bif b/src/bro.bif index e6f6923130..6571826e87 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -2398,7 +2398,7 @@ function to_subnet%(sn: string%): subnet ## ## a: The address to convert. ## -## Returns: The *sn* string as a :bro:type:`subnet`. +## Returns: The *a* address as a :bro:type:`subnet`. ## ## .. bro:see:: to_subset function addr_to_subnet%(a: addr%): subnet @@ -2407,6 +2407,31 @@ function addr_to_subnet%(a: addr%): subnet 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/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/scripts.base.frameworks.pacf.acld/recv.recv.out b/testing/btest/Baseline/scripts.base.frameworks.pacf.acld/recv.recv.out index 92ccbc6257..ad604ec09f 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.acld/recv.recv.out +++ b/testing/btest/Baseline/scripts.base.frameworks.pacf.acld/recv.recv.out @@ -1,7 +1,7 @@ BrokerComm::incoming_connection_established -add_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=, dst_h=74.53.140.153/32, dst_p=, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1], [command=blockhosthost, cookie=2, arg=10.10.1.4/32 74.53.140.153/32, comment=here] +add_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=, dst_h=74.53.140.153/32, dst_p=, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1], [command=blockhosthost, cookie=2, arg=10.10.1.4 74.53.140.153, comment=here] add_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1], [command=droptcpport, cookie=3, arg=25, comment=here] add_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1], [command=drop, cookie=4, arg=10.10.1.4/32, comment=] -remove_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=, dst_h=74.53.140.153/32, dst_p=, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1], [command=restorehosthost, cookie=2, arg=10.10.1.4/32 74.53.140.153/32, comment=here] +remove_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=, dst_h=74.53.140.153/32, dst_p=, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1], [command=restorehosthost, cookie=2, arg=10.10.1.4 74.53.140.153, comment=here] remove_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1], [command=restoretcpport, cookie=3, arg=25, comment=here] remove_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1], [command=restore, cookie=4, arg=10.10.1.4/32, comment=] 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]); From 0e213352d74062bb5841d198face1c75a1dc6d0b Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 8 Jul 2015 12:34:42 -0700 Subject: [PATCH 57/93] Rename Pacf to NetControl --- .../{pacf => netcontrol}/__load__.bro | 0 .../catch-and-release.bro | 4 +- .../{pacf => netcontrol}/cluster.bro | 18 +++--- .../frameworks/{pacf => netcontrol}/main.bro | 22 +++---- .../{pacf => netcontrol}/non-cluster.bro | 2 +- .../{pacf => netcontrol}/plugin.bro | 2 +- .../{pacf => netcontrol}/plugins/__load__.bro | 0 .../{pacf => netcontrol}/plugins/acld.bro | 52 +++++++-------- .../{pacf => netcontrol}/plugins/broker.bro | 64 +++++++++---------- .../{pacf => netcontrol}/plugins/debug.bro | 8 +-- .../{pacf => netcontrol}/plugins/openflow.bro | 18 +++--- .../plugins/packetfilter.bro | 2 +- .../frameworks/{pacf => netcontrol}/types.bro | 2 +- scripts/base/init-default.bro | 2 +- .../recv.recv.out | 7 ++ .../send.send.out | 7 ++ .../manager-1.netcontrol.log | 32 ++++++++++ .../worker-1..stdout | 0 .../worker-2..stdout | 0 .../.stdout | 9 +++ .../netcontrol.log | 26 ++++++++ .../recv.recv.out | 5 ++ .../send.send.out | 7 ++ .../.stdout | 11 ++++ .../netcontrol.log | 30 +++++++++ .../netcontrol.log | 18 ++++++ .../netcontrol.log | 36 +++++++++++ .../netcontrol.log | 14 ++++ .../openflow.log | 0 .../conn.log | 0 .../netcontrol.log | 18 ++++++ .../openflow.log | 0 .../recv.recv.out | 7 -- .../send.send.out | 7 -- .../manager-1.pacf.log | 32 ---------- .../.stdout | 9 --- .../pacf.log | 26 -------- .../recv.recv.out | 5 -- .../send.send.out | 7 -- .../.stdout | 11 ---- .../pacf.log | 30 --------- .../pacf.log | 18 ------ .../pacf.log | 36 ----------- .../pacf.log | 14 ---- .../pacf.log | 18 ------ .../frameworks/{pacf => netcontrol}/acld.bro | 42 ++++++------ .../{pacf => netcontrol}/basic-cluster.bro | 14 ++-- .../base/frameworks/netcontrol/basic.bro | 20 ++++++ .../{pacf => netcontrol}/broker.bro | 32 +++++----- .../catch-and-release.bro | 14 ++-- .../base/frameworks/netcontrol/hook.bro | 27 ++++++++ .../base/frameworks/netcontrol/multiple.bro | 24 +++++++ .../base/frameworks/netcontrol/openflow.bro | 21 ++++++ .../frameworks/netcontrol/packetfilter.bro | 18 ++++++ .../netcontrol/quarantine-openflow.bro | 19 ++++++ .../scripts/base/frameworks/pacf/basic.bro | 20 ------ .../scripts/base/frameworks/pacf/hook.bro | 27 -------- .../scripts/base/frameworks/pacf/multiple.bro | 24 ------- .../scripts/base/frameworks/pacf/openflow.bro | 21 ------ .../base/frameworks/pacf/packetfilter.bro | 18 ------ .../frameworks/pacf/quarantine-openflow.bro | 19 ------ 61 files changed, 498 insertions(+), 498 deletions(-) rename scripts/base/frameworks/{pacf => netcontrol}/__load__.bro (100%) rename scripts/base/frameworks/{pacf => netcontrol}/catch-and-release.bro (96%) rename scripts/base/frameworks/{pacf => netcontrol}/cluster.bro (67%) rename scripts/base/frameworks/{pacf => netcontrol}/main.bro (96%) rename scripts/base/frameworks/{pacf => netcontrol}/non-cluster.bro (92%) rename scripts/base/frameworks/{pacf => netcontrol}/plugin.bro (99%) rename scripts/base/frameworks/{pacf => netcontrol}/plugins/__load__.bro (100%) rename scripts/base/frameworks/{pacf => netcontrol}/plugins/acld.bro (78%) rename scripts/base/frameworks/{pacf => netcontrol}/plugins/broker.bro (56%) rename scripts/base/frameworks/{pacf => netcontrol}/plugins/debug.bro (91%) rename scripts/base/frameworks/{pacf => netcontrol}/plugins/openflow.bro (93%) rename scripts/base/frameworks/{pacf => netcontrol}/plugins/packetfilter.bro (99%) rename scripts/base/frameworks/{pacf => netcontrol}/types.bro (99%) create mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld/recv.recv.out create mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld/send.send.out create mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/manager-1.netcontrol.log rename testing/btest/Baseline/{scripts.base.frameworks.pacf.basic-cluster => scripts.base.frameworks.netcontrol.basic-cluster}/worker-1..stdout (100%) rename testing/btest/Baseline/{scripts.base.frameworks.pacf.basic-cluster => scripts.base.frameworks.netcontrol.basic-cluster}/worker-2..stdout (100%) create mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/.stdout create mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol.log create mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/recv.recv.out create mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/send.send.out create mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.catch-and-release/.stdout create mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.catch-and-release/netcontrol.log create mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.hook/netcontrol.log create mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/netcontrol.log create mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/netcontrol.log rename testing/btest/Baseline/{scripts.base.frameworks.pacf.openflow => scripts.base.frameworks.netcontrol.openflow}/openflow.log (100%) rename testing/btest/Baseline/{scripts.base.frameworks.pacf.packetfilter => scripts.base.frameworks.netcontrol.packetfilter}/conn.log (100%) create mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.quarantine-openflow/netcontrol.log rename testing/btest/Baseline/{scripts.base.frameworks.pacf.quarantine-openflow => scripts.base.frameworks.netcontrol.quarantine-openflow}/openflow.log (100%) delete mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.acld/recv.recv.out delete mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.acld/send.send.out delete mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.basic-cluster/manager-1.pacf.log delete mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout delete mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.basic/pacf.log delete mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.broker/recv.recv.out delete mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.broker/send.send.out delete mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.catch-and-release/.stdout delete mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.catch-and-release/pacf.log delete mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.hook/pacf.log delete mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.multiple/pacf.log delete mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/pacf.log delete mode 100644 testing/btest/Baseline/scripts.base.frameworks.pacf.quarantine-openflow/pacf.log rename testing/btest/scripts/base/frameworks/{pacf => netcontrol}/acld.bro (53%) rename testing/btest/scripts/base/frameworks/{pacf => netcontrol}/basic-cluster.bro (75%) create mode 100644 testing/btest/scripts/base/frameworks/netcontrol/basic.bro rename testing/btest/scripts/base/frameworks/{pacf => netcontrol}/broker.bro (57%) rename testing/btest/scripts/base/frameworks/{pacf => netcontrol}/catch-and-release.bro (68%) create mode 100644 testing/btest/scripts/base/frameworks/netcontrol/hook.bro create mode 100644 testing/btest/scripts/base/frameworks/netcontrol/multiple.bro create mode 100644 testing/btest/scripts/base/frameworks/netcontrol/openflow.bro create mode 100644 testing/btest/scripts/base/frameworks/netcontrol/packetfilter.bro create mode 100644 testing/btest/scripts/base/frameworks/netcontrol/quarantine-openflow.bro delete mode 100644 testing/btest/scripts/base/frameworks/pacf/basic.bro delete mode 100644 testing/btest/scripts/base/frameworks/pacf/hook.bro delete mode 100644 testing/btest/scripts/base/frameworks/pacf/multiple.bro delete mode 100644 testing/btest/scripts/base/frameworks/pacf/openflow.bro delete mode 100644 testing/btest/scripts/base/frameworks/pacf/packetfilter.bro delete mode 100644 testing/btest/scripts/base/frameworks/pacf/quarantine-openflow.bro diff --git a/scripts/base/frameworks/pacf/__load__.bro b/scripts/base/frameworks/netcontrol/__load__.bro similarity index 100% rename from scripts/base/frameworks/pacf/__load__.bro rename to scripts/base/frameworks/netcontrol/__load__.bro diff --git a/scripts/base/frameworks/pacf/catch-and-release.bro b/scripts/base/frameworks/netcontrol/catch-and-release.bro similarity index 96% rename from scripts/base/frameworks/pacf/catch-and-release.bro rename to scripts/base/frameworks/netcontrol/catch-and-release.bro index fceefadb5c..608f18ac19 100644 --- a/scripts/base/frameworks/pacf/catch-and-release.bro +++ b/scripts/base/frameworks/netcontrol/catch-and-release.bro @@ -1,6 +1,6 @@ -##! Implementation of catch-and-release functionality for Pacf +##! Implementation of catch-and-release functionality for NetControl -module Pacf; +module NetControl; export { ## Stops all packets involving an IP address from being forwarded. This function diff --git a/scripts/base/frameworks/pacf/cluster.bro b/scripts/base/frameworks/netcontrol/cluster.bro similarity index 67% rename from scripts/base/frameworks/pacf/cluster.bro rename to scripts/base/frameworks/netcontrol/cluster.bro index aea6e832e8..880736c8ed 100644 --- a/scripts/base/frameworks/pacf/cluster.bro +++ b/scripts/base/frameworks/netcontrol/cluster.bro @@ -1,20 +1,20 @@ @load ./main @load base/frameworks/cluster -module Pacf; +module NetControl; export { ## This is the event used to transport add_rule calls to the manager. - global cluster_pacf_add_rule: event(r: Rule); + global cluster_netcontrol_add_rule: event(r: Rule); ## This is the event used to transport remove_rule calls to the manager. - global cluster_pacf_remove_rule: event(id: string); + global cluster_netcontrol_remove_rule: event(id: string); } ## Workers need ability to forward commands to manager. -redef Cluster::worker2manager_events += /Pacf::cluster_pacf_(add|remove)_rule/; +redef Cluster::worker2manager_events += /NetControl::cluster_netcontrol_(add|remove)_rule/; ## Workers need to see the result events from the manager. -redef Cluster::manager2worker_events += /Pacf::rule_(added|removed|timeout|error)/; +redef Cluster::manager2worker_events += /NetControl::rule_(added|removed|timeout|error)/; function activate(p: PluginState, priority: int) @@ -37,7 +37,7 @@ function add_rule(r: Rule) : string if ( r$id == "" ) r$id = cat(Cluster::node, ":", ++local_rule_count); - event Pacf::cluster_pacf_add_rule(r); + event NetControl::cluster_netcontrol_add_rule(r); return r$id; } } @@ -48,18 +48,18 @@ function remove_rule(id: string) : bool return remove_rule_impl(id); else { - event Pacf::cluster_pacf_remove_rule(id); + 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 Pacf::cluster_pacf_add_rule(r: Rule) +event NetControl::cluster_netcontrol_add_rule(r: Rule) { add_rule_impl(r); } -event Pacf::cluster_pacf_remove_rule(id: string) +event NetControl::cluster_netcontrol_remove_rule(id: string) { remove_rule_impl(id); } diff --git a/scripts/base/frameworks/pacf/main.bro b/scripts/base/frameworks/netcontrol/main.bro similarity index 96% rename from scripts/base/frameworks/pacf/main.bro rename to scripts/base/frameworks/netcontrol/main.bro index 3ba941e4da..fd32b4ec64 100644 --- a/scripts/base/frameworks/pacf/main.bro +++ b/scripts/base/frameworks/netcontrol/main.bro @@ -10,7 +10,7 @@ ##! provides convinience functions for a set of common operations. The ##! low-level API provides full flexibility. -module Pacf; +module NetControl; @load ./plugin @load ./types @@ -195,7 +195,7 @@ export { ## ignored and not passed on to any plugin. ## ## r: The rule to be added - global Pacf::rule_policy: hook(r: Rule); + global NetControl::rule_policy: hook(r: Rule); ## Type of an entry in the PACF log. type InfoCategory: enum { @@ -242,9 +242,9 @@ export { plugin: string &log &optional; }; - ## Event that can be handled to access the :bro:type:`Pacf::Info` + ## Event that can be handled to access the :bro:type:`NetControl::Info` ## record as it is sent on to the logging framework. - global log_pacf: event(rec: Info); + global log_netcontrol: event(rec: Info); } redef record Rule += { @@ -261,7 +261,7 @@ global id_to_cids: table[string] of set[count]; # id to cid event bro_init() &priority=5 { - Log::create_stream(Pacf::LOG, [$columns=Info, $ev=log_pacf, $path="pacf"]); + Log::create_stream(NetControl::LOG, [$columns=Info, $ev=log_netcontrol, $path="netcontrol"]); } function entity_to_info(info: Info, e: Entity) @@ -394,7 +394,7 @@ function whitelist_subnet(s: subnet, t: interval, location: string &default="") function shunt_flow(f: flow_id, t: interval, location: string &default="") : string { - local flow = Pacf::Flow( + 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), @@ -408,7 +408,7 @@ function shunt_flow(f: flow_id, t: interval, location: string &default="") : str function redirect_flow(f: flow_id, out_port: count, t: interval, location: string &default="") : string { - local flow = Pacf::Flow( + 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), @@ -469,7 +469,7 @@ function add_rule_impl(rule: Rule) : string if ( ! rule?$id || rule$id == "" ) rule$id = cat(rule$cid); - if ( ! hook Pacf::rule_policy(rule) ) + if ( ! hook NetControl::rule_policy(rule) ) return ""; local accepted = F; @@ -514,7 +514,7 @@ function remove_single_rule(id: string, cid: count) : bool { if ( [id,cid] !in rules ) { - Reporter::error(fmt("Rule %s -- %d does not exist in Pacf::remove_single_rule", id, cid)); + Reporter::error(fmt("Rule %s -- %d does not exist in NetControl::remove_single_rule", id, cid)); return F; } @@ -536,7 +536,7 @@ function remove_rule_impl(id: string) : bool { if ( id !in id_to_cids ) { - Reporter::error(fmt("Rule %s does not exist in Pacf::remove_rule", id)); + Reporter::error(fmt("Rule %s does not exist in NetControl::remove_rule", id)); return F; } @@ -547,7 +547,7 @@ function remove_rule_impl(id: string) : bool { if ( [id,cid] !in rules ) { - Reporter::error(fmt("Internal error in pacf::remove_rule - cid %d does not belong to rule %s", cid, id)); + Reporter::error(fmt("Internal error in netcontrol::remove_rule - cid %d does not belong to rule %s", cid, id)); delete cids[cid]; next; } diff --git a/scripts/base/frameworks/pacf/non-cluster.bro b/scripts/base/frameworks/netcontrol/non-cluster.bro similarity index 92% rename from scripts/base/frameworks/pacf/non-cluster.bro rename to scripts/base/frameworks/netcontrol/non-cluster.bro index aa642ca20f..c94e4c9e08 100644 --- a/scripts/base/frameworks/pacf/non-cluster.bro +++ b/scripts/base/frameworks/netcontrol/non-cluster.bro @@ -1,4 +1,4 @@ -module Pacf; +module NetControl; @load ./main diff --git a/scripts/base/frameworks/pacf/plugin.bro b/scripts/base/frameworks/netcontrol/plugin.bro similarity index 99% rename from scripts/base/frameworks/pacf/plugin.bro rename to scripts/base/frameworks/netcontrol/plugin.bro index 501befed76..22a846b977 100644 --- a/scripts/base/frameworks/pacf/plugin.bro +++ b/scripts/base/frameworks/netcontrol/plugin.bro @@ -1,5 +1,5 @@ -module Pacf; +module NetControl; @load ./types diff --git a/scripts/base/frameworks/pacf/plugins/__load__.bro b/scripts/base/frameworks/netcontrol/plugins/__load__.bro similarity index 100% rename from scripts/base/frameworks/pacf/plugins/__load__.bro rename to scripts/base/frameworks/netcontrol/plugins/__load__.bro diff --git a/scripts/base/frameworks/pacf/plugins/acld.bro b/scripts/base/frameworks/netcontrol/plugins/acld.bro similarity index 78% rename from scripts/base/frameworks/pacf/plugins/acld.bro rename to scripts/base/frameworks/netcontrol/plugins/acld.bro index 95d8d5abed..43375cb7ae 100644 --- a/scripts/base/frameworks/pacf/plugins/acld.bro +++ b/scripts/base/frameworks/netcontrol/plugins/acld.bro @@ -1,6 +1,6 @@ -# Acld plugin for the pacf framework. +# Acld plugin for the netcontrol framework. -module Pacf; +module NetControl; @load ../plugin @load base/frameworks/broker @@ -41,9 +41,9 @@ export { global acld_rule_error: event(id: count, r: Rule, msg: string); } -global pacf_acld_topics: set[string] = set(); -global pacf_acld_id: table[count] of PluginState = table(); -global pacf_acld_current_id: count = 0; +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", @@ -58,43 +58,43 @@ const acld_add_to_remove: table[string] of string = { ["nullzero "] ="nonullzero" }; -event Pacf::acld_rule_added(id: count, r: Rule, msg: string) +event NetControl::acld_rule_added(id: count, r: Rule, msg: string) { - if ( id !in pacf_acld_id ) + if ( id !in netcontrol_acld_id ) { - Reporter::error(fmt("Pacf acld plugin with id %d not found, aborting", id)); + Reporter::error(fmt("NetControl acld plugin with id %d not found, aborting", id)); return; } - local p = pacf_acld_id[id]; + local p = netcontrol_acld_id[id]; - event Pacf::rule_added(r, p, msg); + event NetControl::rule_added(r, p, msg); } -event Pacf::acld_rule_removed(id: count, r: Rule, msg: string) +event NetControl::acld_rule_removed(id: count, r: Rule, msg: string) { - if ( id !in pacf_acld_id ) + if ( id !in netcontrol_acld_id ) { - Reporter::error(fmt("Pacf acld plugin with id %d not found, aborting", id)); + Reporter::error(fmt("NetControl acld plugin with id %d not found, aborting", id)); return; } - local p = pacf_acld_id[id]; + local p = netcontrol_acld_id[id]; - event Pacf::rule_removed(r, p, msg); + event NetControl::rule_removed(r, p, msg); } -event Pacf::acld_rule_error(id: count, r: Rule, msg: string) +event NetControl::acld_rule_error(id: count, r: Rule, msg: string) { - if ( id !in pacf_acld_id ) + if ( id !in netcontrol_acld_id ) { - Reporter::error(fmt("Pacf acld plugin with id %d not found, aborting", id)); + Reporter::error(fmt("NetControl acld plugin with id %d not found, aborting", id)); return; } - local p = pacf_acld_id[id]; + local p = netcontrol_acld_id[id]; - event Pacf::rule_error(r, p, msg); + event NetControl::rule_error(r, p, msg); } function acld_name(p: PluginState) : string @@ -215,15 +215,15 @@ global acld_plugin = Plugin( function create_acld(config: AcldConfig) : PluginState { - if ( config$acld_topic in pacf_acld_topics ) - Reporter::warning(fmt("Topic %s was added to Pacf acld plugin twice. Possible duplication of commands", config$acld_topic)); + 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 pacf_acld_topics[config$acld_topic]; + add netcontrol_acld_topics[config$acld_topic]; - local p: PluginState = [$acld_config=config, $plugin=acld_plugin, $acld_id=pacf_acld_current_id]; + local p: PluginState = [$acld_config=config, $plugin=acld_plugin, $acld_id=netcontrol_acld_current_id]; - pacf_acld_id[pacf_acld_current_id] = p; - ++pacf_acld_current_id; + netcontrol_acld_id[netcontrol_acld_current_id] = p; + ++netcontrol_acld_current_id; return p; } diff --git a/scripts/base/frameworks/pacf/plugins/broker.bro b/scripts/base/frameworks/netcontrol/plugins/broker.bro similarity index 56% rename from scripts/base/frameworks/pacf/plugins/broker.bro rename to scripts/base/frameworks/netcontrol/plugins/broker.bro index 0f47641018..959218ca3a 100644 --- a/scripts/base/frameworks/pacf/plugins/broker.bro +++ b/scripts/base/frameworks/netcontrol/plugins/broker.bro @@ -1,8 +1,8 @@ -# Broker plugin for the pacf framework. Sends the raw data structures -# used in pacf on to Broker to allow for easy handling, e.g., of +# 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 Pacf; +module NetControl; @load ../plugin @load base/frameworks/broker @@ -31,60 +31,60 @@ export { global broker_rule_timeout: event(id: count, r: Rule, i: FlowInfo); } -global pacf_broker_topics: set[string] = set(); -global pacf_broker_id: table[count] of PluginState = table(); -global pacf_broker_current_id: count = 0; +global netcontrol_broker_topics: set[string] = set(); +global netcontrol_broker_id: table[count] of PluginState = table(); +global netcontrol_broker_current_id: count = 0; -event Pacf::broker_rule_added(id: count, r: Rule, msg: string) +event NetControl::broker_rule_added(id: count, r: Rule, msg: string) { - if ( id !in pacf_broker_id ) + if ( id !in netcontrol_broker_id ) { - Reporter::error(fmt("Pacf broker plugin with id %d not found, aborting", id)); + Reporter::error(fmt("NetControl broker plugin with id %d not found, aborting", id)); return; } - local p = pacf_broker_id[id]; + local p = netcontrol_broker_id[id]; - event Pacf::rule_added(r, p, msg); + event NetControl::rule_added(r, p, msg); } -event Pacf::broker_rule_removed(id: count, r: Rule, msg: string) +event NetControl::broker_rule_removed(id: count, r: Rule, msg: string) { - if ( id !in pacf_broker_id ) + if ( id !in netcontrol_broker_id ) { - Reporter::error(fmt("Pacf broker plugin with id %d not found, aborting", id)); + Reporter::error(fmt("NetControl broker plugin with id %d not found, aborting", id)); return; } - local p = pacf_broker_id[id]; + local p = netcontrol_broker_id[id]; - event Pacf::rule_removed(r, p, msg); + event NetControl::rule_removed(r, p, msg); } -event Pacf::broker_rule_error(id: count, r: Rule, msg: string) +event NetControl::broker_rule_error(id: count, r: Rule, msg: string) { - if ( id !in pacf_broker_id ) + if ( id !in netcontrol_broker_id ) { - Reporter::error(fmt("Pacf broker plugin with id %d not found, aborting", id)); + Reporter::error(fmt("NetControl broker plugin with id %d not found, aborting", id)); return; } - local p = pacf_broker_id[id]; + local p = netcontrol_broker_id[id]; - event Pacf::rule_error(r, p, msg); + event NetControl::rule_error(r, p, msg); } -event Pacf::broker_rule_timeout(id: count, r: Rule, i: FlowInfo) +event NetControl::broker_rule_timeout(id: count, r: Rule, i: FlowInfo) { - if ( id !in pacf_broker_id ) + if ( id !in netcontrol_broker_id ) { - Reporter::error(fmt("Pacf broker plugin with id %d not found, aborting", id)); + Reporter::error(fmt("NetControl broker plugin with id %d not found, aborting", id)); return; } - local p = pacf_broker_id[id]; + local p = netcontrol_broker_id[id]; - event Pacf::rule_timeout(r, i, p); + event NetControl::rule_timeout(r, i, p); } function broker_name(p: PluginState) : string @@ -129,19 +129,19 @@ global broker_plugin_can_expire = Plugin( function create_broker(host: addr, host_port: port, topic: string, can_expire: bool &default=F) : PluginState { - if ( topic in pacf_broker_topics ) - Reporter::warning(fmt("Topic %s was added to Pacf broker plugin twice. Possible duplication of commands", topic)); + 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 pacf_broker_topics[topic]; + 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=pacf_broker_current_id]; + local p: PluginState = [$broker_host=host, $broker_port=host_port, $plugin=plugin, $broker_topic=topic, $broker_id=netcontrol_broker_current_id]; - pacf_broker_id[pacf_broker_current_id] = p; - ++pacf_broker_current_id; + netcontrol_broker_id[netcontrol_broker_current_id] = p; + ++netcontrol_broker_current_id; return p; } diff --git a/scripts/base/frameworks/pacf/plugins/debug.bro b/scripts/base/frameworks/netcontrol/plugins/debug.bro similarity index 91% rename from scripts/base/frameworks/pacf/plugins/debug.bro rename to scripts/base/frameworks/netcontrol/plugins/debug.bro index f032a22a37..0e42b166c0 100644 --- a/scripts/base/frameworks/pacf/plugins/debug.bro +++ b/scripts/base/frameworks/netcontrol/plugins/debug.bro @@ -1,7 +1,7 @@ @load ../plugin -module Pacf; +module NetControl; export { ## Instantiates a debug plugin for the PACF framework. The debug @@ -24,7 +24,7 @@ function debug_name(p: PluginState) : string function debug_log(p: PluginState, msg: string) { - print fmt("pacf debug (%s): %s", debug_name(p), msg); + print fmt("netcontrol debug (%s): %s", debug_name(p), msg); } function debug_init(p: PluginState) @@ -44,7 +44,7 @@ function debug_add_rule(p: PluginState, r: Rule) : bool if ( do_something(p) ) { - event Pacf::rule_added(r, p); + event NetControl::rule_added(r, p); return T; } @@ -56,7 +56,7 @@ function debug_remove_rule(p: PluginState, r: Rule) : bool local s = fmt("remove_rule: %s", r); debug_log(p, s); - event Pacf::rule_removed(r, p); + event NetControl::rule_removed(r, p); return T; } diff --git a/scripts/base/frameworks/pacf/plugins/openflow.bro b/scripts/base/frameworks/netcontrol/plugins/openflow.bro similarity index 93% rename from scripts/base/frameworks/pacf/plugins/openflow.bro rename to scripts/base/frameworks/netcontrol/plugins/openflow.bro index 3a28a36dfe..6628e5e579 100644 --- a/scripts/base/frameworks/pacf/plugins/openflow.bro +++ b/scripts/base/frameworks/netcontrol/plugins/openflow.bro @@ -1,7 +1,7 @@ @load ../plugin @load base/frameworks/openflow -module Pacf; +module NetControl; export { type OfConfig: record { @@ -9,7 +9,7 @@ export { 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 pacf priorities without having to write a filter function. + 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. check_pred: function(p: PluginState, r: Rule): bool &optional &weaken; match_pred: function(p: PluginState, e: Entity, m: vector of OpenFlow::ofp_match): vector of OpenFlow::ofp_match &optional &weaken; @@ -17,7 +17,7 @@ export { }; redef record PluginState += { - ## OpenFlow controller for Pacf OpenFlow plugin + ## OpenFlow controller for NetControl OpenFlow plugin of_controller: OpenFlow::Controller &optional; ## OpenFlow configuration record that is passed on initialization of_config: OfConfig &optional; @@ -54,7 +54,7 @@ global of_messages: table[count, OpenFlow::ofp_flow_mod_command] of OfTable &cre local p = t[rid, command]$p; local r = t[rid, command]$r; - event Pacf::rule_error(r, p, "Timeout during rule insertion/removal"); + event NetControl::rule_error(r, p, "Timeout during rule insertion/removal"); return 0secs; }; @@ -341,9 +341,9 @@ event OpenFlow::flow_mod_success(match: OpenFlow::ofp_match, flow_mod: OpenFlow: of_flows[id] = OfTable($p=p, $r=r); if ( flow_mod$command == OpenFlow::OFPFC_ADD ) - event Pacf::rule_added(r, p, msg); + event NetControl::rule_added(r, p, msg); else if ( flow_mod$command == OpenFlow::OFPFC_DELETE || flow_mod$command == OpenFlow::OFPFC_DELETE_STRICT ) - event Pacf::rule_removed(r, p, msg); + event NetControl::rule_removed(r, p, msg); } event OpenFlow::flow_mod_failure(match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) &priority=3 @@ -356,7 +356,7 @@ event OpenFlow::flow_mod_failure(match: OpenFlow::ofp_match, flow_mod: OpenFlow: local p = of_messages[id,flow_mod$command]$p; delete of_messages[id,flow_mod$command]; - event Pacf::rule_error(r, p, msg); + event NetControl::rule_error(r, p, msg); } event OpenFlow::flow_removed(match: OpenFlow::ofp_match, cookie: count, priority: count, reason: count, duration_sec: count, idle_timeout: count, packet_count: count, byte_count: count) @@ -375,12 +375,12 @@ event OpenFlow::flow_removed(match: OpenFlow::ofp_match, cookie: count, priority if ( of_flows[id]$c < 2 ) return; # will do stuff once the second part arrives... else - event Pacf::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); + 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 Pacf::rule_timeout(r, FlowInfo($duration=double_to_interval(duration_sec+0.0), $packet_count=packet_count, $byte_count=byte_count), p); + event NetControl::rule_timeout(r, FlowInfo($duration=double_to_interval(duration_sec+0.0), $packet_count=packet_count, $byte_count=byte_count), p); } global openflow_plugin = Plugin( diff --git a/scripts/base/frameworks/pacf/plugins/packetfilter.bro b/scripts/base/frameworks/netcontrol/plugins/packetfilter.bro similarity index 99% rename from scripts/base/frameworks/pacf/plugins/packetfilter.bro rename to scripts/base/frameworks/netcontrol/plugins/packetfilter.bro index d2f2841790..2c532e4009 100644 --- a/scripts/base/frameworks/pacf/plugins/packetfilter.bro +++ b/scripts/base/frameworks/netcontrol/plugins/packetfilter.bro @@ -3,7 +3,7 @@ # and can only add/remove filters for addresses, this is quite # limited in scope at the moment. -module Pacf; +module NetControl; @load ../plugin diff --git a/scripts/base/frameworks/pacf/types.bro b/scripts/base/frameworks/netcontrol/types.bro similarity index 99% rename from scripts/base/frameworks/pacf/types.bro rename to scripts/base/frameworks/netcontrol/types.bro index fc15323e1b..cb130c291b 100644 --- a/scripts/base/frameworks/pacf/types.bro +++ b/scripts/base/frameworks/netcontrol/types.bro @@ -1,5 +1,5 @@ -module Pacf; +module NetControl; export { const default_priority: int = +0 &redef; diff --git a/scripts/base/init-default.bro b/scripts/base/init-default.bro index 0fee22aded..7fefe0111d 100644 --- a/scripts/base/init-default.bro +++ b/scripts/base/init-default.bro @@ -38,7 +38,7 @@ @load base/frameworks/sumstats @load base/frameworks/tunnels @load base/frameworks/openflow -@load base/frameworks/pacf +@load base/frameworks/netcontrol @load base/protocols/conn @load base/protocols/dhcp 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..db2859c4b5 --- /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::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=, dst_h=74.53.140.153/32, dst_p=, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1], [command=blockhosthost, cookie=2, arg=10.10.1.4 74.53.140.153, comment=here] +add_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1], [command=droptcpport, cookie=3, arg=25, comment=here] +add_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1], [command=drop, cookie=4, arg=10.10.1.4/32, comment=] +remove_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=, dst_h=74.53.140.153/32, dst_p=, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1], [command=restorehosthost, cookie=2, arg=10.10.1.4 74.53.140.153, comment=here] +remove_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1], [command=restoretcpport, cookie=3, arg=25, comment=here] +remove_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1], [command=restore, cookie=4, arg=10.10.1.4/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..b823dd0aee --- /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::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=, dst_h=74.53.140.153/32, dst_p=, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] +rule added, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] +rule added, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1] +rule removed, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=, dst_h=74.53.140.153/32, dst_p=, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] +rule removed, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] +rule removed, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1] 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..2007630489 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/manager-1.netcontrol.log @@ -0,0 +1,32 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2015-07-08-19-33-09 +#fields ts category cmd state action target entity_type entity msg location plugin +#types time enum string enum string enum string string string string string +1436383989.876677 NetControl::MESSAGE - - - - - - activated plugin with priority 0 - Debug-All +1436383992.255152 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1436383992.255152 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1436383992.255152 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1436383992.255152 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1436383994.376366 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1436383994.376366 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1436383994.376366 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1436383994.376366 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1436383991.768500 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1436383991.768500 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1436383993.849722 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1436383993.849722 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1436383993.813850 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1436383993.813850 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1436384002.162435 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1436384002.162435 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1436384002.162435 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1436384002.162435 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1436384002.162435 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1436384002.162435 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1436384002.162435 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1436384002.162435 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +#close 2015-07-08-19-33-22 diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic-cluster/worker-1..stdout b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/worker-1..stdout similarity index 100% rename from testing/btest/Baseline/scripts.base.frameworks.pacf.basic-cluster/worker-1..stdout rename to testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/worker-1..stdout diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic-cluster/worker-2..stdout b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/worker-2..stdout similarity index 100% rename from testing/btest/Baseline/scripts.base.frameworks.pacf.basic-cluster/worker-2..stdout rename to testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/worker-2..stdout 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..0964f600f4 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/.stdout @@ -0,0 +1,9 @@ +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=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=], expire=30.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::WHITELIST, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=5, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::REDIRECT, target=NetControl::FORWARD, entity=[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=], expire=30.0 secs, priority=0, location=, c=5, i=, d=, s=, mod=, id=5, cid=5, _plugin_id=1] +netcontrol debug (Debug-All): remove_rule: [ty=NetControl::WHITELIST, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=5, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1] +netcontrol debug (Debug-All): remove_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] +netcontrol debug (Debug-All): remove_rule: [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[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=], expire=30.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] +netcontrol debug (Debug-All): remove_rule: [ty=NetControl::REDIRECT, target=NetControl::FORWARD, entity=[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=], expire=30.0 secs, priority=0, location=, c=5, i=, d=, s=, mod=, id=5, cid=5, _plugin_id=1] 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..379eb0845b --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol.log @@ -0,0 +1,26 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path pacf +#open 2015-06-01-22-57-07 +#fields ts category cmd state action target entity_type entity msg location plugin +#types time enum string enum string enum string string string string string +0.000000 NetControl::MESSAGE - - - - - - activated plugin with priority 0 - Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +#close 2015-06-01-22-57-07 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..1d97db6024 --- /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::DROP, target=NetControl::MONITOR, entity=[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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] +add_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] +remove_rule, 0, [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] +remove_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] 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..826819877b --- /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::DROP, target=NetControl::MONITOR, entity=[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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] +rule added, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] +rule timeout, [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1], [duration=, packet_count=, byte_count=] +rule removed, [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] +rule timeout, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1], [duration=, packet_count=, byte_count=] +rule removed, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.catch-and-release/.stdout b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.catch-and-release/.stdout new file mode 100644 index 0000000000..2570a5edc1 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.catch-and-release/.stdout @@ -0,0 +1,11 @@ +netcontrol debug (Debug-All): init +netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=10.0 mins, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=1.0 hr, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=1.0 day, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=7.0 days, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=5, cid=5, _plugin_id=1] +netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=7.0 days, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=6, cid=6, _plugin_id=1] +netcontrol debug (Debug-All): remove_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=10.0 mins, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] +netcontrol debug (Debug-All): remove_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=1.0 hr, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] +netcontrol debug (Debug-All): remove_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=1.0 day, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1] +netcontrol debug (Debug-All): remove_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=7.0 days, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=6, cid=6, _plugin_id=1] +netcontrol debug (Debug-All): remove_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=7.0 days, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=5, cid=5, _plugin_id=1] 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..dff4c85769 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.catch-and-release/netcontrol.log @@ -0,0 +1,30 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path pacf +#open 2015-06-02-22-02-42 +#fields ts category cmd state action target entity_type entity msg location plugin +#types time enum string enum string enum string string string string string +0.000000 NetControl::MESSAGE - - - - - - activated plugin with priority 0 - Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All +#close 2015-06-02-22-02-42 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..2f39a2623f --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.hook/netcontrol.log @@ -0,0 +1,18 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2015-07-08-19-33-47 +#fields ts category cmd state action target entity_type entity msg location plugin +#types time enum string enum string enum string string string string string +0.000000 NetControl::MESSAGE - - - - - - activated plugin with priority 0 - Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All +#close 2015-07-08-19-33-48 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..f2d13a8251 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/netcontrol.log @@ -0,0 +1,36 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path pacf +#open 2015-06-02-19-34-04 +#fields ts category cmd state action target entity_type entity msg location plugin +#types time enum string enum string enum string string string string string +0.000000 NetControl::MESSAGE - - - - - - activated plugin with priority 10 - Debug-All +0.000000 NetControl::MESSAGE - - - - - - activated plugin with priority 10 - Openflow - OpenFlog Log Plugin - DPID 42 +0.000000 NetControl::MESSAGE - - - - - - activated plugin with priority 0 - Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All +#close 2015-06-02-19-34-04 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..12daa37c03 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/netcontrol.log @@ -0,0 +1,14 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2015-07-08-19-33-52 +#fields ts category cmd state action target entity_type entity msg location plugin +#types time enum string enum string enum string string string string string +0.000000 NetControl::MESSAGE - - - - - - activated plugin with priority 0 - Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +#close 2015-07-08-19-33-52 diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/openflow.log similarity index 100% rename from testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/openflow.log rename to testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/openflow.log diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.packetfilter/conn.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.packetfilter/conn.log similarity index 100% rename from testing/btest/Baseline/scripts.base.frameworks.pacf.packetfilter/conn.log rename to testing/btest/Baseline/scripts.base.frameworks.netcontrol.packetfilter/conn.log 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..74f45e41ec --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.quarantine-openflow/netcontrol.log @@ -0,0 +1,18 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2015-07-08-19-33-55 +#fields ts category cmd state action target entity_type entity msg location plugin +#types time enum string enum string enum string string string string string +0.000000 NetControl::MESSAGE - - - - - - activated plugin with priority 0 - Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/*->*/* - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::MODIFY NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/*->8.8.8.8/32/53 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::MODIFY NetControl::FORWARD NetControl::FLOW 8.8.8.8/32/53->10.10.1.4/32/* - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/*->192.169.18.1/32/80 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/*->*/* - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::MODIFY NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/*->8.8.8.8/32/53 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::MODIFY NetControl::FORWARD NetControl::FLOW 8.8.8.8/32/53->10.10.1.4/32/* - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/*->192.169.18.1/32/80 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +#close 2015-07-08-19-33-55 diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.quarantine-openflow/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.quarantine-openflow/openflow.log similarity index 100% rename from testing/btest/Baseline/scripts.base.frameworks.pacf.quarantine-openflow/openflow.log rename to testing/btest/Baseline/scripts.base.frameworks.netcontrol.quarantine-openflow/openflow.log diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.acld/recv.recv.out b/testing/btest/Baseline/scripts.base.frameworks.pacf.acld/recv.recv.out deleted file mode 100644 index ad604ec09f..0000000000 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.acld/recv.recv.out +++ /dev/null @@ -1,7 +0,0 @@ -BrokerComm::incoming_connection_established -add_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=, dst_h=74.53.140.153/32, dst_p=, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1], [command=blockhosthost, cookie=2, arg=10.10.1.4 74.53.140.153, comment=here] -add_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1], [command=droptcpport, cookie=3, arg=25, comment=here] -add_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1], [command=drop, cookie=4, arg=10.10.1.4/32, comment=] -remove_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=, dst_h=74.53.140.153/32, dst_p=, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1], [command=restorehosthost, cookie=2, arg=10.10.1.4 74.53.140.153, comment=here] -remove_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1], [command=restoretcpport, cookie=3, arg=25, comment=here] -remove_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1], [command=restore, cookie=4, arg=10.10.1.4/32, comment=] diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.acld/send.send.out b/testing/btest/Baseline/scripts.base.frameworks.pacf.acld/send.send.out deleted file mode 100644 index 1f7e952357..0000000000 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.acld/send.send.out +++ /dev/null @@ -1,7 +0,0 @@ -BrokerComm::outgoing_connection_established, 127.0.0.1, 9999/tcp -rule added, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=, dst_h=74.53.140.153/32, dst_p=, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] -rule added, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] -rule added, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1] -rule removed, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=, dst_h=74.53.140.153/32, dst_p=, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] -rule removed, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] -rule removed, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1] diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic-cluster/manager-1.pacf.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic-cluster/manager-1.pacf.log deleted file mode 100644 index 81fecc2fd3..0000000000 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic-cluster/manager-1.pacf.log +++ /dev/null @@ -1,32 +0,0 @@ -#separator \x09 -#set_separator , -#empty_field (empty) -#unset_field - -#path pacf -#open 2015-05-28-00-59-14 -#fields ts category cmd state action target entity_type entity msg location plugin -#types time enum string enum string enum string string string string string -1432774754.087659 Pacf::MESSAGE - - - - - - activated plugin with priority 0 - Debug-All -1432774756.519062 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1432774756.519062 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1432774756.519062 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1432774756.519062 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1432774758.581184 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1432774758.581184 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1432774758.581184 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1432774758.581184 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1432774756.036263 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1432774756.036263 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1432774757.774649 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1432774757.774649 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1432774758.070948 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1432774758.070948 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1432774766.388890 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1432774766.388890 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1432774766.388890 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1432774766.388890 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1432774766.388890 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1432774766.388890 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1432774766.388890 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1432774766.388890 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -#close 2015-05-28-00-59-26 diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout deleted file mode 100644 index b0a30033d0..0000000000 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/.stdout +++ /dev/null @@ -1,9 +0,0 @@ -pacf debug (Debug-All): init -pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] -pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] -pacf debug (Debug-All): add_rule: [ty=Pacf::WHITELIST, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=5, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1] -pacf debug (Debug-All): add_rule: [ty=Pacf::REDIRECT, target=Pacf::FORWARD, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, c=5, i=, d=, s=, mod=, id=5, cid=5, _plugin_id=1] -pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] -pacf debug (Debug-All): remove_rule: [ty=Pacf::WHITELIST, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=5, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1] -pacf debug (Debug-All): remove_rule: [ty=Pacf::REDIRECT, target=Pacf::FORWARD, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, c=5, i=, d=, s=, mod=, id=5, cid=5, _plugin_id=1] -pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=30.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/pacf.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/pacf.log deleted file mode 100644 index 28d5a8c9d8..0000000000 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.basic/pacf.log +++ /dev/null @@ -1,26 +0,0 @@ -#separator \x09 -#set_separator , -#empty_field (empty) -#unset_field - -#path pacf -#open 2015-06-01-22-57-07 -#fields ts category cmd state action target entity_type entity msg location plugin -#types time enum string enum string enum string string string string string -0.000000 Pacf::MESSAGE - - - - - - activated plugin with priority 0 - Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::WHITELIST Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::WHITELIST Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::WHITELIST Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::WHITELIST Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -#close 2015-06-01-22-57-07 diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/recv.recv.out b/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/recv.recv.out deleted file mode 100644 index 2d4118e6f2..0000000000 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/recv.recv.out +++ /dev/null @@ -1,5 +0,0 @@ -BrokerComm::incoming_connection_established -add_rule, 0, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] -add_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] -remove_rule, 0, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] -remove_rule, 0, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/send.send.out b/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/send.send.out deleted file mode 100644 index c1da86ad6e..0000000000 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.broker/send.send.out +++ /dev/null @@ -1,7 +0,0 @@ -BrokerComm::outgoing_connection_established, 127.0.0.1, 9999/tcp -rule added, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] -rule added, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] -rule timeout, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1], [duration=, packet_count=, byte_count=] -rule removed, [ty=Pacf::DROP, target=Pacf::MONITOR, entity=[ty=Pacf::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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] -rule timeout, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1], [duration=, packet_count=, byte_count=] -rule removed, [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.catch-and-release/.stdout b/testing/btest/Baseline/scripts.base.frameworks.pacf.catch-and-release/.stdout deleted file mode 100644 index d7f55a9556..0000000000 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.catch-and-release/.stdout +++ /dev/null @@ -1,11 +0,0 @@ -pacf debug (Debug-All): init -pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=10.0 mins, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] -pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=1.0 hr, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] -pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=1.0 day, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1] -pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=7.0 days, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=5, cid=5, _plugin_id=1] -pacf debug (Debug-All): add_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=7.0 days, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=6, cid=6, _plugin_id=1] -pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=10.0 mins, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] -pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=1.0 hr, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] -pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=1.0 day, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1] -pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=7.0 days, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=6, cid=6, _plugin_id=1] -pacf debug (Debug-All): remove_rule: [ty=Pacf::DROP, target=Pacf::FORWARD, entity=[ty=Pacf::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=7.0 days, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=5, cid=5, _plugin_id=1] diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.catch-and-release/pacf.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.catch-and-release/pacf.log deleted file mode 100644 index 31a7c7dff4..0000000000 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.catch-and-release/pacf.log +++ /dev/null @@ -1,30 +0,0 @@ -#separator \x09 -#set_separator , -#empty_field (empty) -#unset_field - -#path pacf -#open 2015-06-02-22-02-42 -#fields ts category cmd state action target entity_type entity msg location plugin -#types time enum string enum string enum string string string string string -0.000000 Pacf::MESSAGE - - - - - - activated plugin with priority 0 - Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -#close 2015-06-02-22-02-42 diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.hook/pacf.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.hook/pacf.log deleted file mode 100644 index 1725aa4918..0000000000 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.hook/pacf.log +++ /dev/null @@ -1,18 +0,0 @@ -#separator \x09 -#set_separator , -#empty_field (empty) -#unset_field - -#path pacf -#open 2015-06-02-21-23-05 -#fields ts category cmd state action target entity_type entity msg location plugin -#types time enum string enum string enum string string string string string -0.000000 Pacf::MESSAGE - - - - - - activated plugin with priority 0 - Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All -#close 2015-06-02-21-23-05 diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.multiple/pacf.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.multiple/pacf.log deleted file mode 100644 index 588c014285..0000000000 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.multiple/pacf.log +++ /dev/null @@ -1,36 +0,0 @@ -#separator \x09 -#set_separator , -#empty_field (empty) -#unset_field - -#path pacf -#open 2015-06-02-19-34-04 -#fields ts category cmd state action target entity_type entity msg location plugin -#types time enum string enum string enum string string string string string -0.000000 Pacf::MESSAGE - - - - - - activated plugin with priority 10 - Debug-All -0.000000 Pacf::MESSAGE - - - - - - activated plugin with priority 10 - Openflow - OpenFlog Log Plugin - DPID 42 -0.000000 Pacf::MESSAGE - - - - - - activated plugin with priority 0 - Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::WHITELIST Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::WHITELIST Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::WHITELIST Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::WHITELIST Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::WHITELIST Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::WHITELIST Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::REDIRECT Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722776.690444 Pacf::RULE REMOVE Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -#close 2015-06-02-19-34-04 diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/pacf.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/pacf.log deleted file mode 100644 index aa97127528..0000000000 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.openflow/pacf.log +++ /dev/null @@ -1,14 +0,0 @@ -#separator \x09 -#set_separator , -#empty_field (empty) -#unset_field - -#path pacf -#open 2015-05-15-18-21-40 -#fields ts category cmd state action target entity_type entity msg location plugin -#types time enum string enum string enum string string string string string -0.000000 Pacf::MESSAGE - - - - - - activated plugin with priority 0 - Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::MONITOR Pacf::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -#close 2015-05-15-18-21-40 diff --git a/testing/btest/Baseline/scripts.base.frameworks.pacf.quarantine-openflow/pacf.log b/testing/btest/Baseline/scripts.base.frameworks.pacf.quarantine-openflow/pacf.log deleted file mode 100644 index 0bcb99fd48..0000000000 --- a/testing/btest/Baseline/scripts.base.frameworks.pacf.quarantine-openflow/pacf.log +++ /dev/null @@ -1,18 +0,0 @@ -#separator \x09 -#set_separator , -#empty_field (empty) -#unset_field - -#path pacf -#open 2015-06-04-23-18-56 -#fields ts category cmd state action target entity_type entity msg location plugin -#types time enum string enum string enum string string string string string -0.000000 Pacf::MESSAGE - - - - - - activated plugin with priority 0 - Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::DROP Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/*->*/* - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::MODIFY Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/*->8.8.8.8/32/53 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::MODIFY Pacf::FORWARD Pacf::FLOW 8.8.8.8/32/53->10.10.1.4/32/* - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 Pacf::RULE ADD Pacf::REQUESTED Pacf::WHITELIST Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/*->192.169.18.1/32/80 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::DROP Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/*->*/* - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::MODIFY Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/*->8.8.8.8/32/53 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::MODIFY Pacf::FORWARD Pacf::FLOW 8.8.8.8/32/53->10.10.1.4/32/* - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 Pacf::RULE ADD Pacf::SUCCEEDED Pacf::WHITELIST Pacf::FORWARD Pacf::FLOW 10.10.1.4/32/*->192.169.18.1/32/80 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -#close 2015-06-04-23-18-56 diff --git a/testing/btest/scripts/base/frameworks/pacf/acld.bro b/testing/btest/scripts/base/frameworks/netcontrol/acld.bro similarity index 53% rename from testing/btest/scripts/base/frameworks/pacf/acld.bro rename to testing/btest/scripts/base/frameworks/netcontrol/acld.bro index bf10138a6a..c6aabfd2a2 100644 --- a/testing/btest/scripts/base/frameworks/pacf/acld.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/acld.bro @@ -9,7 +9,7 @@ @TEST-START-FILE send.bro -@load base/frameworks/pacf +@load base/frameworks/netcontrol const broker_port: port &redef; redef exit_only_after_terminate = T; @@ -17,8 +17,8 @@ redef exit_only_after_terminate = T; event bro_init() { suspend_processing(); - local pacf_acld = Pacf::create_acld(Pacf::AcldConfig($acld_host=127.0.0.1, $acld_port=broker_port, $acld_topic="bro/event/pacftest")); - Pacf::activate(pacf_acld, 0); + 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, @@ -39,31 +39,31 @@ event connection_established(c: connection) { local id = c$id; - local flow1 = Pacf::Flow( + local flow1 = NetControl::Flow( $src_h=addr_to_subnet(c$id$orig_h), $dst_h=addr_to_subnet(c$id$resp_h) ); - local e1: Pacf::Entity = [$ty=Pacf::FLOW, $flow=flow1]; - local r1: Pacf::Rule = [$ty=Pacf::DROP, $target=Pacf::FORWARD, $entity=e1, $expire=10hrs, $location="here"]; + 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 = Pacf::Flow( + local flow2 = NetControl::Flow( $dst_p=c$id$resp_p ); - local e2: Pacf::Entity = [$ty=Pacf::FLOW, $flow=flow2]; - local r2: Pacf::Rule = [$ty=Pacf::DROP, $target=Pacf::FORWARD, $entity=e2, $expire=10hrs, $location="here"]; + local e2: NetControl::Entity = [$ty=NetControl::FLOW, $flow=flow2]; + local r2: NetControl::Rule = [$ty=NetControl::DROP, $target=NetControl::FORWARD, $entity=e2, $expire=10hrs, $location="here"]; - Pacf::add_rule(r1); - Pacf::add_rule(r2); - Pacf::drop_address(id$orig_h, 10hrs); + NetControl::add_rule(r1); + NetControl::add_rule(r2); + NetControl::drop_address(id$orig_h, 10hrs); } -event Pacf::rule_added(r: Pacf::Rule, p: Pacf::PluginState, msg: string) +event NetControl::rule_added(r: NetControl::Rule, p: NetControl::PluginState, msg: string) { print "rule added", r; - Pacf::remove_rule(r$id); + NetControl::remove_rule(r$id); } -event Pacf::rule_removed(r: Pacf::Rule, p: Pacf::PluginState, msg: string) +event NetControl::rule_removed(r: NetControl::Rule, p: NetControl::PluginState, msg: string) { print "rule removed", r; } @@ -72,7 +72,7 @@ event Pacf::rule_removed(r: Pacf::Rule, p: Pacf::PluginState, msg: string) @TEST-START-FILE recv.bro -@load base/frameworks/pacf +@load base/frameworks/netcontrol @load base/frameworks/broker const broker_port: port &redef; @@ -81,7 +81,7 @@ redef exit_only_after_terminate = T; event bro_init() { BrokerComm::enable(); - BrokerComm::subscribe_to_events("bro/event/pacftest"); + BrokerComm::subscribe_to_events("bro/event/netcontroltest"); BrokerComm::listen(broker_port, "127.0.0.1"); } @@ -90,18 +90,18 @@ event BrokerComm::incoming_connection_established(peer_name: string) print "BrokerComm::incoming_connection_established"; } -event Pacf::acld_add_rule(id: count, r: Pacf::Rule, ar: Pacf::AclRule) +event NetControl::acld_add_rule(id: count, r: NetControl::Rule, ar: NetControl::AclRule) { print "add_rule", id, r, ar; - BrokerComm::event("bro/event/pacftest", BrokerComm::event_args(Pacf::acld_rule_added, id, r, ar$command)); + BrokerComm::event("bro/event/netcontroltest", BrokerComm::event_args(NetControl::acld_rule_added, id, r, ar$command)); } -event Pacf::acld_remove_rule(id: count, r: Pacf::Rule, ar: Pacf::AclRule) +event NetControl::acld_remove_rule(id: count, r: NetControl::Rule, ar: NetControl::AclRule) { print "remove_rule", id, r, ar; - BrokerComm::event("bro/event/pacftest", BrokerComm::event_args(Pacf::acld_rule_removed, id, r, ar$command)); + BrokerComm::event("bro/event/netcontroltest", BrokerComm::event_args(NetControl::acld_rule_removed, id, r, ar$command)); if ( r$cid == 4 ) terminate(); diff --git a/testing/btest/scripts/base/frameworks/pacf/basic-cluster.bro b/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro similarity index 75% rename from testing/btest/scripts/base/frameworks/pacf/basic-cluster.bro rename to testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro index 73be268394..3047416bac 100644 --- a/testing/btest/scripts/base/frameworks/pacf/basic-cluster.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro @@ -6,7 +6,7 @@ # @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/smtp.trace %INPUT" # @TEST-EXEC: btest-bg-wait 20 -# @TEST-EXEC: btest-diff manager-1/pacf.log +# @TEST-EXEC: btest-diff manager-1/netcontrol.log # @TEST-EXEC: btest-diff worker-1/.stdout # @TEST-EXEC: btest-diff worker-2/.stdout @@ -21,19 +21,19 @@ redef Cluster::nodes = { redef Log::default_rotation_interval = 0secs; #redef exit_only_after_terminate = T; -@load base/frameworks/pacf +@load base/frameworks/netcontrol event bro_init() { - local pacf_debug = Pacf::create_debug(T); - Pacf::activate(pacf_debug, 0); + local netcontrol_debug = NetControl::create_debug(T); + NetControl::activate(netcontrol_debug, 0); } event connection_established(c: connection) { local id = c$id; - Pacf::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 30sec); - Pacf::drop_address(id$orig_h, 15sec); + 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); } event terminate_me() { @@ -44,7 +44,7 @@ event remote_connection_closed(p: event_peer) { schedule 1sec { terminate_me() }; } -event Pacf::rule_added(r: Pacf::Rule, p: Pacf::PluginState, msg: string &default="") +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..f1f63b3d99 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/basic.bro @@ -0,0 +1,20 @@ +# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT +# @TEST-EXEC: TEST_DIFF_CANONIFIER='grep -v ^# | $SCRIPTS/diff-sort' btest-diff netcontrol.log +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff .stdout + +@load base/frameworks/netcontrol + +event bro_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); + } diff --git a/testing/btest/scripts/base/frameworks/pacf/broker.bro b/testing/btest/scripts/base/frameworks/netcontrol/broker.bro similarity index 57% rename from testing/btest/scripts/base/frameworks/pacf/broker.bro rename to testing/btest/scripts/base/frameworks/netcontrol/broker.bro index 9e5caa8864..f675a0fd13 100644 --- a/testing/btest/scripts/base/frameworks/pacf/broker.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/broker.bro @@ -9,7 +9,7 @@ @TEST-START-FILE send.bro -@load base/frameworks/pacf +@load base/frameworks/netcontrol const broker_port: port &redef; redef exit_only_after_terminate = T; @@ -17,8 +17,8 @@ redef exit_only_after_terminate = T; event bro_init() { suspend_processing(); - local pacf_broker = Pacf::create_broker(127.0.0.1, broker_port, "bro/event/pacftest", T); - Pacf::activate(pacf_broker, 0); + local netcontrol_broker = NetControl::create_broker(127.0.0.1, broker_port, "bro/event/netcontroltest", T); + NetControl::activate(netcontrol_broker, 0); } event BrokerComm::outgoing_connection_established(peer_address: string, @@ -38,22 +38,22 @@ event BrokerComm::outgoing_connection_broken(peer_address: string, event connection_established(c: connection) { local id = c$id; - Pacf::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 10hrs); - Pacf::drop_address(id$orig_h, 10hrs); + 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 Pacf::rule_added(r: Pacf::Rule, p: Pacf::PluginState, msg: string) +event NetControl::rule_added(r: NetControl::Rule, p: NetControl::PluginState, msg: string) { print "rule added", r; - Pacf::remove_rule(r$id); + NetControl::remove_rule(r$id); } -event Pacf::rule_removed(r: Pacf::Rule, p: Pacf::PluginState, msg: string) +event NetControl::rule_removed(r: NetControl::Rule, p: NetControl::PluginState, msg: string) { print "rule removed", r; } -event Pacf::rule_timeout(r: Pacf::Rule, i: Pacf::FlowInfo, p: Pacf::PluginState) +event NetControl::rule_timeout(r: NetControl::Rule, i: NetControl::FlowInfo, p: NetControl::PluginState) { print "rule timeout", r, i; } @@ -62,7 +62,7 @@ event Pacf::rule_timeout(r: Pacf::Rule, i: Pacf::FlowInfo, p: Pacf::PluginState) @TEST-START-FILE recv.bro -@load base/frameworks/pacf +@load base/frameworks/netcontrol @load base/frameworks/broker const broker_port: port &redef; @@ -71,7 +71,7 @@ redef exit_only_after_terminate = T; event bro_init() { BrokerComm::enable(); - BrokerComm::subscribe_to_events("bro/event/pacftest"); + BrokerComm::subscribe_to_events("bro/event/netcontroltest"); BrokerComm::listen(broker_port, "127.0.0.1"); } @@ -80,19 +80,19 @@ event BrokerComm::incoming_connection_established(peer_name: string) print "BrokerComm::incoming_connection_established"; } -event Pacf::broker_add_rule(id: count, r: Pacf::Rule) +event NetControl::broker_add_rule(id: count, r: NetControl::Rule) { print "add_rule", id, r; - BrokerComm::event("bro/event/pacftest", BrokerComm::event_args(Pacf::broker_rule_added, id, r, "")); + BrokerComm::event("bro/event/netcontroltest", BrokerComm::event_args(NetControl::broker_rule_added, id, r, "")); } -event Pacf::broker_remove_rule(id: count, r: Pacf::Rule) +event NetControl::broker_remove_rule(id: count, r: NetControl::Rule) { print "remove_rule", id, r; - BrokerComm::event("bro/event/pacftest", BrokerComm::event_args(Pacf::broker_rule_timeout, id, r, Pacf::FlowInfo())); - BrokerComm::event("bro/event/pacftest", BrokerComm::event_args(Pacf::broker_rule_removed, id, r, "")); + 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(); diff --git a/testing/btest/scripts/base/frameworks/pacf/catch-and-release.bro b/testing/btest/scripts/base/frameworks/netcontrol/catch-and-release.bro similarity index 68% rename from testing/btest/scripts/base/frameworks/pacf/catch-and-release.bro rename to testing/btest/scripts/base/frameworks/netcontrol/catch-and-release.bro index df6850ac3d..e5ce73410f 100644 --- a/testing/btest/scripts/base/frameworks/pacf/catch-and-release.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/catch-and-release.bro @@ -1,23 +1,23 @@ # @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT -# @TEST-EXEC: TEST_DIFF_CANONIFIER='grep -v ^# | $SCRIPTS/diff-sort' btest-diff pacf.log +# @TEST-EXEC: TEST_DIFF_CANONIFIER='grep -v ^# | $SCRIPTS/diff-sort' btest-diff netcontrol.log # @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff .stdout -@load base/frameworks/pacf +@load base/frameworks/netcontrol event bro_init() { - local pacf_debug = Pacf::create_debug(T); - Pacf::activate(pacf_debug, 0); + local netcontrol_debug = NetControl::create_debug(T); + NetControl::activate(netcontrol_debug, 0); } -module Pacf; +module NetControl; event connection_established(c: connection) { local id = c$id; - Pacf::drop_address_catch_release(id$orig_h); + NetControl::drop_address_catch_release(id$orig_h); # second one should be ignored because duplicate - Pacf::drop_address_catch_release(id$orig_h); + NetControl::drop_address_catch_release(id$orig_h); # mean call directly into framework - simulate new connection delete current_blocks[id$orig_h]; 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..d859f8a089 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/hook.bro @@ -0,0 +1,27 @@ +# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT +# @TEST-EXEC: btest-diff netcontrol.log + +@load base/frameworks/netcontrol + +event bro_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..d8676c07ab --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/multiple.bro @@ -0,0 +1,24 @@ +# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT +# @TEST-EXEC: TEST_DIFF_CANONIFIER='grep -v ^# | $SCRIPTS/diff-sort' btest-diff netcontrol.log + +@load base/frameworks/netcontrol + +event bro_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 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); + } 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..36d3b9bfdb --- /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 bro_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$orig_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..7ccb9dde5c --- /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 bro_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..ced53f441e --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/quarantine-openflow.bro @@ -0,0 +1,19 @@ +# @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 bro_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/pacf/basic.bro b/testing/btest/scripts/base/frameworks/pacf/basic.bro deleted file mode 100644 index 0684daaecd..0000000000 --- a/testing/btest/scripts/base/frameworks/pacf/basic.bro +++ /dev/null @@ -1,20 +0,0 @@ -# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT -# @TEST-EXEC: TEST_DIFF_CANONIFIER='grep -v ^# | $SCRIPTS/diff-sort' btest-diff pacf.log -# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff .stdout - -@load base/frameworks/pacf - -event bro_init() - { - local pacf_debug = Pacf::create_debug(T); - Pacf::activate(pacf_debug, 0); - } - -event connection_established(c: connection) - { - local id = c$id; - Pacf::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 30sec); - Pacf::drop_address(id$orig_h, 15sec); - Pacf::whitelist_address(id$orig_h, 15sec); - Pacf::redirect_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 5, 30sec); - } diff --git a/testing/btest/scripts/base/frameworks/pacf/hook.bro b/testing/btest/scripts/base/frameworks/pacf/hook.bro deleted file mode 100644 index e31237d934..0000000000 --- a/testing/btest/scripts/base/frameworks/pacf/hook.bro +++ /dev/null @@ -1,27 +0,0 @@ -# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT -# @TEST-EXEC: btest-diff pacf.log - -@load base/frameworks/pacf - -event bro_init() - { - local pacf_debug = Pacf::create_debug(T); - Pacf::activate(pacf_debug, 0); - } - -event connection_established(c: connection) - { - local id = c$id; - Pacf::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 30sec); - Pacf::drop_address(id$orig_h, 15sec); - Pacf::whitelist_address(id$orig_h, 15sec); - Pacf::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 Pacf::rule_policy(r: Pacf::Rule) - { - if ( r$expire == 15sec ) - break; - - r$entity$flow$src_h = 0.0.0.0/0; - } diff --git a/testing/btest/scripts/base/frameworks/pacf/multiple.bro b/testing/btest/scripts/base/frameworks/pacf/multiple.bro deleted file mode 100644 index baa8c5822e..0000000000 --- a/testing/btest/scripts/base/frameworks/pacf/multiple.bro +++ /dev/null @@ -1,24 +0,0 @@ -# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT -# @TEST-EXEC: TEST_DIFF_CANONIFIER='grep -v ^# | $SCRIPTS/diff-sort' btest-diff pacf.log - -@load base/frameworks/pacf - -event bro_init() - { - local pacf_debug = Pacf::create_debug(T); - local pacf_debug_2 = Pacf::create_debug(T); - local of_controller = OpenFlow::log_new(42); - local pacf_of = Pacf::create_openflow(of_controller); - Pacf::activate(pacf_debug, 10); - Pacf::activate(pacf_of, 10); - Pacf::activate(pacf_debug_2, 0); - } - -event connection_established(c: connection) - { - local id = c$id; - Pacf::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 30sec); - Pacf::drop_address(id$orig_h, 15sec); - Pacf::whitelist_address(id$orig_h, 15sec); - Pacf::redirect_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 5, 30sec); - } diff --git a/testing/btest/scripts/base/frameworks/pacf/openflow.bro b/testing/btest/scripts/base/frameworks/pacf/openflow.bro deleted file mode 100644 index 7ea537e505..0000000000 --- a/testing/btest/scripts/base/frameworks/pacf/openflow.bro +++ /dev/null @@ -1,21 +0,0 @@ -# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT -# @TEST-EXEC: btest-diff pacf.log -# @TEST-EXEC: btest-diff openflow.log - -@load base/frameworks/pacf - -global of_controller: OpenFlow::Controller; - -event bro_init() - { - of_controller = OpenFlow::log_new(42); - local pacf_of = Pacf::create_openflow(of_controller); - Pacf::activate(pacf_of, 0); - } - -event connection_established(c: connection) - { - local id = c$id; - Pacf::shunt_flow([$src_h=id$orig_h, $src_p=id$orig_p, $dst_h=id$resp_h, $dst_p=id$resp_p], 30sec); - Pacf::drop_address(id$orig_h, 15sec); - } diff --git a/testing/btest/scripts/base/frameworks/pacf/packetfilter.bro b/testing/btest/scripts/base/frameworks/pacf/packetfilter.bro deleted file mode 100644 index 9076fbbb1f..0000000000 --- a/testing/btest/scripts/base/frameworks/pacf/packetfilter.bro +++ /dev/null @@ -1,18 +0,0 @@ -# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT -# @TEST-EXEC: btest-diff conn.log - -@load base/frameworks/pacf - -event bro_init() - { - local pacf_packetfilter = Pacf::create_packetfilter(); - Pacf::activate(pacf_packetfilter, 0); - } - -event connection_established(c: connection) - { - local e = Pacf::Entity($ty=Pacf::ADDRESS, $ip=addr_to_subnet(c$id$orig_h)); - local r = Pacf::Rule($ty=Pacf::DROP, $target=Pacf::MONITOR, $entity=e, $expire=10min); - - Pacf::add_rule(r); - } diff --git a/testing/btest/scripts/base/frameworks/pacf/quarantine-openflow.bro b/testing/btest/scripts/base/frameworks/pacf/quarantine-openflow.bro deleted file mode 100644 index eff863b684..0000000000 --- a/testing/btest/scripts/base/frameworks/pacf/quarantine-openflow.bro +++ /dev/null @@ -1,19 +0,0 @@ -# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT -# @TEST-EXEC: btest-diff pacf.log -# @TEST-EXEC: btest-diff openflow.log - -@load base/frameworks/pacf - -global of_controller: OpenFlow::Controller; - -event bro_init() - { - of_controller = OpenFlow::log_new(42); - local pacf_of = Pacf::create_openflow(of_controller); - Pacf::activate(pacf_of, 0); - } - -event connection_established(c: connection) - { - Pacf::quarantine_host(c$id$orig_h, 8.8.8.8, 192.169.18.1, 10hrs); - } From 13c44895787e12a20fe6aee503c6367c771b7578 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Thu, 21 Jan 2016 13:56:21 -0800 Subject: [PATCH 58/93] Testcase for crash when a record contains a function referencing a record. Needs BRO_PROFILER_FILE set to crash --- .../language/record-function-recursion.bro | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 testing/btest/language/record-function-recursion.bro diff --git a/testing/btest/language/record-function-recursion.bro b/testing/btest/language/record-function-recursion.bro new file mode 100644 index 0000000000..b43c7bfe80 --- /dev/null +++ b/testing/btest/language/record-function-recursion.bro @@ -0,0 +1,19 @@ +# @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; +} From c5a14d1bc165e24e086f58e2149bf0e2cd2ab7bb Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 3 Feb 2016 13:22:05 -0800 Subject: [PATCH 59/93] Fix crash when printing type of recursive structures. Also slightly fix indentation in Type.h --- src/Desc.cc | 21 +++++++++++++++++++ src/Desc.h | 9 ++++++++ src/Type.cc | 14 +++++++++++-- src/Type.h | 9 ++++---- .../language.record-function-recursion/out | 2 ++ .../language/record-function-recursion.bro | 1 + 6 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 testing/btest/Baseline/language.record-function-recursion/out 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/Type.cc b/src/Type.cc index 75f1f445df..020bb3ce19 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -1045,6 +1045,7 @@ TypeDecl* RecordType::FieldDecl(int field) void RecordType::Describe(ODesc* d) const { + d->PushType(this); if ( d->IsReadable() ) { if ( d->IsShort() && GetName().size() ) @@ -1064,10 +1065,12 @@ 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 +1078,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 +1133,10 @@ 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 +1177,10 @@ 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/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/language/record-function-recursion.bro b/testing/btest/language/record-function-recursion.bro index b43c7bfe80..90832bfa69 100644 --- a/testing/btest/language/record-function-recursion.bro +++ b/testing/btest/language/record-function-recursion.bro @@ -16,4 +16,5 @@ redef record Outer += { event bro_init() { local o = Outer(); print o; + print type_name(o); } From bebe2e85cb02f76795a3c19408f3466238c61818 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 3 Feb 2016 14:31:33 -0800 Subject: [PATCH 60/93] Revert "introduce &weaken attribute" This reverts commit 00204ab8a6adcad0d62b1e7e76945c58b738cc3d. We decided to implement this using an alternative method that does not need a new language attribute. --- scripts/base/frameworks/netcontrol/plugin.bro | 4 ++-- src/Attr.cc | 7 +------ src/Attr.h | 3 +-- src/Type.cc | 10 ++-------- src/parse.y | 6 ++---- src/scan.l | 1 - 6 files changed, 8 insertions(+), 23 deletions(-) diff --git a/scripts/base/frameworks/netcontrol/plugin.bro b/scripts/base/frameworks/netcontrol/plugin.bro index 22a846b977..9e53e55622 100644 --- a/scripts/base/frameworks/netcontrol/plugin.bro +++ b/scripts/base/frameworks/netcontrol/plugin.bro @@ -73,8 +73,8 @@ export { # 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 &weaken; + ## because of cyclic type dependency.) + plugin: Plugin &optional; }; } diff --git a/src/Attr.cc b/src/Attr.cc index ea2b946e6a..4bfbcf2ad7 100644 --- a/src/Attr.cc +++ b/src/Attr.cc @@ -18,7 +18,7 @@ const char* attr_name(attr_tag t) "&encrypt", "&raw_output", "&mergeable", "&priority", "&group", "&log", "&error_handler", "&type_column", - "(&tracked)", "&deprecated", "&weaken", + "(&tracked)", "&deprecated", }; return attr_names[int(t)]; @@ -453,11 +453,6 @@ void Attributes::CheckAttr(Attr* a) Error("&log applied to a type that cannot be logged"); break; - case ATTR_WEAKEN: - if ( ! in_record ) - Error("&weaken applied outside of record"); - break; - case ATTR_TYPE_COLUMN: { if ( type->Tag() != TYPE_PORT ) diff --git a/src/Attr.h b/src/Attr.h index 7205e68249..0960a9d5f9 100644 --- a/src/Attr.h +++ b/src/Attr.h @@ -35,8 +35,7 @@ typedef enum { ATTR_TYPE_COLUMN, // for input framework ATTR_TRACKED, // hidden attribute, tracked by NotifierRegistry ATTR_DEPRECATED, - ATTR_WEAKEN, -#define NUM_ATTRS (int(ATTR_WEAKEN) + 1) +#define NUM_ATTRS (int(ATTR_DEPRECATED) + 1) } attr_tag; class Attr : public BroObj { diff --git a/src/Type.cc b/src/Type.cc index 15e2564ad0..75f1f445df 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -1129,10 +1129,7 @@ void RecordType::DescribeFields(ODesc* d) const const TypeDecl* td = FieldDecl(i); d->Add(td->id); d->Add(":"); - if ( td->FindAttr(ATTR_WEAKEN) ) - d->Add(""); - else - td->type->Describe(d); + td->type->Describe(d); d->Add(";"); } } @@ -1173,10 +1170,7 @@ void RecordType::DescribeFieldsReST(ODesc* d, bool func_args) const } const TypeDecl* td = FieldDecl(i); - if ( td->FindAttr(ATTR_WEAKEN) ) - d->Add(""); - else - td->DescribeReST(d); + td->DescribeReST(d); if ( func_args ) continue; diff --git a/src/parse.y b/src/parse.y index ad275e02c0..c67732835f 100644 --- a/src/parse.y +++ b/src/parse.y @@ -2,7 +2,7 @@ // See the file "COPYING" in the main distribution directory for copyright. %} -%expect 81 +%expect 78 %token TOK_ADD TOK_ADD_TO TOK_ADDR TOK_ANY %token TOK_ATENDIF TOK_ATELSE TOK_ATIF TOK_ATIFDEF TOK_ATIFNDEF @@ -25,7 +25,7 @@ %token TOK_ATTR_PERSISTENT TOK_ATTR_SYNCHRONIZED %token TOK_ATTR_RAW_OUTPUT TOK_ATTR_MERGEABLE %token TOK_ATTR_PRIORITY TOK_ATTR_LOG TOK_ATTR_ERROR_HANDLER -%token TOK_ATTR_TYPE_COLUMN TOK_ATTR_DEPRECATED TOK_ATTR_WEAKEN +%token TOK_ATTR_TYPE_COLUMN TOK_ATTR_DEPRECATED %token TOK_DEBUG @@ -1285,8 +1285,6 @@ attr: { $$ = new Attr(ATTR_ERROR_HANDLER); } | TOK_ATTR_DEPRECATED { $$ = new Attr(ATTR_DEPRECATED); } - | TOK_ATTR_WEAKEN - { $$ = new Attr(ATTR_WEAKEN); } ; stmt: diff --git a/src/scan.l b/src/scan.l index 8103201303..a6e37a67f7 100644 --- a/src/scan.l +++ b/src/scan.l @@ -276,7 +276,6 @@ when return TOK_WHEN; &type_column return TOK_ATTR_TYPE_COLUMN; &read_expire return TOK_ATTR_EXPIRE_READ; &redef return TOK_ATTR_REDEF; -&weaken return TOK_ATTR_WEAKEN; &write_expire return TOK_ATTR_EXPIRE_WRITE; &encrypt { From 5e2ec25a38453e9db24de587a2a93b9e02414f5a Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Thu, 11 Feb 2016 11:31:44 -0800 Subject: [PATCH 61/93] small acld plugin fix --- scripts/base/frameworks/netcontrol/plugins/acld.bro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/base/frameworks/netcontrol/plugins/acld.bro b/scripts/base/frameworks/netcontrol/plugins/acld.bro index 43375cb7ae..48965629c5 100644 --- a/scripts/base/frameworks/netcontrol/plugins/acld.bro +++ b/scripts/base/frameworks/netcontrol/plugins/acld.bro @@ -55,7 +55,7 @@ const acld_add_to_remove: table[string] of string = { ["dropudpdsthostport"] ="restoreudpdsthostport", ["permittcpdsthostport"] ="unpermittcpdsthostport", ["permitudpdsthostport"] ="unpermitudpdsthostport", - ["nullzero "] ="nonullzero" + ["nullzero"] ="nonullzero" }; event NetControl::acld_rule_added(id: count, r: Rule, msg: string) From 9f3c0c9bb4e78638c5e5af69a436e08467ffa654 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Thu, 11 Feb 2016 13:09:20 -0800 Subject: [PATCH 62/93] Update OpenFlow API and events. Events now generally carry the unique ID of the backend that is given during initialization; there are a few more functions and other bugfixes. A few netcontrol tests are still broken (mostly due to a pcap update in msater). --- .../frameworks/netcontrol/plugins/acld.bro | 4 +- .../netcontrol/plugins/openflow.bro | 12 ++-- scripts/base/frameworks/openflow/cluster.bro | 41 ++++++++---- scripts/base/frameworks/openflow/main.bro | 66 +++++++++++++++++-- .../base/frameworks/openflow/non-cluster.bro | 13 +++- .../frameworks/openflow/plugins/broker.bro | 8 +-- .../base/frameworks/openflow/plugins/log.bro | 2 +- .../base/frameworks/openflow/plugins/ryu.bro | 8 +-- scripts/base/frameworks/openflow/types.bro | 31 +-------- .../netcontrol.log | 12 +++- .../openflow.log | 10 ++- .../recv.recv.out | 6 +- .../openflow.log | 14 ++-- .../manager-1.openflow.log | 8 +-- .../.stdout | 14 +++- .../base/frameworks/openflow/broker-basic.bro | 16 ++--- .../base/frameworks/openflow/log-basic.bro | 6 +- .../base/frameworks/openflow/log-cluster.bro | 4 +- .../base/frameworks/openflow/ryu-basic.bro | 6 +- 19 files changed, 186 insertions(+), 95 deletions(-) diff --git a/scripts/base/frameworks/netcontrol/plugins/acld.bro b/scripts/base/frameworks/netcontrol/plugins/acld.bro index 48965629c5..9b393f6bf9 100644 --- a/scripts/base/frameworks/netcontrol/plugins/acld.bro +++ b/scripts/base/frameworks/netcontrol/plugins/acld.bro @@ -21,11 +21,11 @@ export { ## Broker port to connect to acld_port: port; ## Function that can decide weather to accept add request - add_pred: function(p: PluginState, r: Rule, ar: AclRule): bool &optional &weaken; + add_pred: function(p: PluginState, r: Rule, ar: AclRule): bool &optional; }; ## Instantiates the acld plugin. - global create_acld: function(config: AcldConfig) : PluginState; + global create_acld: function(config: AcldConfig) : PluginState; redef record PluginState += { acld_config: AcldConfig &optional; diff --git a/scripts/base/frameworks/netcontrol/plugins/openflow.bro b/scripts/base/frameworks/netcontrol/plugins/openflow.bro index 6628e5e579..a9d3aad2ef 100644 --- a/scripts/base/frameworks/netcontrol/plugins/openflow.bro +++ b/scripts/base/frameworks/netcontrol/plugins/openflow.bro @@ -11,9 +11,9 @@ export { 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. - check_pred: function(p: PluginState, r: Rule): bool &optional &weaken; - match_pred: function(p: PluginState, e: Entity, m: vector of OpenFlow::ofp_match): vector of OpenFlow::ofp_match &optional &weaken; - flow_mod_pred: function(p: PluginState, r: Rule, m: OpenFlow::ofp_flow_mod): OpenFlow::ofp_flow_mod &optional &weaken; + 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 += { @@ -318,7 +318,7 @@ function openflow_remove_rule(p: PluginState, r: Rule) : bool return T; } -event OpenFlow::flow_mod_success(match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) &priority=3 +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 ) @@ -346,7 +346,7 @@ event OpenFlow::flow_mod_success(match: OpenFlow::ofp_match, flow_mod: OpenFlow: event NetControl::rule_removed(r, p, msg); } -event OpenFlow::flow_mod_failure(match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) &priority=3 +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 ) @@ -359,7 +359,7 @@ event OpenFlow::flow_mod_failure(match: OpenFlow::ofp_match, flow_mod: OpenFlow: event NetControl::rule_error(r, p, msg); } -event OpenFlow::flow_removed(match: OpenFlow::ofp_match, cookie: count, priority: count, reason: count, duration_sec: count, idle_timeout: count, packet_count: count, byte_count: count) +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 ) diff --git a/scripts/base/frameworks/openflow/cluster.bro b/scripts/base/frameworks/openflow/cluster.bro index 6f08e6839a..36109fa663 100644 --- a/scripts/base/frameworks/openflow/cluster.bro +++ b/scripts/base/frameworks/openflow/cluster.bro @@ -14,8 +14,6 @@ export { ## Workers need ability to forward commands to manager. redef Cluster::worker2manager_events += /OpenFlow::cluster_flow_(mod|clear)/; -global name_to_controller: table[string] of Controller; - # the flow_mod function wrapper function flow_mod(controller: Controller, match: ofp_match, flow_mod: ofp_flow_mod): bool { @@ -81,14 +79,33 @@ function register_controller(tpe: OpenFlow::Plugin, name: string, controller: Co if ( Cluster::local_node_type() != Cluster::MANAGER ) return; - if ( controller$state$_name in name_to_controller ) - { - Reporter::error("OpenFlow Controller %s was already registered. Ignored duplicate registration"); - return; - } - - name_to_controller[controller$state$_name] = controller; - - if ( controller?$init ) - controller$init(controller$state); + 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/main.bro b/scripts/base/frameworks/openflow/main.bro index 139d932e0d..4e336e0412 100644 --- a/scripts/base/frameworks/openflow/main.bro +++ b/scripts/base/frameworks/openflow/main.bro @@ -34,26 +34,32 @@ export { ## 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(match: ofp_match, flow_mod: ofp_flow_mod, msg: string &default=""); + 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(match: ofp_match, flow_mod: ofp_flow_mod, msg: string &default=""); + 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. @@ -67,7 +73,7 @@ export { ## packet_count: packet count of the flow ## ## byte_count: byte count of the flow - global flow_removed: event(match: ofp_match, cookie: count, priority: count, reason: count, duration_sec: count, idle_timeout: count, packet_count: count, byte_count: count); + 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. @@ -113,8 +119,25 @@ export { ## ## 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 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; @@ -137,7 +160,7 @@ function match_conn(id: conn_id, reverse: bool &default=F): ofp_match orig_h = id$resp_h; orig_p = id$resp_p; resp_h = id$orig_h; - resp_p = id$resp_p; + resp_p = id$orig_p; } if ( is_v6_addr(orig_h) ) @@ -203,3 +226,38 @@ function get_cookie_gid(cookie: count): count return INVALID_COOKIE; } + +# 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("OpenFlow Controller %s was already registered. Ignored duplicate registration"); + return; + } + + name_to_controller[controller$state$_name] = controller; + + if ( controller?$init ) + controller$init(controller$state); + } + +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 index efadbe56b6..8975b276ca 100644 --- a/scripts/base/frameworks/openflow/non-cluster.bro +++ b/scripts/base/frameworks/openflow/non-cluster.bro @@ -24,6 +24,15 @@ function register_controller(tpe: OpenFlow::Plugin, name: string, controller: Co controller$state$_name = cat(tpe, name); controller$state$_plugin = tpe; - if ( controller?$init ) - controller$init(controller$state); + 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/broker.bro b/scripts/base/frameworks/openflow/plugins/broker.bro index 55505fd3eb..cd7b9fecd9 100644 --- a/scripts/base/frameworks/openflow/plugins/broker.bro +++ b/scripts/base/frameworks/openflow/plugins/broker.bro @@ -32,8 +32,8 @@ export { broker_topic: string &optional; }; - global broker_flow_mod: event(dpid: count, match: ofp_match, flow_mod: ofp_flow_mod); - global broker_flow_clear: event(dpid: count); + 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); } function broker_describe(state: ControllerState): string @@ -43,14 +43,14 @@ function broker_describe(state: ControllerState): string 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$broker_dpid, match, flow_mod)); + 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$broker_dpid)); + BrokerComm::event(state$broker_topic, BrokerComm::event_args(broker_flow_clear, state$_name, state$broker_dpid)); return T; } diff --git a/scripts/base/frameworks/openflow/plugins/log.bro b/scripts/base/frameworks/openflow/plugins/log.bro index 3780dfd3c0..5a50168a01 100644 --- a/scripts/base/frameworks/openflow/plugins/log.bro +++ b/scripts/base/frameworks/openflow/plugins/log.bro @@ -55,7 +55,7 @@ function log_flow_mod(state: ControllerState, match: ofp_match, flow_mod: OpenFl { 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(match, flow_mod); + event OpenFlow::flow_mod_success(state$_name, match, flow_mod); return T; } diff --git a/scripts/base/frameworks/openflow/plugins/ryu.bro b/scripts/base/frameworks/openflow/plugins/ryu.bro index 8d2d59e5e5..e6c5309bef 100644 --- a/scripts/base/frameworks/openflow/plugins/ryu.bro +++ b/scripts/base/frameworks/openflow/plugins/ryu.bro @@ -91,7 +91,7 @@ function ryu_flow_mod(state: OpenFlow::ControllerState, match: ofp_match, flow_m # 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=OpenFlow::generate_cookie(flow_mod$cookie), + $cookie=flow_mod$cookie, $idle_timeout=flow_mod$idle_timeout, $hard_timeout=flow_mod$hard_timeout, $priority=flow_mod$priority, @@ -122,7 +122,7 @@ function ryu_flow_mod(state: OpenFlow::ControllerState, match: ofp_match, flow_m { print url; print to_json(mod); - event OpenFlow::flow_mod_success(match, flow_mod); + event OpenFlow::flow_mod_success(state$_name, match, flow_mod); return T; } @@ -137,11 +137,11 @@ function ryu_flow_mod(state: OpenFlow::ControllerState, match: ofp_match, flow_m when ( local result = ActiveHTTP::request(request) ) { if(result$code == 200) - event OpenFlow::flow_mod_success(match, flow_mod, result$body); + 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(match, flow_mod, result$body); + event OpenFlow::flow_mod_failure(state$_name, match, flow_mod, result$body); return F; } } diff --git a/scripts/base/frameworks/openflow/types.bro b/scripts/base/frameworks/openflow/types.bro index 9faed67f9c..a8493efd8c 100644 --- a/scripts/base/frameworks/openflow/types.bro +++ b/scripts/base/frameworks/openflow/types.bro @@ -108,35 +108,6 @@ export { actions: ofp_flow_action &default=ofp_flow_action(); } &log; -# Functionality using this is currently not implemented. At all. -# ## Body of reply to OFPST_FLOW request. -# type ofp_flow_stats: record { -# ## ID of table flow came from. -# table_id: count; -# ## Description of fields. -# match: ofp_match; -# ## Time flow has been alive in seconds. -# duration_sec: count; -# ## Time flow has been alive in nanoseconds beyond -# ## duration_sec. -# duration_nsec: count; -# ## Priority of the entry. Only meaningful -# ## when this is not an exact-match entry. -# priority: count; -# ## Number of seconds idle before expiration. -# idle_timeout: count; -# ## Number of seconds before expiration. -# hard_timeout: count; -# ## Opaque controller-issued identifier. -# cookie: count; -# ## Number of packets in flow. -# packet_count: count; -# ## Number of bytes in flow. -# byte_count: count; -# ## Actions -# actions: vector of ofp_action_output; -# }; - ## Controller record representing an openflow controller type Controller: record { ## Controller related state. @@ -147,6 +118,8 @@ export { describe: function(state: ControllerState): string; ## one-time initialization function. 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 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/netcontrol.log index 12daa37c03..bd774345d9 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/netcontrol.log +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/netcontrol.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path netcontrol -#open 2015-07-08-19-33-52 +#open 2016-02-11-21-07-34 #fields ts category cmd state action target entity_type entity msg location plugin #types time enum string enum string enum string string string string string 0.000000 NetControl::MESSAGE - - - - - - activated plugin with priority 0 - Openflow - OpenFlog Log Plugin - DPID 42 @@ -11,4 +11,12 @@ 1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -#close 2015-07-08-19-33-52 +1437831787.861602 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.133.100/32/49648->192.168.133.102/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1437831787.861602 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.133.100/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1437831787.861602 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.133.100/32/49648->192.168.133.102/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1437831787.861602 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.133.100/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1437831799.610433 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.133.100/32/49655->17.167.150.73/32/443 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1437831799.610433 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.133.100/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1437831799.610433 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.133.100/32/49655->17.167.150.73/32/443 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +1437831799.610433 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.133.100/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 +#close 2016-02-11-21-07-34 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/openflow.log index ffc195ed09..56274f20f8 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/openflow.log +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/openflow.log @@ -3,10 +3,16 @@ #empty_field (empty) #unset_field - #path openflow -#open 2015-06-01-17-45-48 +#open 2016-02-11-21-07-34 #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 - - 10.10.1.4/32 - - - 4398046511110 - OpenFlow::OFPFC_ADD 0 15 0 - - 1 (empty) - - F - - - - - - - 1254722767.875996 42 - - - - - 2048 - - - 10.10.1.4/32 - - 4398046511111 - OpenFlow::OFPFC_ADD 0 15 0 - - 1 (empty) - - F - - - - - - - -#close 2015-06-01-17-45-48 +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.100/32 - - - 4398046511114 - OpenFlow::OFPFC_ADD 0 15 0 - - 1 (empty) - - F - - - - - - - +1437831787.861602 42 - - - - - 2048 - - - 192.168.133.100/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 - - 192.168.133.100/32 - - - 4398046511118 - OpenFlow::OFPFC_ADD 0 15 0 - - 1 (empty) - - F - - - - - - - +1437831799.610433 42 - - - - - 2048 - - - 192.168.133.100/32 - - 4398046511119 - OpenFlow::OFPFC_ADD 0 15 0 - - 1 (empty) - - F - - - - - - - +#close 2016-02-11-21-07-34 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 index 08c50b5caa..ec3b038bd9 100644 --- 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 @@ -1,5 +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=1, 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=42, 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=25], [cookie=42, 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=, 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.log-basic/openflow.log b/testing/btest/Baseline/scripts.base.frameworks.openflow.log-basic/openflow.log index 3e65c82baf..eed7c20caf 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.openflow.log-basic/openflow.log +++ b/testing/btest/Baseline/scripts.base.frameworks.openflow.log-basic/openflow.log @@ -3,10 +3,14 @@ #empty_field (empty) #unset_field - #path openflow -#open 2015-05-22-20-37-23 +#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 - - - - - - - - - - - - 1 - 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 42 - 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 25 42 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) - - F - - - - - - - -#close 2015-05-22-20-37-23 +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 index 9d5f2f39c8..a6b8e30871 100644 --- 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 @@ -3,9 +3,9 @@ #empty_field (empty) #unset_field - #path openflow -#open 2015-05-26-20-51-55 +#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 -1432673515.912626 42 - - - - - 2048 - 6 10.10.1.4/32 74.53.140.153/32 1470 25 42 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) - - F - - - - - - - -1432673515.912626 42 - - - - - 2048 - 6 74.53.140.153/32 10.10.1.4/32 25 25 42 - OpenFlow::OFPFC_ADD 30 0 5 - - 0 (empty) - - F - - - - - - - -#close 2015-05-26-20-52-05 +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 index efdb61aae8..f31aec1a92 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.openflow.ryu-basic/.stdout +++ b/testing/btest/Baseline/scripts.base.frameworks.openflow.ryu-basic/.stdout @@ -5,6 +5,18 @@ 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": 25, "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} +{"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/scripts/base/frameworks/openflow/broker-basic.bro b/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro index 6f75f82081..e815cc47c8 100644 --- a/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro +++ b/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro @@ -30,7 +30,7 @@ event BrokerComm::outgoing_connection_established(peer_address: string, print "BrokerComm::outgoing_connection_established", peer_address, peer_port; continue_processing(); OpenFlow::flow_clear(of_controller); - OpenFlow::flow_mod(of_controller, [], [$cookie=1, $command=OpenFlow::OFPFC_ADD, $actions=[$out_ports=vector(3, 7)]]); + 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, @@ -46,7 +46,7 @@ event connection_established(c: connection) local match_rev = OpenFlow::match_conn(c$id, T); local flow_mod: OpenFlow::ofp_flow_mod = [ - $cookie=42, + $cookie=OpenFlow::generate_cookie(42), $command=OpenFlow::OFPFC_ADD, $idle_timeout=30, $priority=5 @@ -56,12 +56,12 @@ event connection_established(c: connection) OpenFlow::flow_mod(of_controller, match_rev, flow_mod); } -event OpenFlow::flow_mod_success(match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) +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(match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) +event OpenFlow::flow_mod_failure(name: string, match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) { print "Flow_mod_failure"; } @@ -97,15 +97,15 @@ function got_message() terminate(); } -event OpenFlow::broker_flow_mod(dpid: count, match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod) +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, match, flow_mod, "")); - BrokerComm::event("bro/event/openflow", BrokerComm::event_args(OpenFlow::flow_mod_failure, 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(dpid: count) +event OpenFlow::broker_flow_clear(name: string, dpid: count) { print "flow_clear", dpid; got_message(); diff --git a/testing/btest/scripts/base/frameworks/openflow/log-basic.bro b/testing/btest/scripts/base/frameworks/openflow/log-basic.bro index 212a3c2fec..d4f08e7822 100644 --- a/testing/btest/scripts/base/frameworks/openflow/log-basic.bro +++ b/testing/btest/scripts/base/frameworks/openflow/log-basic.bro @@ -6,11 +6,13 @@ 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=1, $command=OpenFlow::OFPFC_ADD, $actions=[$out_ports=vector(3, 7)]]); + 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) @@ -19,7 +21,7 @@ event connection_established(c: connection) local match_rev = OpenFlow::match_conn(c$id, T); local flow_mod: OpenFlow::ofp_flow_mod = [ - $cookie=42, + $cookie=OpenFlow::generate_cookie(++cookie_id), $command=OpenFlow::OFPFC_ADD, $idle_timeout=30, $priority=5 diff --git a/testing/btest/scripts/base/frameworks/openflow/log-cluster.bro b/testing/btest/scripts/base/frameworks/openflow/log-cluster.bro index 0859e18571..cccf60cf99 100644 --- a/testing/btest/scripts/base/frameworks/openflow/log-cluster.bro +++ b/testing/btest/scripts/base/frameworks/openflow/log-cluster.bro @@ -33,7 +33,7 @@ event connection_established(c: connection) local match_rev = OpenFlow::match_conn(c$id, T); local flow_mod: OpenFlow::ofp_flow_mod = [ - $cookie=42, + $cookie=OpenFlow::generate_cookie(42), $command=OpenFlow::OFPFC_ADD, $idle_timeout=30, $priority=5 @@ -41,6 +41,8 @@ event connection_established(c: connection) OpenFlow::flow_mod(of_controller, match, flow_mod); OpenFlow::flow_mod(of_controller, match_rev, flow_mod); + + terminate(); } event terminate_me() { diff --git a/testing/btest/scripts/base/frameworks/openflow/ryu-basic.bro b/testing/btest/scripts/base/frameworks/openflow/ryu-basic.bro index 3c8eb8f0d8..3bfaa4c076 100644 --- a/testing/btest/scripts/base/frameworks/openflow/ryu-basic.bro +++ b/testing/btest/scripts/base/frameworks/openflow/ryu-basic.bro @@ -12,7 +12,7 @@ event bro_init() of_controller$state$ryu_debug=T; OpenFlow::flow_clear(of_controller); - OpenFlow::flow_mod(of_controller, [], [$cookie=1, $command=OpenFlow::OFPFC_ADD, $actions=[$out_ports=vector(3, 7)]]); + 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) @@ -21,7 +21,7 @@ event connection_established(c: connection) local match_rev = OpenFlow::match_conn(c$id, T); local flow_mod: OpenFlow::ofp_flow_mod = [ - $cookie=42, + $cookie=OpenFlow::generate_cookie(42), $command=OpenFlow::OFPFC_ADD, $idle_timeout=30, $priority=5 @@ -31,7 +31,7 @@ event connection_established(c: connection) OpenFlow::flow_mod(of_controller, match_rev, flow_mod); } -event OpenFlow::flow_mod_success(match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) +event OpenFlow::flow_mod_success(name: string, match: OpenFlow::ofp_match, flow_mod: OpenFlow::ofp_flow_mod, msg: string) { print "Flow_mod_success"; } From a38327bd08cc35313e889b1264e0457d2fd1f08b Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Thu, 11 Feb 2016 19:45:30 -0800 Subject: [PATCH 63/93] Extend NetControl logging and fix bugs. Netcontrol log now includes more information; before that, it had not quite caught up to the new capabilities (like flow modifying and redirection, as well as mac addresses). Furthermore, this fixes a number of bugs with cluster mode (like duplicate events), test failures due to updates in Bro, etc. --- .../base/frameworks/netcontrol/cluster.bro | 31 +++++ scripts/base/frameworks/netcontrol/main.bro | 129 ++++++++++++++---- .../frameworks/netcontrol/non-cluster.bro | 29 ++++ .../frameworks/netcontrol/plugins/acld.bro | 2 +- .../frameworks/netcontrol/plugins/broker.bro | 2 +- .../frameworks/netcontrol/plugins/debug.bro | 2 +- .../netcontrol/plugins/openflow.bro | 6 +- .../netcontrol/plugins/packetfilter.bro | 6 +- scripts/base/frameworks/netcontrol/types.bro | 5 +- .../frameworks/openflow/plugins/broker.bro | 2 +- .../base/frameworks/openflow/plugins/log.bro | 2 +- .../base/frameworks/openflow/plugins/ryu.bro | 2 +- .../recv.recv.out | 12 +- .../send.send.out | 12 +- .../manager-1.netcontrol.log | 48 +++---- .../worker-1..stdout | 4 - .../worker-2..stdout | 2 - .../.stdout | 28 ++-- .../netcontrol.log | 68 ++++++--- .../recv.recv.out | 8 +- .../send.netcontrol.log | 20 +++ .../send.send.out | 12 +- .../.stdout | 20 +-- .../netcontrol.log | 52 +++---- .../netcontrol.log | 26 ++-- .../netcontrol.log | 64 ++++----- .../netcontrol.log | 34 ++--- .../conn.log | 8 +- .../netcontrol.log | 26 ++-- .../openflow.log | 12 +- .../base/frameworks/netcontrol/acld.bro | 4 +- .../frameworks/netcontrol/basic-cluster.bro | 6 +- .../base/frameworks/netcontrol/basic.bro | 40 ++++-- .../base/frameworks/netcontrol/broker.bro | 1 + .../netcontrol/catch-and-release.bro | 2 +- .../base/frameworks/netcontrol/hook.bro | 2 +- .../base/frameworks/netcontrol/multiple.bro | 2 +- .../netcontrol/quarantine-openflow.bro | 2 +- 38 files changed, 466 insertions(+), 267 deletions(-) delete mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/worker-1..stdout delete mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/worker-2..stdout create mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/send.netcontrol.log diff --git a/scripts/base/frameworks/netcontrol/cluster.bro b/scripts/base/frameworks/netcontrol/cluster.bro index 880736c8ed..9cdaa30d2d 100644 --- a/scripts/base/frameworks/netcontrol/cluster.bro +++ b/scripts/base/frameworks/netcontrol/cluster.bro @@ -64,3 +64,34 @@ 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 && ! 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/main.bro b/scripts/base/frameworks/netcontrol/main.bro index fd32b4ec64..cdbc60541e 100644 --- a/scripts/base/frameworks/netcontrol/main.bro +++ b/scripts/base/frameworks/netcontrol/main.bro @@ -116,7 +116,7 @@ export { ## 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) : vector of string; + global quarantine_host: function(infected: addr, dns: addr, quarantine: addr, t: interval, location: string &default="") : vector of string; ## Flushes all state. global clear: function(); @@ -197,7 +197,7 @@ export { ## r: The rule to be added global NetControl::rule_policy: hook(r: Rule); - ## Type of an entry in the PACF log. + ## Type of an entry in the NetControl log. type InfoCategory: enum { ## A log entry reflecting a framework message. MESSAGE, @@ -207,7 +207,7 @@ export { RULE }; - ## State of an entry in the PACF log. + ## State of an entry in the NetControl log. type InfoState: enum { REQUESTED, SUCCEEDED, @@ -216,10 +216,12 @@ export { TIMEOUT, }; - ## The record type which contains column fields of the PACF log. + ## The record type which contains 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. @@ -234,14 +236,24 @@ export { 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; - ## Logcation where the underlying action was triggered. + ## 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; }; +# type ShuntInfo: record { +# ## Time at which the recorded activity occurred. +# ts: time &log; + ## 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); @@ -262,6 +274,7 @@ global id_to_cids: table[string] of set[count]; # id to cid event bro_init() &priority=5 { Log::create_stream(NetControl::LOG, [$columns=Info, $ev=log_netcontrol, $path="netcontrol"]); +# Log::create_stream(NetControl::SHUNT, [$columns=ShuntInfo, $ev=log_netcontrol_shung, $path="netcontrol_shunt"]); } function entity_to_info(info: Info, e: Entity) @@ -284,6 +297,8 @@ function entity_to_info(info: Info, e: Entity) 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 ) @@ -295,6 +310,15 @@ function entity_to_info(info: Info, e: Entity) 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: @@ -311,10 +335,46 @@ 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 ) + 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); } @@ -328,13 +388,15 @@ function log_error(msg: string, p: PluginState) Log::write(LOG, [$ts=network_time(), $category=ERROR, $msg=msg, $plugin=p$plugin$name(p)]); } -function log_rule(r: Rule, cmd: string, state: InfoState, p: PluginState) +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); @@ -415,7 +477,7 @@ function redirect_flow(f: flow_id, out_port: count, t: interval, location: strin $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, $c=out_port]; + local r: Rule = [$ty=REDIRECT, $target=FORWARD, $entity=e, $expire=t, $location=location, $out_port=out_port]; return add_rule(r); } @@ -559,7 +621,7 @@ function remove_rule_impl(id: string) : bool return success; } -event rule_expire(r: Rule, p: PluginState) +function rule_expire_impl(r: Rule, p: PluginState) &priority=-5 { if ( [r$id,r$cid] !in rules ) # Removed already. @@ -569,41 +631,54 @@ event rule_expire(r: Rule, p: PluginState) remove_single_rule(r$id, r$cid); } -event rule_added(r: Rule, p: PluginState, msg: string &default="") +function rule_added_impl(r: Rule, p: PluginState, msg: string &default="") { - log_rule(r, "ADD", SUCCEEDED, p); + log_rule(r, "ADD", SUCCEEDED, p, msg); rules[r$id,r$cid] = r; if ( r$id !in id_to_cids ) id_to_cids[r$id] = set(); add id_to_cids[r$id][r$cid]; - - if ( r?$expire && ! p$plugin$can_expire ) - schedule r$expire { rule_expire(r, p) }; } -event rule_removed(r: Rule, p: PluginState, msg: string &default="") +function rule_removed_impl(r: Rule, p: PluginState, msg: string &default="") + { + if ( [r$id,r$cid] !in rules ) + { + log_rule_error(r, "Removal of non-existing rule", p); + return; + } + + delete rules[r$id,r$cid]; + delete id_to_cids[r$id][r$cid]; + if ( |id_to_cids[r$id]| == 0 ) + delete id_to_cids[r$id]; + + log_rule(r, "REMOVE", SUCCEEDED, p, msg); + } + +function rule_timeout_impl(r: Rule, i: FlowInfo, p: PluginState) { delete rules[r$id,r$cid]; delete id_to_cids[r$id][r$cid]; if ( |id_to_cids[r$id]| == 0 ) delete id_to_cids[r$id]; - log_rule(r, "REMOVE", SUCCEEDED, p); + 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(r, "EXPIRE", TIMEOUT, p, msg); } -event rule_timeout(r: Rule, i: FlowInfo, p: PluginState) - { - delete rules[r$id,r$cid]; - delete id_to_cids[r$id][r$cid]; - if ( |id_to_cids[r$id]| == 0 ) - delete id_to_cids[r$id]; - - log_rule(r, "EXPIRE", TIMEOUT, p); - } - -event rule_error(r: Rule, p: PluginState, msg: string &default="") +function rule_error_impl(r: Rule, p: PluginState, msg: string &default="") { log_rule_error(r, msg, p); # errors can occur during deletion. Since this probably means we wo't hear diff --git a/scripts/base/frameworks/netcontrol/non-cluster.bro b/scripts/base/frameworks/netcontrol/non-cluster.bro index c94e4c9e08..8e08ebe436 100644 --- a/scripts/base/frameworks/netcontrol/non-cluster.bro +++ b/scripts/base/frameworks/netcontrol/non-cluster.bro @@ -16,3 +16,32 @@ 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 && ! 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/plugins/acld.bro b/scripts/base/frameworks/netcontrol/plugins/acld.bro index 9b393f6bf9..779c3eabd0 100644 --- a/scripts/base/frameworks/netcontrol/plugins/acld.bro +++ b/scripts/base/frameworks/netcontrol/plugins/acld.bro @@ -99,7 +99,7 @@ event NetControl::acld_rule_error(id: count, r: Rule, msg: string) function acld_name(p: PluginState) : string { - return fmt("PACF acld plugin - using broker topic %s", p$acld_config$acld_topic); + return fmt("Acld-%s", p$acld_config$acld_topic); } # check that subnet specifies an addr diff --git a/scripts/base/frameworks/netcontrol/plugins/broker.bro b/scripts/base/frameworks/netcontrol/plugins/broker.bro index 959218ca3a..592c112ecc 100644 --- a/scripts/base/frameworks/netcontrol/plugins/broker.bro +++ b/scripts/base/frameworks/netcontrol/plugins/broker.bro @@ -89,7 +89,7 @@ event NetControl::broker_rule_timeout(id: count, r: Rule, i: FlowInfo) function broker_name(p: PluginState) : string { - return fmt("PACF Broker plugin - topic %s", p$broker_topic); + return fmt("Broker-%s", p$broker_topic); } function broker_add_rule_fun(p: PluginState, r: Rule) : bool diff --git a/scripts/base/frameworks/netcontrol/plugins/debug.bro b/scripts/base/frameworks/netcontrol/plugins/debug.bro index 0e42b166c0..015b7083fc 100644 --- a/scripts/base/frameworks/netcontrol/plugins/debug.bro +++ b/scripts/base/frameworks/netcontrol/plugins/debug.bro @@ -4,7 +4,7 @@ module NetControl; export { - ## Instantiates a debug plugin for the PACF framework. The debug + ## 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 diff --git a/scripts/base/frameworks/netcontrol/plugins/openflow.bro b/scripts/base/frameworks/netcontrol/plugins/openflow.bro index a9d3aad2ef..9cdc79b0ea 100644 --- a/scripts/base/frameworks/netcontrol/plugins/openflow.bro +++ b/scripts/base/frameworks/netcontrol/plugins/openflow.bro @@ -41,7 +41,7 @@ export { ## buildup for quite a while if keeping this around... const openflow_flow_timeout = 24hrs &redef; - ## Instantiates an openflow plugin for the PACF framework. + ## Instantiates an openflow plugin for the NetControl framework. global create_openflow: function(controller: OpenFlow::Controller, config: OfConfig &default=[]) : PluginState; } @@ -62,7 +62,7 @@ global of_flows: table[count] of OfTable &create_expire=openflow_flow_timeout; function openflow_name(p: PluginState) : string { - return fmt("Openflow - %s", p$of_controller$describe(p$of_controller$state)); + return fmt("Openflow-%s", p$of_controller$describe(p$of_controller$state)); } function openflow_check_rule(p: PluginState, r: Rule) : bool @@ -256,7 +256,7 @@ function openflow_rule_to_flow_mod(p: PluginState, r: Rule) : OpenFlow::ofp_flow else if ( r$ty == REDIRECT ) { # redirect to port c - flow_mod$actions$out_ports = vector(r$c); + flow_mod$actions$out_ports = vector(r$out_port); } else { diff --git a/scripts/base/frameworks/netcontrol/plugins/packetfilter.bro b/scripts/base/frameworks/netcontrol/plugins/packetfilter.bro index 2c532e4009..d3fae6c8c7 100644 --- a/scripts/base/frameworks/netcontrol/plugins/packetfilter.bro +++ b/scripts/base/frameworks/netcontrol/plugins/packetfilter.bro @@ -1,4 +1,4 @@ -# PACF plugin for the PacketFilter handling that comes with +# NetControl plugin for the PacketFilter handling 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. @@ -67,7 +67,7 @@ function packetfilter_remove_rule(p: PluginState, r: Rule) : bool { if ( ! packetfilter_check_rule(r) ) return F; - + local e = r$entity; if ( e$ty == ADDRESS ) { @@ -92,7 +92,7 @@ function packetfilter_remove_rule(p: PluginState, r: Rule) : bool function packetfilter_name(p: PluginState) : string { - return "PACF plugin for the Bro packetfilter"; + return "Packetfilter"; } global packetfilter_plugin = Plugin( diff --git a/scripts/base/frameworks/netcontrol/types.bro b/scripts/base/frameworks/netcontrol/types.bro index cb130c291b..a593c59f22 100644 --- a/scripts/base/frameworks/netcontrol/types.bro +++ b/scripts/base/frameworks/netcontrol/types.bro @@ -89,10 +89,7 @@ export { 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. - c: count &optional; ##< Argument for rule types requiring an count argument. - i: int &optional; ##< Argument for rule types requiring an integer argument. - d: double &optional; ##< Argument for rule types requiring a double argument. - s: string &optional; ##< Argument for rule types requiring a string argument. + 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. diff --git a/scripts/base/frameworks/openflow/plugins/broker.bro b/scripts/base/frameworks/openflow/plugins/broker.bro index cd7b9fecd9..dcb3d7d5a2 100644 --- a/scripts/base/frameworks/openflow/plugins/broker.bro +++ b/scripts/base/frameworks/openflow/plugins/broker.bro @@ -38,7 +38,7 @@ export { function broker_describe(state: ControllerState): string { - return fmt("Broker Plugin - %s:%d - DPID: %d", state$broker_host, state$broker_port, state$broker_dpid); + 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 diff --git a/scripts/base/frameworks/openflow/plugins/log.bro b/scripts/base/frameworks/openflow/plugins/log.bro index 5a50168a01..79cbce5fc9 100644 --- a/scripts/base/frameworks/openflow/plugins/log.bro +++ b/scripts/base/frameworks/openflow/plugins/log.bro @@ -62,7 +62,7 @@ function log_flow_mod(state: ControllerState, match: ofp_match, flow_mod: OpenFl function log_describe(state: ControllerState): string { - return fmt("OpenFlog Log Plugin - DPID %d", state$log_dpid); + return fmt("Log-%d", state$log_dpid); } function log_new(dpid: count, success_event: bool &default=T): OpenFlow::Controller diff --git a/scripts/base/frameworks/openflow/plugins/ryu.bro b/scripts/base/frameworks/openflow/plugins/ryu.bro index e6c5309bef..8b0d368683 100644 --- a/scripts/base/frameworks/openflow/plugins/ryu.bro +++ b/scripts/base/frameworks/openflow/plugins/ryu.bro @@ -173,7 +173,7 @@ function ryu_flow_clear(state: OpenFlow::ControllerState): bool function ryu_describe(state: ControllerState): string { - return fmt("Ryu Plugin - http://%s:%d - DPID: %d", state$ryu_host, state$ryu_port, state$ryu_dpid); + return fmt("Ryu-%d-http://%s:%d", state$ryu_dpid, state$ryu_host, state$ryu_port); } # Ryu controller constructor 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 index db2859c4b5..f17d8fad9f 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld/recv.recv.out +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld/recv.recv.out @@ -1,7 +1,7 @@ BrokerComm::incoming_connection_established -add_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=, dst_h=74.53.140.153/32, dst_p=, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1], [command=blockhosthost, cookie=2, arg=10.10.1.4 74.53.140.153, comment=here] -add_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1], [command=droptcpport, cookie=3, arg=25, comment=here] -add_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1], [command=drop, cookie=4, arg=10.10.1.4/32, comment=] -remove_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=, dst_h=74.53.140.153/32, dst_p=, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1], [command=restorehosthost, cookie=2, arg=10.10.1.4 74.53.140.153, comment=here] -remove_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1], [command=restoretcpport, cookie=3, arg=25, comment=here] -remove_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1], [command=restore, cookie=4, arg=10.10.1.4/32, comment=] +add_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[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=], expire=36000.0, priority=0, location=here, out_port=, mod=, id=2, cid=2, _plugin_id=1], [command=blockhosthost, cookie=2, arg=192.168.18.50 74.125.239.97, comment=here] +add_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=there, out_port=, mod=, id=3, cid=3, _plugin_id=1], [command=droptcpport, cookie=3, arg=443, comment=there] +add_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=4, cid=4, _plugin_id=1], [command=drop, cookie=4, arg=192.168.18.50/32, comment=] +remove_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[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=], expire=36000.0, priority=0, location=here, out_port=, mod=, id=2, cid=2, _plugin_id=1], [command=restorehosthost, cookie=2, arg=192.168.18.50 74.125.239.97, comment=here] +remove_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=there, out_port=, mod=, id=3, cid=3, _plugin_id=1], [command=restoretcpport, cookie=3, arg=443, comment=there] +remove_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=4, cid=4, _plugin_id=1], [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 index b823dd0aee..edb28710a4 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld/send.send.out +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld/send.send.out @@ -1,7 +1,7 @@ BrokerComm::outgoing_connection_established, 127.0.0.1, 9999/tcp -rule added, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=, dst_h=74.53.140.153/32, dst_p=, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] -rule added, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] -rule added, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1] -rule removed, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=10.10.1.4/32, src_p=, dst_h=74.53.140.153/32, dst_p=, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] -rule removed, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=25/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=here, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] -rule removed, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1] +rule added, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[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=], expire=36000.0, priority=0, location=here, out_port=, mod=, id=2, cid=2, _plugin_id=1] +rule added, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=there, out_port=, mod=, id=3, cid=3, _plugin_id=1] +rule added, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=4, cid=4, _plugin_id=1] +rule removed, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[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=], expire=36000.0, priority=0, location=here, out_port=, mod=, id=2, cid=2, _plugin_id=1] +rule removed, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=there, out_port=, mod=, id=3, cid=3, _plugin_id=1] +rule removed, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=4, cid=4, _plugin_id=1] 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 index 2007630489..fe29252480 100644 --- 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 @@ -3,30 +3,24 @@ #empty_field (empty) #unset_field - #path netcontrol -#open 2015-07-08-19-33-09 -#fields ts category cmd state action target entity_type entity msg location plugin -#types time enum string enum string enum string string string string string -1436383989.876677 NetControl::MESSAGE - - - - - - activated plugin with priority 0 - Debug-All -1436383992.255152 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1436383992.255152 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1436383992.255152 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1436383992.255152 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1436383994.376366 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1436383994.376366 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1436383994.376366 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1436383994.376366 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1436383991.768500 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1436383991.768500 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1436383993.849722 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1436383993.849722 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1436383993.813850 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1436383993.813850 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1436384002.162435 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1436384002.162435 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1436384002.162435 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1436384002.162435 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1436384002.162435 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1436384002.162435 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1436384002.162435 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1436384002.162435 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -#close 2015-07-08-19-33-22 +#open 2016-02-12-00-47-14 +#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 +1455238034.228329 - NetControl::MESSAGE - - - - - - - activated plugin with priority 0 - - - Debug-All +1455238036.276570 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 30.000000 - Debug-All +1455238036.276570 worker-1:3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All +1455238036.276570 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 30.000000 - Debug-All +1455238036.276570 worker-1:3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All +1455238038.340995 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 30.000000 - Debug-All +1455238038.340995 worker-2:3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All +1455238038.340995 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 30.000000 - Debug-All +1455238038.340995 worker-2:3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All +1455238038.865312 worker-1:3 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All +1455238038.865312 worker-2:3 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All +1455238038.865312 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 30.000000 - Debug-All +1455238038.865312 worker-2: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 30.000000 - Debug-All +1455238038.865312 worker-1:3 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All +1455238038.865312 worker-2:3 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All +1455238038.865312 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 30.000000 - Debug-All +1455238038.865312 worker-2: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 30.000000 - Debug-All +#close 2016-02-12-00-47-18 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/worker-1..stdout b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/worker-1..stdout deleted file mode 100644 index 52871d66f0..0000000000 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/worker-1..stdout +++ /dev/null @@ -1,4 +0,0 @@ -Rule added, worker-1:2, 2 -Rule added, worker-1:3, 3 -Rule added, worker-2:2, 4 -Rule added, worker-2:3, 5 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/worker-2..stdout b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/worker-2..stdout deleted file mode 100644 index 938eac9557..0000000000 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic-cluster/worker-2..stdout +++ /dev/null @@ -1,2 +0,0 @@ -Rule added, worker-2:2, 4 -Rule added, worker-2:3, 5 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/.stdout b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/.stdout index 0964f600f4..4322b62392 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/.stdout +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/.stdout @@ -1,9 +1,21 @@ 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=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=], expire=30.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] -netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] -netcontrol debug (Debug-All): add_rule: [ty=NetControl::WHITELIST, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=5, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1] -netcontrol debug (Debug-All): add_rule: [ty=NetControl::REDIRECT, target=NetControl::FORWARD, entity=[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=], expire=30.0 secs, priority=0, location=, c=5, i=, d=, s=, mod=, id=5, cid=5, _plugin_id=1] -netcontrol debug (Debug-All): remove_rule: [ty=NetControl::WHITELIST, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=5, location=, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1] -netcontrol debug (Debug-All): remove_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=15.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] -netcontrol debug (Debug-All): remove_rule: [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[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=], expire=30.0 secs, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] -netcontrol debug (Debug-All): remove_rule: [ty=NetControl::REDIRECT, target=NetControl::FORWARD, entity=[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=], expire=30.0 secs, priority=0, location=, c=5, i=, d=, s=, mod=, id=5, cid=5, _plugin_id=1] +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_id=1] +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_id=1] +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_id=1] +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_id=1] +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_id=1] +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_id=1] +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_id=1] +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_id=1] +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_id=1] +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_id=1] +netcontrol debug (Debug-All): remove_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_id=1] +netcontrol debug (Debug-All): remove_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_id=1] +netcontrol debug (Debug-All): remove_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_id=1] +netcontrol debug (Debug-All): remove_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_id=1] +netcontrol debug (Debug-All): remove_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_id=1] +netcontrol debug (Debug-All): remove_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_id=1] +netcontrol debug (Debug-All): remove_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_id=1] +netcontrol debug (Debug-All): remove_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_id=1] +netcontrol debug (Debug-All): remove_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_id=1] +netcontrol debug (Debug-All): remove_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_id=1] diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol.log index 379eb0845b..ebeb4a59ee 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol.log +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol.log @@ -2,25 +2,49 @@ #set_separator , #empty_field (empty) #unset_field - -#path pacf -#open 2015-06-01-22-57-07 -#fields ts category cmd state action target entity_type entity msg location plugin -#types time enum string enum string enum string string string string string -0.000000 NetControl::MESSAGE - - - - - - activated plugin with priority 0 - Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -#close 2015-06-01-22-57-07 +#path netcontrol +#open 2016-02-12-00-21-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 +1455236494.855016 - NetControl::MESSAGE - - - - - - - activated plugin with priority 0 - - - Debug-All +1455236494.855016 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 +1455236494.855016 3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 1.1.2.2/32 - - 0 15.000000 Hi there Debug-All +1455236494.855016 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 1.2.3.4/32 - - 5 15.000000 - Debug-All +1455236494.855016 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 +1455236494.855016 6 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->*/* - - 0 15.000000 - Debug-All +1455236494.855016 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 +1455236494.855016 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 +1455236494.855016 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 +1455236494.855016 10 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::MAC FF:FF:FF:FF:FF:FF - - 0 15.000000 - Debug-All +1455236494.855016 11 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::FLOW */*->*/* (FF:FF:FF:FF:FF:FF->*) - - 0 15.000000 - Debug-All +1455236494.855016 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 +1455236494.855016 3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 1.1.2.2/32 - - 0 15.000000 Hi there Debug-All +1455236494.855016 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 1.2.3.4/32 - - 5 15.000000 - Debug-All +1455236494.855016 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 +1455236494.855016 6 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->*/* - - 0 15.000000 - Debug-All +1455236494.855016 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 +1455236494.855016 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 +1455236494.855016 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 +1455236494.855016 10 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::MAC FF:FF:FF:FF:FF:FF - - 0 15.000000 - Debug-All +1455236494.855016 11 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::FLOW */*->*/* (FF:FF:FF:FF:FF:FF->*) - - 0 15.000000 - Debug-All +1455236494.855016 7 NetControl::RULE REMOVE 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 +1455236494.855016 8 NetControl::RULE REMOVE 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 +1455236494.855016 3 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 1.1.2.2/32 - - 0 15.000000 Hi there Debug-All +1455236494.855016 9 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->127.0.0.3/32/80 - - 5 15.000000 - Debug-All +1455236494.855016 11 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::FLOW */*->*/* (FF:FF:FF:FF:FF:FF->*) - - 0 15.000000 - Debug-All +1455236494.855016 6 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->*/* - - 0 15.000000 - Debug-All +1455236494.855016 10 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::MAC FF:FF:FF:FF:FF:FF - - 0 15.000000 - Debug-All +1455236494.855016 4 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 1.2.3.4/32 - - 5 15.000000 - Debug-All +1455236494.855016 5 NetControl::RULE REMOVE 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 +1455236494.855016 2 NetControl::RULE REMOVE 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 +1455236494.855016 7 NetControl::RULE REMOVE 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 +1455236494.855016 8 NetControl::RULE REMOVE 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 +1455236494.855016 3 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 1.1.2.2/32 - - 0 15.000000 Hi there Debug-All +1455236494.855016 9 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->127.0.0.3/32/80 - - 5 15.000000 - Debug-All +1455236494.855016 11 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::FLOW */*->*/* (FF:FF:FF:FF:FF:FF->*) - - 0 15.000000 - Debug-All +1455236494.855016 6 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->*/* - - 0 15.000000 - Debug-All +1455236494.855016 10 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::MAC FF:FF:FF:FF:FF:FF - - 0 15.000000 - Debug-All +1455236494.855016 4 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 1.2.3.4/32 - - 5 15.000000 - Debug-All +1455236494.855016 5 NetControl::RULE REMOVE 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 +1455236494.855016 2 NetControl::RULE REMOVE 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 +#close 2016-02-12-00-21-34 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 index 1d97db6024..c6d61a3a14 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/recv.recv.out +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/recv.recv.out @@ -1,5 +1,5 @@ BrokerComm::incoming_connection_established -add_rule, 0, [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] -add_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] -remove_rule, 0, [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] -remove_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] +add_rule, 0, [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[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=], expire=36000.0, priority=0, location=, out_port=, mod=, id=2, cid=2, _plugin_id=1] +add_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=3, cid=3, _plugin_id=1] +remove_rule, 0, [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[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=], expire=36000.0, priority=0, location=, out_port=, mod=, id=2, cid=2, _plugin_id=1] +remove_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=3, cid=3, _plugin_id=1] 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..a44788e7b1 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/send.netcontrol.log @@ -0,0 +1,20 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path netcontrol +#open 2016-02-12-03-43-39 +#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 - - - - - - - activated plugin with priority 0 - - - Broker-bro/event/netcontroltest +1455248619.521854 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 +1455248619.521854 3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - - 0 36000.000000 - Broker-bro/event/netcontroltest +1455248619.521886 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 +1455248619.521886 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 +1455248619.521886 3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - - 0 36000.000000 - Broker-bro/event/netcontroltest +1455248619.521886 3 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - - 0 36000.000000 - Broker-bro/event/netcontroltest +1455248619.521886 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 +1455248619.521886 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 +1455248619.521886 3 NetControl::RULE EXPIRE NetControl::TIMEOUT NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - - 0 36000.000000 - Broker-bro/event/netcontroltest +1455248619.521886 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-02-12-03-43-39 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 index 826819877b..65f523ea94 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/send.send.out +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/send.send.out @@ -1,7 +1,7 @@ BrokerComm::outgoing_connection_established, 127.0.0.1, 9999/tcp -rule added, [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] -rule added, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] -rule timeout, [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1], [duration=, packet_count=, byte_count=] -rule removed, [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[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=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] -rule timeout, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1], [duration=, packet_count=, byte_count=] -rule removed, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] +rule added, [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[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=], expire=36000.0, priority=0, location=, out_port=, mod=, id=2, cid=2, _plugin_id=1] +rule added, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=3, cid=3, _plugin_id=1] +rule timeout, [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[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=], expire=36000.0, priority=0, location=, out_port=, mod=, id=2, cid=2, _plugin_id=1], [duration=, packet_count=, byte_count=] +rule removed, [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[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=], expire=36000.0, priority=0, location=, out_port=, mod=, id=2, cid=2, _plugin_id=1] +rule timeout, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=3, cid=3, _plugin_id=1], [duration=, packet_count=, byte_count=] +rule removed, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=3, cid=3, _plugin_id=1] diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.catch-and-release/.stdout b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.catch-and-release/.stdout index 2570a5edc1..17c390799f 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.catch-and-release/.stdout +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.catch-and-release/.stdout @@ -1,11 +1,11 @@ netcontrol debug (Debug-All): init -netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=10.0 mins, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] -netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=1.0 hr, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] -netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=1.0 day, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1] -netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=7.0 days, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=5, cid=5, _plugin_id=1] -netcontrol debug (Debug-All): add_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=7.0 days, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=6, cid=6, _plugin_id=1] -netcontrol debug (Debug-All): remove_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=10.0 mins, priority=0, location=, c=, i=, d=, s=, mod=, id=2, cid=2, _plugin_id=1] -netcontrol debug (Debug-All): remove_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=1.0 hr, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=3, cid=3, _plugin_id=1] -netcontrol debug (Debug-All): remove_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=1.0 day, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=4, cid=4, _plugin_id=1] -netcontrol debug (Debug-All): remove_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=7.0 days, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=6, cid=6, _plugin_id=1] -netcontrol debug (Debug-All): remove_rule: [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=7.0 days, priority=0, location=Re-drop by catch-and-release, c=, i=, d=, s=, mod=, id=5, cid=5, _plugin_id=1] +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=10.0 mins, priority=0, location=, out_port=, mod=, id=2, cid=2, _plugin_id=1] +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=1.0 hr, priority=0, location=Re-drop by catch-and-release, out_port=, mod=, id=3, cid=3, _plugin_id=1] +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=1.0 day, priority=0, location=Re-drop by catch-and-release, out_port=, mod=, id=4, cid=4, _plugin_id=1] +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=7.0 days, priority=0, location=Re-drop by catch-and-release, out_port=, mod=, id=5, cid=5, _plugin_id=1] +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=7.0 days, priority=0, location=Re-drop by catch-and-release, out_port=, mod=, id=6, cid=6, _plugin_id=1] +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=10.0 mins, priority=0, location=, out_port=, mod=, id=2, cid=2, _plugin_id=1] +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=1.0 hr, priority=0, location=Re-drop by catch-and-release, out_port=, mod=, id=3, cid=3, _plugin_id=1] +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=1.0 day, priority=0, location=Re-drop by catch-and-release, out_port=, mod=, id=4, cid=4, _plugin_id=1] +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=7.0 days, priority=0, location=Re-drop by catch-and-release, out_port=, mod=, id=6, cid=6, _plugin_id=1] +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=7.0 days, priority=0, location=Re-drop by catch-and-release, out_port=, mod=, id=5, cid=5, _plugin_id=1] 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 index dff4c85769..ceb8f0e3c4 100644 --- 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 @@ -2,29 +2,29 @@ #set_separator , #empty_field (empty) #unset_field - -#path pacf -#open 2015-06-02-22-02-42 -#fields ts category cmd state action target entity_type entity msg location plugin -#types time enum string enum string enum string string string string string -0.000000 NetControl::MESSAGE - - - - - - activated plugin with priority 0 - Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - Re-drop by catch-and-release Debug-All -#close 2015-06-02-22-02-42 +#path netcontrol +#open 2016-02-12-03-24-03 +#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 - - - - - - - activated plugin with priority 0 - - - Debug-All +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 ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 3600.000000 Re-drop by catch-and-release Debug-All +1398529018.678276 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 86400.000000 Re-drop by catch-and-release Debug-All +1398529018.678276 5 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 604800.000000 Re-drop by catch-and-release Debug-All +1398529018.678276 6 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 604800.000000 Re-drop by catch-and-release Debug-All +1398529018.678276 2 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 600.000000 - Debug-All +1398529018.678276 3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 3600.000000 Re-drop by catch-and-release Debug-All +1398529018.678276 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 86400.000000 Re-drop by catch-and-release Debug-All +1398529018.678276 5 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 604800.000000 Re-drop by catch-and-release Debug-All +1398529018.678276 6 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 604800.000000 Re-drop by catch-and-release Debug-All +1398529020.164464 2 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 600.000000 - Debug-All +1398529020.164464 3 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 3600.000000 Re-drop by catch-and-release Debug-All +1398529020.164464 4 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 86400.000000 Re-drop by catch-and-release Debug-All +1398529020.164464 6 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 604800.000000 Re-drop by catch-and-release Debug-All +1398529020.164464 5 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 604800.000000 Re-drop by catch-and-release Debug-All +1398529020.164464 2 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 600.000000 - Debug-All +1398529020.164464 3 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 3600.000000 Re-drop by catch-and-release Debug-All +1398529020.164464 4 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 86400.000000 Re-drop by catch-and-release Debug-All +1398529020.164464 6 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 604800.000000 Re-drop by catch-and-release Debug-All +1398529020.164464 5 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 604800.000000 Re-drop by catch-and-release Debug-All +#close 2016-02-12-03-24-03 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.hook/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.hook/netcontrol.log index 2f39a2623f..e98ec69983 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.hook/netcontrol.log +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.hook/netcontrol.log @@ -3,16 +3,16 @@ #empty_field (empty) #unset_field - #path netcontrol -#open 2015-07-08-19-33-47 -#fields ts category cmd state action target entity_type entity msg location plugin -#types time enum string enum string enum string string string string string -0.000000 NetControl::MESSAGE - - - - - - activated plugin with priority 0 - Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 0.0.0.0/0/1470->74.53.140.153/32/25 - (empty) Debug-All -#close 2015-07-08-19-33-48 +#open 2016-02-12-03-22-09 +#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 - - - - - - - activated plugin with priority 0 - - - Debug-All +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 +1398529020.164464 5 NetControl::RULE REMOVE 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 +1398529020.164464 2 NetControl::RULE REMOVE 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 +1398529020.164464 5 NetControl::RULE REMOVE 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 +1398529020.164464 2 NetControl::RULE REMOVE 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 +#close 2016-02-12-03-22-09 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/netcontrol.log index f2d13a8251..40e6c0e82d 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/netcontrol.log +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/netcontrol.log @@ -2,35 +2,35 @@ #set_separator , #empty_field (empty) #unset_field - -#path pacf -#open 2015-06-02-19-34-04 -#fields ts category cmd state action target entity_type entity msg location plugin -#types time enum string enum string enum string string string string string -0.000000 NetControl::MESSAGE - - - - - - activated plugin with priority 10 - Debug-All -0.000000 NetControl::MESSAGE - - - - - - activated plugin with priority 10 - Openflow - OpenFlog Log Plugin - DPID 42 -0.000000 NetControl::MESSAGE - - - - - - activated plugin with priority 0 - Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::REDIRECT NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -1254722776.690444 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Debug-All -#close 2015-06-02-19-34-04 +#path netcontrol +#open 2016-02-12-03-43-55 +#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 - - - - - - - activated plugin with priority 10 - - - Debug-All +0.000000 - NetControl::MESSAGE - - - - - - - activated plugin with priority 10 - - - Openflow-Log-42 +0.000000 - NetControl::MESSAGE - - - - - - - activated plugin with priority 0 - - - 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 30.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 30.000000 - Openflow-Log-42 +1398529018.678276 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All +1398529018.678276 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Openflow-Log-42 +1398529018.678276 6 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 15.000000 - Debug-All +1398529018.678276 6 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 15.000000 - Openflow-Log-42 +1398529018.678276 8 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 30.000000 - Debug-All +1398529018.678276 8 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 30.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 30.000000 - Debug-All +1398529018.678276 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All +1398529018.678276 6 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 15.000000 - Debug-All +1398529018.678276 8 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 30.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 30.000000 - Openflow-Log-42 +1398529018.678276 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Openflow-Log-42 +1398529018.678276 6 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 15.000000 - Openflow-Log-42 +1398529018.678276 8 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 30.000000 - Openflow-Log-42 +1398529020.164464 4 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All +1398529020.164464 6 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 15.000000 - Debug-All +1398529020.164464 8 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 30.000000 - Debug-All +1398529020.164464 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 30.000000 - Debug-All +1398529020.164464 4 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All +1398529020.164464 6 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 15.000000 - Debug-All +1398529020.164464 8 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 30.000000 - Debug-All +1398529020.164464 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 30.000000 - Debug-All +#close 2016-02-12-03-43-55 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/netcontrol.log index bd774345d9..c31024e8d9 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/netcontrol.log +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/netcontrol.log @@ -3,20 +3,20 @@ #empty_field (empty) #unset_field - #path netcontrol -#open 2016-02-11-21-07-34 -#fields ts category cmd state action target entity_type entity msg location plugin -#types time enum string enum string enum string string string string string -0.000000 NetControl::MESSAGE - - - - - - activated plugin with priority 0 - Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 10.10.1.4/32/1470->74.53.140.153/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1437831787.861602 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.133.100/32/49648->192.168.133.102/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1437831787.861602 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.133.100/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1437831787.861602 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.133.100/32/49648->192.168.133.102/32/25 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1437831787.861602 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.133.100/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1437831799.610433 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.133.100/32/49655->17.167.150.73/32/443 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1437831799.610433 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.133.100/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1437831799.610433 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::MONITOR NetControl::FLOW 192.168.133.100/32/49655->17.167.150.73/32/443 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1437831799.610433 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.133.100/32 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -#close 2016-02-11-21-07-34 +#open 2016-02-12-03-44-04 +#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 - - - - - - - activated plugin with priority 0 - - - 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 10.10.1.4/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 10.10.1.4/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.100/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.100/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 192.168.133.100/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 192.168.133.100/32 - - 0 15.000000 - Openflow-Log-42 +#close 2016-02-12-03-44-04 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.packetfilter/conn.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.packetfilter/conn.log index 1f51ecc2fd..f4674275e9 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.packetfilter/conn.log +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.packetfilter/conn.log @@ -3,10 +3,12 @@ #empty_field (empty) #unset_field - #path conn -#open 2015-05-12-22-11-25 +#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) -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) 1254722776.690444 CCvvfg3TEfuqmmG4bh 10.10.1.20 138 10.10.1.255 138 udp - - - - S0 - - 0 D 1 229 0 0 (empty) -#close 2015-05-12-22-11-25 +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 index 74f45e41ec..2a68c2a4b3 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.quarantine-openflow/netcontrol.log +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.quarantine-openflow/netcontrol.log @@ -3,16 +3,16 @@ #empty_field (empty) #unset_field - #path netcontrol -#open 2015-07-08-19-33-55 -#fields ts category cmd state action target entity_type entity msg location plugin -#types time enum string enum string enum string string string string string -0.000000 NetControl::MESSAGE - - - - - - activated plugin with priority 0 - Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/*->*/* - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::MODIFY NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/*->8.8.8.8/32/53 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::MODIFY NetControl::FORWARD NetControl::FLOW 8.8.8.8/32/53->10.10.1.4/32/* - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/*->192.169.18.1/32/80 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/*->*/* - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::MODIFY NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/*->8.8.8.8/32/53 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::MODIFY NetControl::FORWARD NetControl::FLOW 8.8.8.8/32/53->10.10.1.4/32/* - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -1254722767.875996 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::FLOW 10.10.1.4/32/*->192.169.18.1/32/80 - (empty) Openflow - OpenFlog Log Plugin - DPID 42 -#close 2015-07-08-19-33-55 +#open 2016-02-12-03-44-17 +#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 - - - - - - - activated plugin with priority 0 - - - 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-02-12-03-44-17 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 index 1b4081a31d..64d6cabaf5 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.quarantine-openflow/openflow.log +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.quarantine-openflow/openflow.log @@ -3,11 +3,11 @@ #empty_field (empty) #unset_field - #path openflow -#open 2015-06-04-23-21-03 +#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 -1254722767.875996 42 - - - - - 2048 - - 10.10.1.4/32 - - - 4398046511108 - OpenFlow::OFPFC_ADD 0 36000 0 - - 1 (empty) - - F - - - - - - - -1254722767.875996 42 - - - - - 2048 - 17 10.10.1.4/32 8.8.8.8/32 - 53 4398046511110 - OpenFlow::OFPFC_ADD 0 36000 5 - - 1 4294967290 - - F - - - - 192.169.18.1 - - -1254722767.875996 42 - - - - - 2048 - 17 8.8.8.8/32 10.10.1.4/32 53 - 4398046511112 - OpenFlow::OFPFC_ADD 0 36000 5 - - 1 4294967290 - - F - - - 8.8.8.8 - - - -1254722767.875996 42 - - - - - 2048 - 6 10.10.1.4/32 192.169.18.1/32 - 80 4398046511114 - OpenFlow::OFPFC_ADD 0 36000 5 - - 1 4294967290 - - F - - - - - - - -#close 2015-06-04-23-21-03 +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/scripts/base/frameworks/netcontrol/acld.bro b/testing/btest/scripts/base/frameworks/netcontrol/acld.bro index c6aabfd2a2..d799b36d30 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/acld.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/acld.bro @@ -1,7 +1,7 @@ # @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-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 @@ -50,7 +50,7 @@ event connection_established(c: connection) $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="here"]; + local r2: NetControl::Rule = [$ty=NetControl::DROP, $target=NetControl::FORWARD, $entity=e2, $expire=10hrs, $location="there"]; NetControl::add_rule(r1); NetControl::add_rule(r2); diff --git a/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro b/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro index 3047416bac..df275307ee 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro @@ -2,13 +2,11 @@ # # @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-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/smtp.trace %INPUT" +# @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-EXEC: btest-diff worker-1/.stdout -# @TEST-EXEC: btest-diff worker-2/.stdout @TEST-START-FILE cluster-layout.bro redef Cluster::nodes = { diff --git a/testing/btest/scripts/base/frameworks/netcontrol/basic.bro b/testing/btest/scripts/base/frameworks/netcontrol/basic.bro index f1f63b3d99..c32cb1d7c6 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/basic.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/basic.bro @@ -1,6 +1,6 @@ -# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT -# @TEST-EXEC: TEST_DIFF_CANONIFIER='grep -v ^# | $SCRIPTS/diff-sort' btest-diff netcontrol.log -# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff .stdout +# @TEST-EXEC: bro %INPUT +# @TEST-EXEC: btest-diff netcontrol.log +# @TEST-EXEC: btest-diff .stdout @load base/frameworks/netcontrol @@ -10,11 +10,33 @@ event bro_init() NetControl::activate(netcontrol_debug, 0); } -event connection_established(c: connection) +function test_mac_flow() { - 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); + 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 bro_init() &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 index f675a0fd13..7546977344 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/broker.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/broker.bro @@ -4,6 +4,7 @@ # @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 diff --git a/testing/btest/scripts/base/frameworks/netcontrol/catch-and-release.bro b/testing/btest/scripts/base/frameworks/netcontrol/catch-and-release.bro index e5ce73410f..318d87803f 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/catch-and-release.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/catch-and-release.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT +# @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: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff .stdout diff --git a/testing/btest/scripts/base/frameworks/netcontrol/hook.bro b/testing/btest/scripts/base/frameworks/netcontrol/hook.bro index d859f8a089..5ad0fe85e8 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/hook.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/hook.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT +# @TEST-EXEC: bro -r $TRACES/tls/ecdhe.pcap %INPUT # @TEST-EXEC: btest-diff netcontrol.log @load base/frameworks/netcontrol diff --git a/testing/btest/scripts/base/frameworks/netcontrol/multiple.bro b/testing/btest/scripts/base/frameworks/netcontrol/multiple.bro index d8676c07ab..c2d209ca38 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/multiple.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/multiple.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT +# @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 diff --git a/testing/btest/scripts/base/frameworks/netcontrol/quarantine-openflow.bro b/testing/btest/scripts/base/frameworks/netcontrol/quarantine-openflow.bro index ced53f441e..d9fb1fd62c 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/quarantine-openflow.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/quarantine-openflow.bro @@ -1,4 +1,4 @@ -# @TEST-EXEC: bro -r $TRACES/smtp.trace %INPUT +# @TEST-EXEC: bro -r $TRACES/tls/ecdhe.pcap %INPUT # @TEST-EXEC: btest-diff netcontrol.log # @TEST-EXEC: btest-diff openflow.log From 8f60974bc017b5153e2457aff95c2fae26244fbc Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 17 Feb 2016 12:47:42 -0800 Subject: [PATCH 64/93] Add new logfiles for shunting and drops to netcontrol Also fix small bugs and update baselines. --- .../base/frameworks/netcontrol/__load__.bro | 2 + .../netcontrol/catch-and-release.bro | 3 + scripts/base/frameworks/netcontrol/drop.bro | 98 ++++++++++++++++ scripts/base/frameworks/netcontrol/main.bro | 73 +----------- .../frameworks/netcontrol/plugins/acld.bro | 1 + .../frameworks/netcontrol/plugins/broker.bro | 1 + .../frameworks/netcontrol/plugins/debug.bro | 1 + .../netcontrol/plugins/openflow.bro | 1 + scripts/base/frameworks/netcontrol/shunt.bro | 69 +++++++++++ .../base/frameworks/openflow/plugins/log.bro | 2 +- scripts/base/init-bare.bro | 2 +- .../canonified_loaded_scripts.log | 28 ++++- .../btest/Baseline/coverage.find-bro-logs/out | 4 + .../coverage.init-default/missing_loads | 2 + testing/btest/Baseline/plugins.hooks/output | 107 +++++++++++++++++- .../netcontrol_drop.log | 10 ++ .../netcontrol_shunt.log | 10 ++ .../netcontrol.log | 57 +++++----- .../base/frameworks/netcontrol/basic.bro | 2 + .../base/frameworks/netcontrol/multiple.bro | 19 +++- 20 files changed, 385 insertions(+), 107 deletions(-) create mode 100644 scripts/base/frameworks/netcontrol/drop.bro create mode 100644 scripts/base/frameworks/netcontrol/shunt.bro create mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol_drop.log create mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol_shunt.log diff --git a/scripts/base/frameworks/netcontrol/__load__.bro b/scripts/base/frameworks/netcontrol/__load__.bro index 7bfd6aed7e..a8e391f7c8 100644 --- a/scripts/base/frameworks/netcontrol/__load__.bro +++ b/scripts/base/frameworks/netcontrol/__load__.bro @@ -1,6 +1,8 @@ @load ./types @load ./main @load ./plugins +@load ./drop +@load ./shunt @load ./catch-and-release # The cluster framework must be loaded first. diff --git a/scripts/base/frameworks/netcontrol/catch-and-release.bro b/scripts/base/frameworks/netcontrol/catch-and-release.bro index 608f18ac19..aec39fd4d1 100644 --- a/scripts/base/frameworks/netcontrol/catch-and-release.bro +++ b/scripts/base/frameworks/netcontrol/catch-and-release.bro @@ -2,6 +2,9 @@ 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 diff --git a/scripts/base/frameworks/netcontrol/drop.bro b/scripts/base/frameworks/netcontrol/drop.bro new file mode 100644 index 0000000000..70096b711b --- /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 index cdbc60541e..82a4b5e225 100644 --- a/scripts/base/frameworks/netcontrol/main.bro +++ b/scripts/base/frameworks/netcontrol/main.bro @@ -35,38 +35,8 @@ export { # ### High-level API. # ### - ## 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; - - ## 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; + # ### 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. ## @@ -142,7 +112,7 @@ export { ## ## id: The rule to remove, specified as the ID returned by :bro:id:`add_rule` . ## - ## Returns: True if succesful, the relevant plugin indicated that ity knew how + ## 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. @@ -250,9 +220,6 @@ export { plugin: string &log &optional; }; -# type ShuntInfo: record { -# ## Time at which the recorded activity occurred. -# ts: time &log; ## Event that can be handled to access the :bro:type:`NetControl::Info` ## record as it is sent on to the logging framework. @@ -266,15 +233,16 @@ redef record Rule += { global plugins: vector of PluginState; global plugin_ids: table[count] of PluginState; + global rule_counter: count = 1; global plugin_counter: count = 1; + global rules: table[string,count] of Rule; # Rules indexed by id and cid global id_to_cids: table[string] of set[count]; # id to cid event bro_init() &priority=5 { Log::create_stream(NetControl::LOG, [$columns=Info, $ev=log_netcontrol, $path="netcontrol"]); -# Log::create_stream(NetControl::SHUNT, [$columns=ShuntInfo, $ev=log_netcontrol_shung, $path="netcontrol_shunt"]); } function entity_to_info(info: Info, e: Entity) @@ -422,22 +390,6 @@ function log_rule_no_plugin(r: Rule, state: InfoState, msg: string) Log::write(LOG, info); } -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]; - - return add_rule(r); - } - -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]; - - return add_rule(r); - } - function whitelist_address(a: addr, t: interval, location: string &default="") : string { local e: Entity = [$ty=ADDRESS, $ip=addr_to_subnet(a)]; @@ -454,19 +406,6 @@ function whitelist_subnet(s: subnet, t: interval, location: string &default="") return add_rule(r); } -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]; - - return add_rule(r); - } function redirect_flow(f: flow_id, out_port: count, t: interval, location: string &default="") : string { @@ -517,7 +456,7 @@ function activate_impl(p: PluginState, priority: int) p$_id = plugin_counter; ++plugin_counter; - # perform one-timi initialization + # perform one-time initialization if ( p$plugin?$init ) p$plugin$init(p); diff --git a/scripts/base/frameworks/netcontrol/plugins/acld.bro b/scripts/base/frameworks/netcontrol/plugins/acld.bro index 779c3eabd0..2a524ee664 100644 --- a/scripts/base/frameworks/netcontrol/plugins/acld.bro +++ b/scripts/base/frameworks/netcontrol/plugins/acld.bro @@ -2,6 +2,7 @@ module NetControl; +@load ../main @load ../plugin @load base/frameworks/broker diff --git a/scripts/base/frameworks/netcontrol/plugins/broker.bro b/scripts/base/frameworks/netcontrol/plugins/broker.bro index 592c112ecc..ebb157c763 100644 --- a/scripts/base/frameworks/netcontrol/plugins/broker.bro +++ b/scripts/base/frameworks/netcontrol/plugins/broker.bro @@ -4,6 +4,7 @@ module NetControl; +@load ../main @load ../plugin @load base/frameworks/broker diff --git a/scripts/base/frameworks/netcontrol/plugins/debug.bro b/scripts/base/frameworks/netcontrol/plugins/debug.bro index 015b7083fc..430f191e16 100644 --- a/scripts/base/frameworks/netcontrol/plugins/debug.bro +++ b/scripts/base/frameworks/netcontrol/plugins/debug.bro @@ -1,5 +1,6 @@ @load ../plugin +@load ../main module NetControl; diff --git a/scripts/base/frameworks/netcontrol/plugins/openflow.bro b/scripts/base/frameworks/netcontrol/plugins/openflow.bro index 9cdc79b0ea..2ec12dd4b9 100644 --- a/scripts/base/frameworks/netcontrol/plugins/openflow.bro +++ b/scripts/base/frameworks/netcontrol/plugins/openflow.bro @@ -1,3 +1,4 @@ +@load ../main @load ../plugin @load base/frameworks/openflow diff --git a/scripts/base/frameworks/netcontrol/shunt.bro b/scripts/base/frameworks/netcontrol/shunt.bro new file mode 100644 index 0000000000..38880d8608 --- /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/openflow/plugins/log.bro b/scripts/base/frameworks/openflow/plugins/log.bro index 79cbce5fc9..f40c773226 100644 --- a/scripts/base/frameworks/openflow/plugins/log.bro +++ b/scripts/base/frameworks/openflow/plugins/log.bro @@ -68,7 +68,7 @@ function log_describe(state: ControllerState): string 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, $flow_clear=ryu_flow_clear, $describe=log_describe, $supports_flow_removed=F); + $flow_mod=log_flow_mod, $describe=log_describe, $supports_flow_removed=F); register_controller(OpenFlow::OFLOG, cat(dpid), c); diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 53e33f5621..1df4399922 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -130,7 +130,7 @@ type flow_id : record { 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/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/plugins.hooks/output b/testing/btest/Baseline/plugins.hooks/output index 7a5718b1db..b247670177 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=1455741196.212164, 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,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=1455741196.212164, node=bro, filter=ip or not ip, init=T, success=T])) -> 0.000000 MetaHookPost CallFunction(Notice::want_pp, , ()) -> 0.000000 MetaHookPost CallFunction(PacketFilter::build, , ()) -> 0.000000 MetaHookPost CallFunction(PacketFilter::combine_filters, , (ip or not ip, and, )) -> @@ -361,6 +381,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 +455,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 +472,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 +489,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 +500,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 +521,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 +581,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 @@ -756,8 +792,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 +831,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 +856,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=1455741196.212164, 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 +871,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 +910,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 +949,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 +974,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=1455741196.212164, node=bro, filter=ip or not ip, init=T, success=T])) 0.000000 MetaHookPre CallFunction(Notice::want_pp, , ()) 0.000000 MetaHookPre CallFunction(PacketFilter::build, , ()) 0.000000 MetaHookPre CallFunction(PacketFilter::combine_filters, , (ip or not ip, and, )) @@ -953,6 +1009,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 +1083,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 +1100,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 +1117,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 +1128,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 +1149,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 +1209,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) @@ -1347,8 +1419,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 +1458,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 +1483,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=1455741196.212164, 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 +1498,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 +1537,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 +1576,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 +1601,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=1455741196.212164, node=bro, filter=ip or not ip, init=T, success=T]) 0.000000 | HookCallFunction Notice::want_pp() 0.000000 | HookCallFunction PacketFilter::build() 0.000000 | HookCallFunction PacketFilter::combine_filters(ip or not ip, and, ) @@ -1552,6 +1644,7 @@ 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 +1655,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 +1667,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.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.multiple/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/netcontrol.log index 40e6c0e82d..7a948f40a6 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/netcontrol.log +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/netcontrol.log @@ -3,34 +3,39 @@ #empty_field (empty) #unset_field - #path netcontrol -#open 2016-02-12-03-43-55 +#open 2016-02-17-18-55-27 #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 - - - - - - - activated plugin with priority 10 - - - Debug-All 0.000000 - NetControl::MESSAGE - - - - - - - activated plugin with priority 10 - - - Openflow-Log-42 0.000000 - NetControl::MESSAGE - - - - - - - activated plugin with priority 0 - - - 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 30.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 30.000000 - Openflow-Log-42 -1398529018.678276 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All -1398529018.678276 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Openflow-Log-42 -1398529018.678276 6 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 15.000000 - Debug-All -1398529018.678276 6 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 15.000000 - Openflow-Log-42 -1398529018.678276 8 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 30.000000 - Debug-All -1398529018.678276 8 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 30.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 30.000000 - Debug-All -1398529018.678276 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All -1398529018.678276 6 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 15.000000 - Debug-All -1398529018.678276 8 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 30.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 30.000000 - Openflow-Log-42 -1398529018.678276 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Openflow-Log-42 -1398529018.678276 6 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 15.000000 - Openflow-Log-42 -1398529018.678276 8 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 30.000000 - Openflow-Log-42 -1398529020.164464 4 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All -1398529020.164464 6 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 15.000000 - Debug-All -1398529020.164464 8 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 30.000000 - Debug-All -1398529020.164464 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 30.000000 - Debug-All -1398529020.164464 4 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All -1398529020.164464 6 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 15.000000 - Debug-All -1398529020.164464 8 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 30.000000 - Debug-All -1398529020.164464 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 30.000000 - Debug-All -#close 2016-02-12-03-43-55 +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 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Debug-All +1398529018.678276 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Openflow-Log-42 +1398529018.678276 6 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Debug-All +1398529018.678276 6 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Openflow-Log-42 +1398529018.678276 8 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 8 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 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Debug-All +1398529018.678276 6 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Debug-All +1398529018.678276 8 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 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Openflow-Log-42 +1398529018.678276 6 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Openflow-Log-42 +1398529018.678276 8 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 +1398529018.678429 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 +1398529018.678429 4 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Debug-All +1398529018.678429 6 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Debug-All +1398529018.678429 8 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 +1398529018.678429 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 +1398529018.678429 4 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Debug-All +1398529018.678429 6 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Debug-All +1398529018.678429 8 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.164464 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.164464 4 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Openflow-Log-42 +1398529020.164464 6 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Openflow-Log-42 +1398529020.164464 8 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.164464 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 +#close 2016-02-17-18-55-27 diff --git a/testing/btest/scripts/base/frameworks/netcontrol/basic.bro b/testing/btest/scripts/base/frameworks/netcontrol/basic.bro index c32cb1d7c6..778b3febe8 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/basic.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/basic.bro @@ -1,5 +1,7 @@ # @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 diff --git a/testing/btest/scripts/base/frameworks/netcontrol/multiple.bro b/testing/btest/scripts/base/frameworks/netcontrol/multiple.bro index c2d209ca38..5ddc549670 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/multiple.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/multiple.bro @@ -3,6 +3,8 @@ @load base/frameworks/netcontrol +global rules: vector of string; + event bro_init() { local netcontrol_debug = NetControl::create_debug(T); @@ -14,11 +16,20 @@ event bro_init() 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; - 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); + 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 10sec { remove_all() }; } + From 446a44787ab65702e9cc11bafaff1c562658590d Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Fri, 4 Mar 2016 12:02:19 -0800 Subject: [PATCH 65/93] Remove old string functions. More specifically, this removes the functions: strcasecmp_n strchr_n strrchr_n and replaces the calls with the respective C-library calls that should be part of just about all operating systems by now. --- src/analyzer/protocol/finger/Finger.cc | 3 +- src/analyzer/protocol/http/HTTP.cc | 4 +-- src/analyzer/protocol/ident/Ident.cc | 5 ++-- src/analyzer/protocol/mime/MIME.cc | 2 +- src/analyzer/protocol/smtp/SMTP.cc | 4 +-- src/util.cc | 41 +------------------------- src/util.h | 3 -- 7 files changed, 11 insertions(+), 51 deletions(-) diff --git a/src/analyzer/protocol/finger/Finger.cc b/src/analyzer/protocol/finger/Finger.cc index 6a5865383b..bc64f19793 100644 --- a/src/analyzer/protocol/finger/Finger.cc +++ b/src/analyzer/protocol/finger/Finger.cc @@ -54,7 +54,8 @@ 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); + const char* at = reinterpret_cast(memchr(line, '@', end_of_line - line)); 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 36c92ed6e6..d921a20a54 100644 --- a/src/analyzer/protocol/http/HTTP.cc +++ b/src/analyzer/protocol/http/HTTP.cc @@ -1370,7 +1370,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 ) @@ -1564,7 +1564,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..268ae04c57 100644 --- a/src/analyzer/protocol/ident/Ident.cc +++ b/src/analyzer/protocol/ident/Ident.cc @@ -153,8 +153,9 @@ 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); + const char* colon = reinterpret_cast(memchr(line, ':', end_of_line - line)); + const char* comma = reinterpret_cast(memchr(line, ':', end_of_line - line)); 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/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/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 From 9df5a36a5ce672bfbdf35f296ff5d83b7b0df791 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Fri, 4 Mar 2016 12:14:14 -0800 Subject: [PATCH 66/93] Fix typo in previous string function replacement commit --- src/analyzer/protocol/ident/Ident.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/analyzer/protocol/ident/Ident.cc b/src/analyzer/protocol/ident/Ident.cc index 268ae04c57..3ad86156a0 100644 --- a/src/analyzer/protocol/ident/Ident.cc +++ b/src/analyzer/protocol/ident/Ident.cc @@ -155,7 +155,7 @@ void Ident_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig) const char* sys_type = line; assert(line <= end_of_line); const char* colon = reinterpret_cast(memchr(line, ':', end_of_line - line)); - const char* comma = reinterpret_cast(memchr(line, ':', end_of_line - line)); + const char* comma = reinterpret_cast(memchr(line, ',', end_of_line - line)); if ( ! colon ) { BadReply(length, orig_line); From 6c0165b0907f7a18fe4191064bf1d612a8546e15 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 8 Mar 2016 07:45:16 -0800 Subject: [PATCH 67/93] Commit correct version of conn.log. Sorry, I mistakenly committed the one triggering the bug, after testing both of them for a bit. --- .../scripts.base.protocols.ssh.basic/conn.log | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) 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 From 4476638d0ea72639365838891c5cfa63715ea1f7 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 8 Mar 2016 09:57:11 -0800 Subject: [PATCH 68/93] Fix compile problem on os-x (usage of min) --- src/analyzer/protocol/finger/Finger.cc | 3 ++- src/analyzer/protocol/ident/Ident.cc | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/analyzer/protocol/finger/Finger.cc b/src/analyzer/protocol/finger/Finger.cc index ef50048474..8db28d8413 100644 --- a/src/analyzer/protocol/finger/Finger.cc +++ b/src/analyzer/protocol/finger/Finger.cc @@ -3,6 +3,7 @@ #include "bro-config.h" #include +#include #include "NetVar.h" #include "Finger.h" @@ -55,7 +56,7 @@ void Finger_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig line = skip_whitespace(line+2, end_of_line); assert(line <= end_of_line); - int n = min(end_of_line - line, 0); // just to be sure if assertions aren't on. + long n = std::min(end_of_line - line, 0L); // just to be sure if assertions aren't on. const char* at = reinterpret_cast(memchr(line, '@', n)); const char* host = 0; if ( ! at ) diff --git a/src/analyzer/protocol/ident/Ident.cc b/src/analyzer/protocol/ident/Ident.cc index 7fbc128a26..4266c7bc96 100644 --- a/src/analyzer/protocol/ident/Ident.cc +++ b/src/analyzer/protocol/ident/Ident.cc @@ -3,6 +3,7 @@ #include "bro-config.h" #include +#include #include "NetVar.h" #include "Ident.h" @@ -154,7 +155,7 @@ void Ident_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig) { const char* sys_type = line; assert(line <= end_of_line); - int n = min(end_of_line - line, 0); // just to be sure if assertions aren't on. + int n = std::min(end_of_line - line, 0L); // 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 ) From d9459fc59aea61c3fcdd6d72c94468e3a37eda42 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 8 Mar 2016 11:25:15 -0800 Subject: [PATCH 69/93] Add rule hooks to the acld plugin. The hook name is NetControl::acld_rule_policy and allows the modification of acld rules before they are sent out to the network. This allows, e.g. network policies to use nullzero instead of drop in certain circumstances. --- .../frameworks/netcontrol/plugins/acld.bro | 62 +++++++-- .../netcontrol/plugins/openflow.bro | 7 ++ .../recv.recv.out | 7 ++ .../send.send.out | 7 ++ .../base/frameworks/netcontrol/acld-hook.bro | 118 ++++++++++++++++++ 5 files changed, 193 insertions(+), 8 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld-hook/recv.recv.out create mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld-hook/send.send.out create mode 100644 testing/btest/scripts/base/frameworks/netcontrol/acld-hook.bro diff --git a/scripts/base/frameworks/netcontrol/plugins/acld.bro b/scripts/base/frameworks/netcontrol/plugins/acld.bro index 2a524ee664..9e10806678 100644 --- a/scripts/base/frameworks/netcontrol/plugins/acld.bro +++ b/scripts/base/frameworks/netcontrol/plugins/acld.bro @@ -21,8 +21,19 @@ export { acld_host: addr; ## Broker port to connect to acld_port: port; - ## Function that can decide weather to accept add request - add_pred: function(p: PluginState, r: Rule, ar: AclRule): bool &optional; + ## 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. @@ -34,9 +45,23 @@ export { 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); @@ -115,7 +140,7 @@ function check_sn(sn: subnet) : bool return F; } -function rule_to_acl_rule(r: Rule) : AclRule +function rule_to_acl_rule(p: PluginState, r: Rule) : AclRule { local e = r$entity; @@ -169,16 +194,34 @@ function rule_to_acl_rule(r: Rule) : AclRule 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 { - local ar = rule_to_acl_rule(r); + if ( ! acld_check_rule(p, r) ) + return F; - if ( p$acld_config?$add_pred ) - if ( ! p$acld_config$add_pred(p, r, ar) ) - return F; + local ar = rule_to_acl_rule(p, r); if ( ar$command == "" ) return F; @@ -189,7 +232,10 @@ function acld_add_rule_fun(p: PluginState, r: Rule) : bool function acld_remove_rule_fun(p: PluginState, r: Rule) : bool { - local ar = rule_to_acl_rule(r); + 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 diff --git a/scripts/base/frameworks/netcontrol/plugins/openflow.bro b/scripts/base/frameworks/netcontrol/plugins/openflow.bro index 2ec12dd4b9..4ebf673207 100644 --- a/scripts/base/frameworks/netcontrol/plugins/openflow.bro +++ b/scripts/base/frameworks/netcontrol/plugins/openflow.bro @@ -12,6 +12,13 @@ export { 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; 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..72fac44013 --- /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::DROP, target=NetControl::FORWARD, entity=[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=], expire=36000.0, priority=0, location=here, out_port=, mod=, id=2, cid=2, _plugin_id=1], [command=blockhosthost, cookie=2, arg=192.168.18.50 74.125.239.97, comment=here] +add_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=there, out_port=, mod=, id=3, cid=3, _plugin_id=1], [command=droptcpport, cookie=3, arg=443, comment=there] +add_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=4, cid=4, _plugin_id=1], [command=nullzero, cookie=4, arg=192.168.18.50/32, comment=] +remove_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[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=], expire=36000.0, priority=0, location=here, out_port=, mod=, id=2, cid=2, _plugin_id=1], [command=restorehosthost, cookie=2, arg=192.168.18.50 74.125.239.97, comment=here] +remove_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=there, out_port=, mod=, id=3, cid=3, _plugin_id=1], [command=restoretcpport, cookie=3, arg=443, comment=there] +remove_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=4, cid=4, _plugin_id=1], [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..edb28710a4 --- /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::DROP, target=NetControl::FORWARD, entity=[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=], expire=36000.0, priority=0, location=here, out_port=, mod=, id=2, cid=2, _plugin_id=1] +rule added, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=there, out_port=, mod=, id=3, cid=3, _plugin_id=1] +rule added, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=4, cid=4, _plugin_id=1] +rule removed, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[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=], expire=36000.0, priority=0, location=here, out_port=, mod=, id=2, cid=2, _plugin_id=1] +rule removed, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=there, out_port=, mod=, id=3, cid=3, _plugin_id=1] +rule removed, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=4, cid=4, _plugin_id=1] 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..0076ed88c2 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/netcontrol/acld-hook.bro @@ -0,0 +1,118 @@ +# @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 bro_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; + continue_processing(); + } + +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; + NetControl::remove_rule(r$id); + } + +event NetControl::rule_removed(r: NetControl::Rule, p: NetControl::PluginState, msg: string) + { + print "rule removed", r; + } + +@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, 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, 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 + From 42e40726737b1b8ef6517eaf90a8b905a57998cb Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Tue, 8 Mar 2016 14:49:22 -0800 Subject: [PATCH 70/93] Add signaling of succesful initialization of plugins to NetControl. This does not really have many user-facing changes. The one big change is that users now should initialize plugins in the NetControl::init() event instead of bro_init. Once all plugins finished initializing and the NetControl framework starts operations, the NetControl::init_done() event is raised. Rules that are sent to NetControl before the plugins have finished initializing are ignored - this is important when several plugins that require external connections have to be initialized at the beginning. Without this delay, rules could end up at the wrong plugin. --- scripts/base/frameworks/netcontrol/main.bro | 108 +++++++++++++++++- scripts/base/frameworks/netcontrol/plugin.bro | 8 ++ .../frameworks/netcontrol/plugins/acld.bro | 17 +++ .../frameworks/netcontrol/plugins/broker.bro | 15 +++ .../frameworks/netcontrol/plugins/debug.bro | 1 + .../netcontrol/plugins/openflow.bro | 22 +++- scripts/base/frameworks/openflow/cluster.bro | 7 ++ scripts/base/frameworks/openflow/main.bro | 28 ++++- .../base/frameworks/openflow/non-cluster.bro | 6 + .../frameworks/openflow/plugins/broker.bro | 18 +++ scripts/base/frameworks/openflow/types.bro | 4 +- .../manager-1.netcontrol.log | 40 ++++--- .../netcontrol.log | 88 +++++++------- .../send.netcontrol.log | 29 ++--- .../netcontrol.log | 8 +- .../netcontrol.log | 8 +- .../netcontrol.log | 15 ++- .../netcontrol.log | 9 +- .../netcontrol.log | 9 +- .../base/frameworks/netcontrol/acld-hook.bro | 8 +- .../base/frameworks/netcontrol/acld.bro | 6 +- .../frameworks/netcontrol/basic-cluster.bro | 2 +- .../base/frameworks/netcontrol/basic.bro | 4 +- .../base/frameworks/netcontrol/broker.bro | 8 +- .../netcontrol/catch-and-release.bro | 2 +- .../base/frameworks/netcontrol/hook.bro | 2 +- .../base/frameworks/netcontrol/multiple.bro | 2 +- .../base/frameworks/netcontrol/openflow.bro | 2 +- .../frameworks/netcontrol/packetfilter.bro | 2 +- .../netcontrol/quarantine-openflow.bro | 2 +- .../base/frameworks/openflow/broker-basic.bro | 4 + 31 files changed, 371 insertions(+), 113 deletions(-) diff --git a/scripts/base/frameworks/netcontrol/main.bro b/scripts/base/frameworks/netcontrol/main.bro index 82a4b5e225..e950e0d163 100644 --- a/scripts/base/frameworks/netcontrol/main.bro +++ b/scripts/base/frameworks/netcontrol/main.bro @@ -20,7 +20,7 @@ export { redef enum Log::ID += { LOG }; # ### - # ### Generic functions. + # ### Generic functions and events. # ### # Activates a plugin. @@ -31,6 +31,14 @@ export { # 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. # ### @@ -167,6 +175,14 @@ export { ## 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. @@ -231,12 +247,25 @@ redef record Rule += { _plugin_id: count &optional; }; -global plugins: vector of PluginState; -global plugin_ids: table[count] of PluginState; +# 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 informations about rules _after_ they have been +# succesfully added. Currently no information about the rules is held +# in these tables while they are in the process of being added. global rules: table[string,count] of Rule; # Rules indexed by id and cid global id_to_cids: table[string] of set[count]; # id to cid @@ -356,6 +385,11 @@ 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()]; @@ -443,6 +477,56 @@ function quarantine_host(infected: addr, dns: addr, quarantine: addr, t: interva 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; + 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. @@ -458,13 +542,26 @@ function activate_impl(p: PluginState, priority: int) # 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); + } - log_msg(fmt("activated plugin with priority %d", priority), p); } 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 == "" ) @@ -481,6 +578,9 @@ function add_rule_impl(rule: Rule) : string { local p = plugins[i]; + if ( p$_activated == F ) + next; + # in this case, rule was accepted by earlier plugin and thus plugin has same # priority. accept, but give out new rule id. if ( accepted == T && p$_priority == priority ) diff --git a/scripts/base/frameworks/netcontrol/plugin.bro b/scripts/base/frameworks/netcontrol/plugin.bro index 9e53e55622..6709584312 100644 --- a/scripts/base/frameworks/netcontrol/plugin.bro +++ b/scripts/base/frameworks/netcontrol/plugin.bro @@ -14,6 +14,9 @@ export { ## 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. @@ -40,6 +43,11 @@ export { # 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 diff --git a/scripts/base/frameworks/netcontrol/plugins/acld.bro b/scripts/base/frameworks/netcontrol/plugins/acld.bro index 9e10806678..7c74a86d77 100644 --- a/scripts/base/frameworks/netcontrol/plugins/acld.bro +++ b/scripts/base/frameworks/netcontrol/plugins/acld.bro @@ -67,6 +67,7 @@ export { 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; @@ -252,6 +253,16 @@ function acld_init(p: PluginState) 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, @@ -267,8 +278,14 @@ function create_acld(config: AcldConfig) : PluginState 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; diff --git a/scripts/base/frameworks/netcontrol/plugins/broker.bro b/scripts/base/frameworks/netcontrol/plugins/broker.bro index ebb157c763..e62435d41c 100644 --- a/scripts/base/frameworks/netcontrol/plugins/broker.bro +++ b/scripts/base/frameworks/netcontrol/plugins/broker.bro @@ -32,6 +32,7 @@ export { 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; @@ -112,6 +113,15 @@ function broker_init(p: PluginState) 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, @@ -141,6 +151,11 @@ function create_broker(host: addr, host_port: port, topic: string, can_expire: b 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; diff --git a/scripts/base/frameworks/netcontrol/plugins/debug.bro b/scripts/base/frameworks/netcontrol/plugins/debug.bro index 430f191e16..45f0a577e6 100644 --- a/scripts/base/frameworks/netcontrol/plugins/debug.bro +++ b/scripts/base/frameworks/netcontrol/plugins/debug.bro @@ -31,6 +31,7 @@ function debug_log(p: PluginState, msg: string) function debug_init(p: PluginState) { debug_log(p, "init"); + plugin_activated(p); } function debug_done(p: PluginState) diff --git a/scripts/base/frameworks/netcontrol/plugins/openflow.bro b/scripts/base/frameworks/netcontrol/plugins/openflow.bro index 4ebf673207..7262931a12 100644 --- a/scripts/base/frameworks/netcontrol/plugins/openflow.bro +++ b/scripts/base/frameworks/netcontrol/plugins/openflow.bro @@ -67,6 +67,7 @@ global of_messages: table[count, OpenFlow::ofp_flow_mod_command] of OfTable &cre }; 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 { @@ -391,10 +392,29 @@ event OpenFlow::flow_removed(name: string, match: OpenFlow::ofp_match, cookie: c 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, + $init = openflow_init, # $done = openflow_done, $add_rule = openflow_add_rule, $remove_rule = openflow_remove_rule diff --git a/scripts/base/frameworks/openflow/cluster.bro b/scripts/base/frameworks/openflow/cluster.bro index 36109fa663..833817fa35 100644 --- a/scripts/base/frameworks/openflow/cluster.bro +++ b/scripts/base/frameworks/openflow/cluster.bro @@ -51,6 +51,10 @@ event OpenFlow::cluster_flow_mod(name: string, match: ofp_match, flow_mod: ofp_f } local c = name_to_controller[name]; + + if ( ! c$state$_activated ) + return; + if ( c?$flow_mod ) c$flow_mod(c$state, match, flow_mod); } @@ -65,6 +69,9 @@ event OpenFlow::cluster_flow_clear(name: string) local c = name_to_controller[name]; + if ( ! c$state$_activated ) + return; + if ( c?$flow_clear ) c$flow_clear(c$state); } diff --git a/scripts/base/frameworks/openflow/main.bro b/scripts/base/frameworks/openflow/main.bro index 4e336e0412..19135bc055 100644 --- a/scripts/base/frameworks/openflow/main.bro +++ b/scripts/base/frameworks/openflow/main.bro @@ -127,6 +127,18 @@ export { ## 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 @@ -227,13 +239,25 @@ function get_cookie_gid(cookie: count): count 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("OpenFlow Controller %s was already registered. Ignored duplicate registration"); + Reporter::error(fmt("OpenFlow Controller %s was already registered. Ignored duplicate registration", controller$state$_name)); return; } @@ -241,6 +265,8 @@ function register_controller_impl(tpe: OpenFlow::Plugin, name: string, controlle if ( controller?$init ) controller$init(controller$state); + else + controller_init_done(controller); } function unregister_controller_impl(controller: Controller) diff --git a/scripts/base/frameworks/openflow/non-cluster.bro b/scripts/base/frameworks/openflow/non-cluster.bro index 8975b276ca..22b5980924 100644 --- a/scripts/base/frameworks/openflow/non-cluster.bro +++ b/scripts/base/frameworks/openflow/non-cluster.bro @@ -5,6 +5,9 @@ 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 @@ -13,6 +16,9 @@ function flow_mod(controller: Controller, match: ofp_match, flow_mod: ofp_flow_m function flow_clear(controller: Controller): bool { + if ( ! controller$state$_activated ) + return F; + if ( controller?$flow_clear ) return controller$flow_clear(controller$state); else diff --git a/scripts/base/frameworks/openflow/plugins/broker.bro b/scripts/base/frameworks/openflow/plugins/broker.bro index dcb3d7d5a2..37e66c628a 100644 --- a/scripts/base/frameworks/openflow/plugins/broker.bro +++ b/scripts/base/frameworks/openflow/plugins/broker.bro @@ -36,6 +36,8 @@ export { 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); @@ -62,6 +64,17 @@ function broker_init(state: OpenFlow::ControllerState) 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 { @@ -70,6 +83,11 @@ function broker_new(name: string, host: addr, host_port: port, topic: string, dp 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/types.bro b/scripts/base/frameworks/openflow/types.bro index a8493efd8c..a10173c5ab 100644 --- a/scripts/base/frameworks/openflow/types.bro +++ b/scripts/base/frameworks/openflow/types.bro @@ -17,6 +17,8 @@ export { _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. @@ -116,7 +118,7 @@ export { supports_flow_removed: bool; ## function that describes the controller. Has to be implemented. describe: function(state: ControllerState): string; - ## one-time initialization function. + ## 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; 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 index fe29252480..818a86edd8 100644 --- 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 @@ -3,24 +3,26 @@ #empty_field (empty) #unset_field - #path netcontrol -#open 2016-02-12-00-47-14 +#open 2016-03-08-22-10-57 #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 -1455238034.228329 - NetControl::MESSAGE - - - - - - - activated plugin with priority 0 - - - Debug-All -1455238036.276570 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 30.000000 - Debug-All -1455238036.276570 worker-1:3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All -1455238036.276570 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 30.000000 - Debug-All -1455238036.276570 worker-1:3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All -1455238038.340995 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 30.000000 - Debug-All -1455238038.340995 worker-2:3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All -1455238038.340995 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 30.000000 - Debug-All -1455238038.340995 worker-2:3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All -1455238038.865312 worker-1:3 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All -1455238038.865312 worker-2:3 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All -1455238038.865312 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 30.000000 - Debug-All -1455238038.865312 worker-2: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 30.000000 - Debug-All -1455238038.865312 worker-1:3 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All -1455238038.865312 worker-2:3 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All -1455238038.865312 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 30.000000 - Debug-All -1455238038.865312 worker-2: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 30.000000 - Debug-All -#close 2016-02-12-00-47-18 +1457475057.498655 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Debug-All +1457475057.498655 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All +1457475057.498655 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - - +1457475059.567575 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 30.000000 - Debug-All +1457475059.567575 worker-1:3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All +1457475059.567575 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 30.000000 - Debug-All +1457475059.567575 worker-1:3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All +1457475061.660987 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 30.000000 - Debug-All +1457475061.660987 worker-2:3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All +1457475061.660987 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 30.000000 - Debug-All +1457475061.660987 worker-2:3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All +1457475062.165525 worker-1:3 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All +1457475062.165525 worker-2:3 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All +1457475062.165525 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 30.000000 - Debug-All +1457475062.165525 worker-2: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 30.000000 - Debug-All +1457475062.165525 worker-1:3 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All +1457475062.165525 worker-2:3 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All +1457475062.165525 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 30.000000 - Debug-All +1457475062.165525 worker-2: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 30.000000 - Debug-All +#close 2016-03-08-22-11-02 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol.log index ebeb4a59ee..cee95003b7 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol.log +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol.log @@ -3,48 +3,50 @@ #empty_field (empty) #unset_field - #path netcontrol -#open 2016-02-12-00-21-34 +#open 2016-03-08-21-39-06 #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 -1455236494.855016 - NetControl::MESSAGE - - - - - - - activated plugin with priority 0 - - - Debug-All -1455236494.855016 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 -1455236494.855016 3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 1.1.2.2/32 - - 0 15.000000 Hi there Debug-All -1455236494.855016 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 1.2.3.4/32 - - 5 15.000000 - Debug-All -1455236494.855016 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 -1455236494.855016 6 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->*/* - - 0 15.000000 - Debug-All -1455236494.855016 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 -1455236494.855016 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 -1455236494.855016 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 -1455236494.855016 10 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::MAC FF:FF:FF:FF:FF:FF - - 0 15.000000 - Debug-All -1455236494.855016 11 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::FLOW */*->*/* (FF:FF:FF:FF:FF:FF->*) - - 0 15.000000 - Debug-All -1455236494.855016 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 -1455236494.855016 3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 1.1.2.2/32 - - 0 15.000000 Hi there Debug-All -1455236494.855016 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 1.2.3.4/32 - - 5 15.000000 - Debug-All -1455236494.855016 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 -1455236494.855016 6 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->*/* - - 0 15.000000 - Debug-All -1455236494.855016 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 -1455236494.855016 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 -1455236494.855016 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 -1455236494.855016 10 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::MAC FF:FF:FF:FF:FF:FF - - 0 15.000000 - Debug-All -1455236494.855016 11 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::FLOW */*->*/* (FF:FF:FF:FF:FF:FF->*) - - 0 15.000000 - Debug-All -1455236494.855016 7 NetControl::RULE REMOVE 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 -1455236494.855016 8 NetControl::RULE REMOVE 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 -1455236494.855016 3 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 1.1.2.2/32 - - 0 15.000000 Hi there Debug-All -1455236494.855016 9 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->127.0.0.3/32/80 - - 5 15.000000 - Debug-All -1455236494.855016 11 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::FLOW */*->*/* (FF:FF:FF:FF:FF:FF->*) - - 0 15.000000 - Debug-All -1455236494.855016 6 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->*/* - - 0 15.000000 - Debug-All -1455236494.855016 10 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::MAC FF:FF:FF:FF:FF:FF - - 0 15.000000 - Debug-All -1455236494.855016 4 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 1.2.3.4/32 - - 5 15.000000 - Debug-All -1455236494.855016 5 NetControl::RULE REMOVE 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 -1455236494.855016 2 NetControl::RULE REMOVE 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 -1455236494.855016 7 NetControl::RULE REMOVE 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 -1455236494.855016 8 NetControl::RULE REMOVE 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 -1455236494.855016 3 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 1.1.2.2/32 - - 0 15.000000 Hi there Debug-All -1455236494.855016 9 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->127.0.0.3/32/80 - - 5 15.000000 - Debug-All -1455236494.855016 11 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::FLOW */*->*/* (FF:FF:FF:FF:FF:FF->*) - - 0 15.000000 - Debug-All -1455236494.855016 6 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->*/* - - 0 15.000000 - Debug-All -1455236494.855016 10 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::MAC FF:FF:FF:FF:FF:FF - - 0 15.000000 - Debug-All -1455236494.855016 4 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 1.2.3.4/32 - - 5 15.000000 - Debug-All -1455236494.855016 5 NetControl::RULE REMOVE 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 -1455236494.855016 2 NetControl::RULE REMOVE 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 -#close 2016-02-12-00-21-34 +1457473146.241696 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Debug-All +1457473146.241696 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All +1457473146.241696 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - - +1457473146.241696 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 +1457473146.241696 3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 1.1.2.2/32 - - 0 15.000000 Hi there Debug-All +1457473146.241696 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 1.2.3.4/32 - - 5 15.000000 - Debug-All +1457473146.241696 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 +1457473146.241696 6 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->*/* - - 0 15.000000 - Debug-All +1457473146.241696 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 +1457473146.241696 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 +1457473146.241696 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 +1457473146.241696 10 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::MAC FF:FF:FF:FF:FF:FF - - 0 15.000000 - Debug-All +1457473146.241696 11 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::FLOW */*->*/* (FF:FF:FF:FF:FF:FF->*) - - 0 15.000000 - Debug-All +1457473146.241696 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 +1457473146.241696 3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 1.1.2.2/32 - - 0 15.000000 Hi there Debug-All +1457473146.241696 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 1.2.3.4/32 - - 5 15.000000 - Debug-All +1457473146.241696 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 +1457473146.241696 6 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->*/* - - 0 15.000000 - Debug-All +1457473146.241696 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 +1457473146.241696 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 +1457473146.241696 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 +1457473146.241696 10 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::MAC FF:FF:FF:FF:FF:FF - - 0 15.000000 - Debug-All +1457473146.241696 11 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::FLOW */*->*/* (FF:FF:FF:FF:FF:FF->*) - - 0 15.000000 - Debug-All +1457473146.241696 7 NetControl::RULE REMOVE 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 +1457473146.241696 8 NetControl::RULE REMOVE 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 +1457473146.241696 3 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 1.1.2.2/32 - - 0 15.000000 Hi there Debug-All +1457473146.241696 9 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->127.0.0.3/32/80 - - 5 15.000000 - Debug-All +1457473146.241696 11 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::FLOW */*->*/* (FF:FF:FF:FF:FF:FF->*) - - 0 15.000000 - Debug-All +1457473146.241696 6 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->*/* - - 0 15.000000 - Debug-All +1457473146.241696 10 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::MAC FF:FF:FF:FF:FF:FF - - 0 15.000000 - Debug-All +1457473146.241696 4 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 1.2.3.4/32 - - 5 15.000000 - Debug-All +1457473146.241696 5 NetControl::RULE REMOVE 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 +1457473146.241696 2 NetControl::RULE REMOVE 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 +1457473146.241696 7 NetControl::RULE REMOVE 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 +1457473146.241696 8 NetControl::RULE REMOVE 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 +1457473146.241696 3 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 1.1.2.2/32 - - 0 15.000000 Hi there Debug-All +1457473146.241696 9 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->127.0.0.3/32/80 - - 5 15.000000 - Debug-All +1457473146.241696 11 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::FLOW */*->*/* (FF:FF:FF:FF:FF:FF->*) - - 0 15.000000 - Debug-All +1457473146.241696 6 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->*/* - - 0 15.000000 - Debug-All +1457473146.241696 10 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::MAC FF:FF:FF:FF:FF:FF - - 0 15.000000 - Debug-All +1457473146.241696 4 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 1.2.3.4/32 - - 5 15.000000 - Debug-All +1457473146.241696 5 NetControl::RULE REMOVE 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 +1457473146.241696 2 NetControl::RULE REMOVE 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 +#close 2016-03-08-21-39-06 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 index a44788e7b1..fb1381e291 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/send.netcontrol.log +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/send.netcontrol.log @@ -3,18 +3,21 @@ #empty_field (empty) #unset_field - #path netcontrol -#open 2016-02-12-03-43-39 +#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 - - - - - - - activated plugin with priority 0 - - - Broker-bro/event/netcontroltest -1455248619.521854 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 -1455248619.521854 3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - - 0 36000.000000 - Broker-bro/event/netcontroltest -1455248619.521886 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 -1455248619.521886 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 -1455248619.521886 3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - - 0 36000.000000 - Broker-bro/event/netcontroltest -1455248619.521886 3 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - - 0 36000.000000 - Broker-bro/event/netcontroltest -1455248619.521886 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 -1455248619.521886 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 -1455248619.521886 3 NetControl::RULE EXPIRE NetControl::TIMEOUT NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 10.10.1.4/32 - - 0 36000.000000 - Broker-bro/event/netcontroltest -1455248619.521886 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-02-12-03-43-39 +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.catch-and-release/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.catch-and-release/netcontrol.log index ceb8f0e3c4..823a2e6cd7 100644 --- 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 @@ -3,10 +3,12 @@ #empty_field (empty) #unset_field - #path netcontrol -#open 2016-02-12-03-24-03 +#open 2016-03-08-22-15-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 - - - - - - - activated plugin with priority 0 - - - Debug-All +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 ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 3600.000000 Re-drop by catch-and-release Debug-All 1398529018.678276 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 86400.000000 Re-drop by catch-and-release Debug-All @@ -27,4 +29,4 @@ 1398529020.164464 4 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 86400.000000 Re-drop by catch-and-release Debug-All 1398529020.164464 6 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 604800.000000 Re-drop by catch-and-release Debug-All 1398529020.164464 5 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 604800.000000 Re-drop by catch-and-release Debug-All -#close 2016-02-12-03-24-03 +#close 2016-03-08-22-15-32 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.hook/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.hook/netcontrol.log index e98ec69983..ce0d07a261 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.hook/netcontrol.log +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.hook/netcontrol.log @@ -3,10 +3,12 @@ #empty_field (empty) #unset_field - #path netcontrol -#open 2016-02-12-03-22-09 +#open 2016-03-08-22-00-47 #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 - - - - - - - activated plugin with priority 0 - - - Debug-All +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 @@ -15,4 +17,4 @@ 1398529020.164464 2 NetControl::RULE REMOVE 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 1398529020.164464 5 NetControl::RULE REMOVE 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 1398529020.164464 2 NetControl::RULE REMOVE 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 -#close 2016-02-12-03-22-09 +#close 2016-03-08-22-00-47 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/netcontrol.log index 7a948f40a6..0ffea89a1a 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/netcontrol.log +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/netcontrol.log @@ -3,12 +3,17 @@ #empty_field (empty) #unset_field - #path netcontrol -#open 2016-02-17-18-55-27 +#open 2016-03-08-22-46-38 #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 - - - - - - - activated plugin with priority 10 - - - Debug-All -0.000000 - NetControl::MESSAGE - - - - - - - activated plugin with priority 10 - - - Openflow-Log-42 -0.000000 - NetControl::MESSAGE - - - - - - - activated plugin with priority 0 - - - Debug-All +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 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Debug-All @@ -38,4 +43,4 @@ 1398529020.164464 6 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Openflow-Log-42 1398529020.164464 8 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.164464 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 -#close 2016-02-17-18-55-27 +#close 2016-03-08-22-46-38 diff --git a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/netcontrol.log index c31024e8d9..cec23634b4 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/netcontrol.log +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/netcontrol.log @@ -3,10 +3,13 @@ #empty_field (empty) #unset_field - #path netcontrol -#open 2016-02-12-03-44-04 +#open 2016-03-08-22-47-07 #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 - - - - - - - activated plugin with priority 0 - - - Openflow-Log-42 +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 10.10.1.4/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 @@ -19,4 +22,4 @@ 1437831799.610433 7 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.133.100/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 192.168.133.100/32 - - 0 15.000000 - Openflow-Log-42 -#close 2016-02-12-03-44-04 +#close 2016-03-08-22-47-07 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 index 2a68c2a4b3..0da63fd6f5 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.quarantine-openflow/netcontrol.log +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.quarantine-openflow/netcontrol.log @@ -3,10 +3,13 @@ #empty_field (empty) #unset_field - #path netcontrol -#open 2016-02-12-03-44-17 +#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 - - - - - - - activated plugin with priority 0 - - - Openflow-Log-42 +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 @@ -15,4 +18,4 @@ 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-02-12-03-44-17 +#close 2016-03-08-22-48-10 diff --git a/testing/btest/scripts/base/frameworks/netcontrol/acld-hook.bro b/testing/btest/scripts/base/frameworks/netcontrol/acld-hook.bro index 0076ed88c2..da0f74900e 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/acld-hook.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/acld-hook.bro @@ -14,19 +14,23 @@ const broker_port: port &redef; redef exit_only_after_terminate = T; -event bro_init() +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; - continue_processing(); } event BrokerComm::outgoing_connection_broken(peer_address: string, diff --git a/testing/btest/scripts/base/frameworks/netcontrol/acld.bro b/testing/btest/scripts/base/frameworks/netcontrol/acld.bro index d799b36d30..33c943f68d 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/acld.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/acld.bro @@ -14,7 +14,7 @@ const broker_port: port &redef; redef exit_only_after_terminate = T; -event bro_init() +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")); @@ -26,6 +26,10 @@ event BrokerComm::outgoing_connection_established(peer_address: string, peer_name: string) { print "BrokerComm::outgoing_connection_established", peer_address, peer_port; + } + +event NetControl::init_done() + { continue_processing(); } diff --git a/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro b/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro index df275307ee..f255f619d8 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro @@ -21,7 +21,7 @@ redef Log::default_rotation_interval = 0secs; @load base/frameworks/netcontrol -event bro_init() +event NetControl::init() { local netcontrol_debug = NetControl::create_debug(T); NetControl::activate(netcontrol_debug, 0); diff --git a/testing/btest/scripts/base/frameworks/netcontrol/basic.bro b/testing/btest/scripts/base/frameworks/netcontrol/basic.bro index 778b3febe8..1efe420d73 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/basic.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/basic.bro @@ -6,7 +6,7 @@ @load base/frameworks/netcontrol -event bro_init() +event NetControl::init() { local netcontrol_debug = NetControl::create_debug(T); NetControl::activate(netcontrol_debug, 0); @@ -31,7 +31,7 @@ function test_mac() NetControl::add_rule(r); } -event bro_init() &priority=-5 +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"); diff --git a/testing/btest/scripts/base/frameworks/netcontrol/broker.bro b/testing/btest/scripts/base/frameworks/netcontrol/broker.bro index 7546977344..30b9d18c1c 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/broker.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/broker.bro @@ -15,19 +15,23 @@ const broker_port: port &redef; redef exit_only_after_terminate = T; -event bro_init() +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; - continue_processing(); } event BrokerComm::outgoing_connection_broken(peer_address: string, diff --git a/testing/btest/scripts/base/frameworks/netcontrol/catch-and-release.bro b/testing/btest/scripts/base/frameworks/netcontrol/catch-and-release.bro index 318d87803f..0710fb6981 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/catch-and-release.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/catch-and-release.bro @@ -4,7 +4,7 @@ @load base/frameworks/netcontrol -event bro_init() +event NetControl::init() { local netcontrol_debug = NetControl::create_debug(T); NetControl::activate(netcontrol_debug, 0); diff --git a/testing/btest/scripts/base/frameworks/netcontrol/hook.bro b/testing/btest/scripts/base/frameworks/netcontrol/hook.bro index 5ad0fe85e8..02056a1e0a 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/hook.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/hook.bro @@ -3,7 +3,7 @@ @load base/frameworks/netcontrol -event bro_init() +event NetControl::init() { local netcontrol_debug = NetControl::create_debug(T); NetControl::activate(netcontrol_debug, 0); diff --git a/testing/btest/scripts/base/frameworks/netcontrol/multiple.bro b/testing/btest/scripts/base/frameworks/netcontrol/multiple.bro index 5ddc549670..db98382615 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/multiple.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/multiple.bro @@ -5,7 +5,7 @@ global rules: vector of string; -event bro_init() +event NetControl::init() { local netcontrol_debug = NetControl::create_debug(T); local netcontrol_debug_2 = NetControl::create_debug(T); diff --git a/testing/btest/scripts/base/frameworks/netcontrol/openflow.bro b/testing/btest/scripts/base/frameworks/netcontrol/openflow.bro index 36d3b9bfdb..47cb0fb9e4 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/openflow.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/openflow.bro @@ -6,7 +6,7 @@ global of_controller: OpenFlow::Controller; -event bro_init() +event NetControl::init() { of_controller = OpenFlow::log_new(42); local netcontrol_of = NetControl::create_openflow(of_controller); diff --git a/testing/btest/scripts/base/frameworks/netcontrol/packetfilter.bro b/testing/btest/scripts/base/frameworks/netcontrol/packetfilter.bro index 7ccb9dde5c..46a1193a21 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/packetfilter.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/packetfilter.bro @@ -3,7 +3,7 @@ @load base/frameworks/netcontrol -event bro_init() +event NetControl::init() { local netcontrol_packetfilter = NetControl::create_packetfilter(); NetControl::activate(netcontrol_packetfilter, 0); diff --git a/testing/btest/scripts/base/frameworks/netcontrol/quarantine-openflow.bro b/testing/btest/scripts/base/frameworks/netcontrol/quarantine-openflow.bro index d9fb1fd62c..9356253c98 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/quarantine-openflow.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/quarantine-openflow.bro @@ -6,7 +6,7 @@ global of_controller: OpenFlow::Controller; -event bro_init() +event NetControl::init() { of_controller = OpenFlow::log_new(42); local netcontrol_of = NetControl::create_openflow(of_controller); diff --git a/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro b/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro index e815cc47c8..e973517d44 100644 --- a/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro +++ b/testing/btest/scripts/base/frameworks/openflow/broker-basic.bro @@ -28,6 +28,10 @@ event BrokerComm::outgoing_connection_established(peer_address: string, 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)]]); From 41fd96b3206b881bc14b2fc8d6fafc339dde5ee9 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 9 Mar 2016 09:23:50 -0800 Subject: [PATCH 71/93] Fix the compile problem. Again. Now hopefully for all systems. --- src/analyzer/protocol/finger/Finger.cc | 3 +-- src/analyzer/protocol/ident/Ident.cc | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/analyzer/protocol/finger/Finger.cc b/src/analyzer/protocol/finger/Finger.cc index 8db28d8413..a9818ff7af 100644 --- a/src/analyzer/protocol/finger/Finger.cc +++ b/src/analyzer/protocol/finger/Finger.cc @@ -3,7 +3,6 @@ #include "bro-config.h" #include -#include #include "NetVar.h" #include "Finger.h" @@ -56,7 +55,7 @@ void Finger_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig line = skip_whitespace(line+2, end_of_line); assert(line <= end_of_line); - long n = std::min(end_of_line - line, 0L); // just to be sure if assertions aren't on. + 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 ) diff --git a/src/analyzer/protocol/ident/Ident.cc b/src/analyzer/protocol/ident/Ident.cc index 4266c7bc96..f668be921c 100644 --- a/src/analyzer/protocol/ident/Ident.cc +++ b/src/analyzer/protocol/ident/Ident.cc @@ -3,7 +3,6 @@ #include "bro-config.h" #include -#include #include "NetVar.h" #include "Ident.h" @@ -155,7 +154,7 @@ void Ident_Analyzer::DeliverStream(int length, const u_char* data, bool is_orig) { const char* sys_type = line; assert(line <= end_of_line); - int n = std::min(end_of_line - line, 0L); // just to be sure if assertions aren't on. + 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 ) From 562e5a9f6368e74c9b6987ace43ad8214c4e6448 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 9 Mar 2016 12:24:00 -0800 Subject: [PATCH 72/93] Add bif that allows searching for all matching subnets in table. Example: global test: set[subnet] = { 10.0.0.0/8, 10.1.0.0/16, 10.2.0.0/16, 10.2.0.2/31 } print matching_subnets(10.2.0.2/32, test); -> [10.2.0.2/31, 10.2.0.0/16, 10.0.0.0/8] --- scripts/base/frameworks/netcontrol/main.bro | 2 +- scripts/base/init-bare.bro | 7 ++ src/PrefixTable.cc | 75 +++++++++++-- src/PrefixTable.h | 8 ++ src/Val.h | 5 + src/bro.bif | 34 ++++++ src/patricia.c | 105 ++++++++++++++++++ src/patricia.h | 1 + .../Baseline/bifs.matching_subnets/output | 18 +++ testing/btest/bifs/matching_subnets.bro | 30 +++++ 10 files changed, 274 insertions(+), 11 deletions(-) create mode 100644 testing/btest/Baseline/bifs.matching_subnets/output create mode 100644 testing/btest/bifs/matching_subnets.bro diff --git a/scripts/base/frameworks/netcontrol/main.bro b/scripts/base/frameworks/netcontrol/main.bro index e950e0d163..c3ad4c0ff3 100644 --- a/scripts/base/frameworks/netcontrol/main.bro +++ b/scripts/base/frameworks/netcontrol/main.bro @@ -263,7 +263,7 @@ global plugin_counter: count = 1; global plugins: vector of PluginState; global plugin_ids: table[count] of PluginState; -# These tables hold informations about rules _after_ they have been +# These tables hold information about rules _after_ they have been # succesfully added. Currently no information about the rules is held # in these tables while they are in the process of being added. global rules: table[string,count] of Rule; # Rules indexed by id and cid diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 1df4399922..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. ## diff --git a/src/PrefixTable.cc b/src/PrefixTable.cc index d31203c9d3..d2d5b286a5 100644 --- a/src/PrefixTable.cc +++ b/src/PrefixTable.cc @@ -1,21 +1,48 @@ #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)); - addr.CopyIPv6(&prefix->add.sin6); - prefix->family = AF_INET6; - prefix->bitlen = width; - prefix->ref_count = 1; + if ( addr.GetFamily() == IPv4 ) + { + addr.CopyIPv4(&prefix->add.sin); + prefix->family = AF_INET; + prefix->bitlen = width; + prefix->ref_count = 1; + } + else + { + addr.CopyIPv6(&prefix->add.sin6); + prefix->family = AF_INET6; + prefix->bitlen = width; + prefix->ref_count = 1; + } return prefix; } +IPPrefix PrefixTable::PrefixToIPPrefix(prefix_t* prefix) + { + if ( prefix->family == AF_INET ) + { + return IPPrefix(IPAddr(IPv4, reinterpret_cast(&prefix->add.sin), IPAddr::Network), prefix->bitlen); + } + else if ( prefix->family == AF_INET6 ) + { + return IPPrefix(IPAddr(IPv6, reinterpret_cast(&prefix->add.sin6), IPAddr::Network), prefix->bitlen, 0); + } + else + { + reporter->InternalWarning("Unknown prefix family for PrefixToIPAddr"); + return IPPrefix(); + } + } + 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); @@ -43,12 +70,12 @@ void* PrefixTable::Insert(const Val* value, void* data) switch ( value->Type()->Tag() ) { case TYPE_ADDR: - return Insert(value->AsAddr(), 128, data); + return Insert(value->AsAddr(), value->AsAddr().GetFamily() == IPv4 ? 32 : 128, data); break; case TYPE_SUBNET: return Insert(value->AsSubNet().Prefix(), - value->AsSubNet().LengthIPv6(), data); + value->AsSubNet().Length(), data); break; default: @@ -57,13 +84,41 @@ 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(PrefixToIPPrefix(list[i]->prefix)); + } + + 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 +149,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..626ce0b553 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 otherwhise. + 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/Val.h b/src/Val.h index 86d75af94a..fdc60436bf 100644 --- a/src/Val.h +++ b/src/Val.h @@ -814,6 +814,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/bro.bif b/src/bro.bif index 72e7067b92..793efc5eba 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -1031,6 +1031,40 @@ function clear_table%(v: any%): any return 0; %} +## Gets all subnets that match 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; + } + + const PrefixTable* pt = t->AsTableVal()->Subnets(); + if ( !pt ) + { + reporter->Error("matching_subnets encountered nonexisting prefix table."); + return nullptr; + } + + VectorVal* result_v = new VectorVal(internal_type("subnet_vec")->AsVectorType()); + + auto matches = pt->FindAll(search); + for ( auto element : matches ) + { + SubNetVal* s = new SubNetVal(element); + result_v->Assign(result_v->Size(), s); + } + + return result_v; + %} + ## 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. 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/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/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; + } From 7ef431808d5588ef36938befbc6e9ccdc75efe18 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 9 Mar 2016 15:43:47 -0800 Subject: [PATCH 73/93] Rewrite internal handling of rules. This has no user-facing changes. It makes the internal handling of rules much easier (no crazy duplicate rules in case our rules are added to several backends). It also fixes several open ends and small bugs in the process. --- .../base/frameworks/netcontrol/cluster.bro | 2 +- scripts/base/frameworks/netcontrol/main.bro | 236 ++++++++++++------ .../frameworks/netcontrol/non-cluster.bro | 2 +- .../netcontrol/plugins/openflow.bro | 2 +- .../recv.recv.out | 12 +- .../send.send.out | 12 +- .../recv.recv.out | 12 +- .../send.send.out | 12 +- .../manager-1.netcontrol.log | 40 ++- .../.stdout | 30 +-- .../netcontrol.log | 70 ++---- .../recv.recv.out | 8 +- .../send.send.out | 12 +- .../.stdout | 11 - .../netcontrol.log | 26 +- .../netcontrol.log | 15 ++ .../netcontrol.log | 8 +- .../netcontrol.log | 57 +++-- .../openflow.log | 21 ++ .../netcontrol.log | 16 +- .../openflow.log | 16 +- .../netcontrol.log | 17 ++ .../base/frameworks/netcontrol/acld-hook.bro | 8 +- .../base/frameworks/netcontrol/acld.bro | 8 +- .../frameworks/netcontrol/basic-cluster.bro | 4 +- .../base/frameworks/netcontrol/broker.bro | 10 +- .../netcontrol/catch-and-release.bro | 1 - .../base/frameworks/netcontrol/duplicate.bro | 15 ++ .../base/frameworks/netcontrol/multiple.bro | 4 +- .../base/frameworks/netcontrol/openflow.bro | 2 +- .../base/frameworks/netcontrol/timeout.bro | 15 ++ 31 files changed, 409 insertions(+), 295 deletions(-) delete mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.catch-and-release/.stdout create mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.duplicate/netcontrol.log create mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/openflow.log create mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.timeout/netcontrol.log create mode 100644 testing/btest/scripts/base/frameworks/netcontrol/duplicate.bro create mode 100644 testing/btest/scripts/base/frameworks/netcontrol/timeout.bro diff --git a/scripts/base/frameworks/netcontrol/cluster.bro b/scripts/base/frameworks/netcontrol/cluster.bro index 9cdaa30d2d..913997826e 100644 --- a/scripts/base/frameworks/netcontrol/cluster.bro +++ b/scripts/base/frameworks/netcontrol/cluster.bro @@ -75,7 +75,7 @@ event rule_added(r: Rule, p: PluginState, msg: string &default="") &priority=5 { rule_added_impl(r, p, msg); - if ( r?$expire && ! p$plugin$can_expire ) + if ( r?$expire && r$expire > 0secs && ! p$plugin$can_expire ) schedule r$expire { rule_expire(r, p) }; } diff --git a/scripts/base/frameworks/netcontrol/main.bro b/scripts/base/frameworks/netcontrol/main.bro index c3ad4c0ff3..92e33175e7 100644 --- a/scripts/base/frameworks/netcontrol/main.bro +++ b/scripts/base/frameworks/netcontrol/main.bro @@ -243,8 +243,12 @@ export { } redef record Rule += { - ##< Internally set to the plugin handling the rule. - _plugin_id: count &optional; + ##< 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 @@ -263,11 +267,16 @@ global plugin_counter: count = 1; global plugins: vector of PluginState; global plugin_ids: table[count] of PluginState; -# These tables hold information about rules _after_ they have been -# succesfully added. Currently no information about the rules is held -# in these tables while they are in the process of being added. -global rules: table[string,count] of Rule; # Rules indexed by id and cid -global id_to_cids: table[string] of set[count]; # id to cid +# 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. +# Contains only succesfully added rules. +global rules_by_subnets: table[subnet] of set[Rule]; + +# 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 { @@ -570,9 +579,14 @@ function add_rule_impl(rule: Rule) : string 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; - local r = rule; for ( i in plugins ) { @@ -581,80 +595,65 @@ function add_rule_impl(rule: Rule) : string if ( p$_activated == F ) next; - # in this case, rule was accepted by earlier plugin and thus plugin has same - # priority. accept, but give out new rule id. - if ( accepted == T && p$_priority == priority ) - { - r = copy(rule); - r$cid = ++rule_counter; - } - else if ( accepted == T ) # 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; - # set before, in case the plugins sends and regenerates the plugin record later. - r$_plugin_id = p$_id; - - if ( p$plugin$add_rule(p, r) ) + if ( p$plugin$add_rule(p, rule) ) { accepted = T; priority = p$_priority; - log_rule(r, "ADD", REQUESTED, p); + 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; return rule$id; + } - log_rule_no_plugin(r, FAILED, "not supported"); + log_rule_no_plugin(rule, FAILED, "not supported"); return ""; } -function remove_single_rule(id: string, cid: count) : bool +function remove_rule_plugin(r: Rule, p: PluginState): bool { - if ( [id,cid] !in rules ) - { - Reporter::error(fmt("Rule %s -- %d does not exist in NetControl::remove_single_rule", id, cid)); - return F; - } + local success = T; - local r = rules[id,cid]; - local p = plugin_ids[r$_plugin_id]; - - # remove the respective rules from its plugins.. if ( ! p$plugin$remove_rule(p, r) ) { + # still continue and send to other plugins log_rule_error(r, "remove failed", p); - return F; + success = F; + } + else + { + log_rule(r, "REMOVE", REQUESTED, p); } - log_rule(r, "REMOVE", REQUESTED, p); - return T; + return success; } function remove_rule_impl(id: string) : bool { - if ( id !in id_to_cids ) + if ( id !in rules ) { Reporter::error(fmt("Rule %s does not exist in NetControl::remove_rule", id)); return F; } - local cids = id_to_cids[id]; + local r = rules[id]; local success = T; - for ( cid in cids ) + for ( plugin_id in r$_active_plugin_ids ) { - if ( [id,cid] !in rules ) - { - Reporter::error(fmt("Internal error in netcontrol::remove_rule - cid %d does not belong to rule %s", cid, id)); - delete cids[cid]; - next; - } - - if ( ! remove_single_rule(id, cid) ) - success = F; + local p = plugin_ids[plugin_id]; + success = remove_rule_plugin(r, p); } return success; @@ -662,47 +661,87 @@ function remove_rule_impl(id: string) : bool function rule_expire_impl(r: Rule, p: PluginState) &priority=-5 { - if ( [r$id,r$cid] !in rules ) + # do not emit timeout events on shutdown + if ( bro_is_terminating() ) + return; + + if ( r$id !in rules ) # Removed already. return; - event rule_timeout(r, FlowInfo(), p); - remove_single_rule(r$id, r$cid); + 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); - rules[r$id,r$cid] = r; - if ( r$id !in id_to_cids ) - id_to_cids[r$id] = set(); + add rule$_active_plugin_ids[p$_id]; + if ( |rule$_plugin_ids| == |rule$_active_plugin_ids| ) + { + # rule was completely added. + rule$_added = T; + } + } - add id_to_cids[r$id][r$cid]; +function rule_cleanup(r: Rule) + { + if ( |r$_active_plugin_ids| > 0 ) + return; + + 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,r$cid] !in rules ) + if ( r$id !in rules ) { log_rule_error(r, "Removal of non-existing rule", p); return; } - delete rules[r$id,r$cid]; - delete id_to_cids[r$id][r$cid]; - if ( |id_to_cids[r$id]| == 0 ) - delete id_to_cids[r$id]; + # use our version to prevent operating on copies. + local rule = rules[r$id]; - log_rule(r, "REMOVE", SUCCEEDED, p, msg); + 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) { - delete rules[r$id,r$cid]; - delete id_to_cids[r$id][r$cid]; - if ( |id_to_cids[r$id]| == 0 ) - delete id_to_cids[r$id]; + 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 ) @@ -714,22 +753,71 @@ function rule_timeout_impl(r: Rule, i: FlowInfo, p: PluginState) msg = fmt("%sBytes: %s", msg, i$byte_count); } - log_rule(r, "EXPIRE", TIMEOUT, p, msg); + 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="") { - log_rule_error(r, msg, p); - # errors can occur during deletion. Since this probably means we wo't hear - # from it again, let's just remove it if it exists... - delete rules[r$id,r$cid]; - delete id_to_cids[r$id][r$cid]; - if ( |id_to_cids[r$id]| == 0 ) - delete id_to_cids[r$id]; + 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,cid] in rules ) - remove_single_rule(id, cid); + 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 index 8e08ebe436..4098586be4 100644 --- a/scripts/base/frameworks/netcontrol/non-cluster.bro +++ b/scripts/base/frameworks/netcontrol/non-cluster.bro @@ -26,7 +26,7 @@ event rule_added(r: Rule, p: PluginState, msg: string &default="") &priority=5 { rule_added_impl(r, p, msg); - if ( r?$expire && ! p$plugin$can_expire ) + if ( r?$expire && r$expire > 0secs && ! p$plugin$can_expire ) schedule r$expire { rule_expire(r, p) }; } diff --git a/scripts/base/frameworks/netcontrol/plugins/openflow.bro b/scripts/base/frameworks/netcontrol/plugins/openflow.bro index 7262931a12..71cbe5c0a6 100644 --- a/scripts/base/frameworks/netcontrol/plugins/openflow.bro +++ b/scripts/base/frameworks/netcontrol/plugins/openflow.bro @@ -304,7 +304,7 @@ function openflow_remove_rule(p: PluginState, r: Rule) : bool return F; local flow_mod: OpenFlow::ofp_flow_mod = [ - $cookie=OpenFlow::generate_cookie(r$cid), + $cookie=OpenFlow::generate_cookie(r$cid*2), $command=OpenFlow::OFPFC_DELETE ]; 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 index 72fac44013..d36130b29b 100644 --- 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 @@ -1,7 +1,7 @@ BrokerComm::incoming_connection_established -add_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[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=], expire=36000.0, priority=0, location=here, out_port=, mod=, id=2, cid=2, _plugin_id=1], [command=blockhosthost, cookie=2, arg=192.168.18.50 74.125.239.97, comment=here] -add_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=there, out_port=, mod=, id=3, cid=3, _plugin_id=1], [command=droptcpport, cookie=3, arg=443, comment=there] -add_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=4, cid=4, _plugin_id=1], [command=nullzero, cookie=4, arg=192.168.18.50/32, comment=] -remove_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[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=], expire=36000.0, priority=0, location=here, out_port=, mod=, id=2, cid=2, _plugin_id=1], [command=restorehosthost, cookie=2, arg=192.168.18.50 74.125.239.97, comment=here] -remove_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=there, out_port=, mod=, id=3, cid=3, _plugin_id=1], [command=restoretcpport, cookie=3, arg=443, comment=there] -remove_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=4, cid=4, _plugin_id=1], [command=nonullzero, cookie=4, arg=192.168.18.50/32, comment=] +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 index edb28710a4..fd7f00bb7c 100644 --- 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 @@ -1,7 +1,7 @@ BrokerComm::outgoing_connection_established, 127.0.0.1, 9999/tcp -rule added, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[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=], expire=36000.0, priority=0, location=here, out_port=, mod=, id=2, cid=2, _plugin_id=1] -rule added, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=there, out_port=, mod=, id=3, cid=3, _plugin_id=1] -rule added, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=4, cid=4, _plugin_id=1] -rule removed, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[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=], expire=36000.0, priority=0, location=here, out_port=, mod=, id=2, cid=2, _plugin_id=1] -rule removed, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=there, out_port=, mod=, id=3, cid=3, _plugin_id=1] -rule removed, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=4, cid=4, _plugin_id=1] +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 index f17d8fad9f..6890484529 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld/recv.recv.out +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld/recv.recv.out @@ -1,7 +1,7 @@ BrokerComm::incoming_connection_established -add_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[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=], expire=36000.0, priority=0, location=here, out_port=, mod=, id=2, cid=2, _plugin_id=1], [command=blockhosthost, cookie=2, arg=192.168.18.50 74.125.239.97, comment=here] -add_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=there, out_port=, mod=, id=3, cid=3, _plugin_id=1], [command=droptcpport, cookie=3, arg=443, comment=there] -add_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=4, cid=4, _plugin_id=1], [command=drop, cookie=4, arg=192.168.18.50/32, comment=] -remove_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[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=], expire=36000.0, priority=0, location=here, out_port=, mod=, id=2, cid=2, _plugin_id=1], [command=restorehosthost, cookie=2, arg=192.168.18.50 74.125.239.97, comment=here] -remove_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=there, out_port=, mod=, id=3, cid=3, _plugin_id=1], [command=restoretcpport, cookie=3, arg=443, comment=there] -remove_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=4, cid=4, _plugin_id=1], [command=restore, cookie=4, arg=192.168.18.50/32, comment=] +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 index edb28710a4..fd7f00bb7c 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld/send.send.out +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.acld/send.send.out @@ -1,7 +1,7 @@ BrokerComm::outgoing_connection_established, 127.0.0.1, 9999/tcp -rule added, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[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=], expire=36000.0, priority=0, location=here, out_port=, mod=, id=2, cid=2, _plugin_id=1] -rule added, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=there, out_port=, mod=, id=3, cid=3, _plugin_id=1] -rule added, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=4, cid=4, _plugin_id=1] -rule removed, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[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=], expire=36000.0, priority=0, location=here, out_port=, mod=, id=2, cid=2, _plugin_id=1] -rule removed, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::FLOW, conn=, flow=[src_h=, src_p=, dst_h=, dst_p=443/tcp, src_m=, dst_m=], ip=, mac=], expire=36000.0, priority=0, location=there, out_port=, mod=, id=3, cid=3, _plugin_id=1] -rule removed, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=192.168.18.50/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=4, cid=4, _plugin_id=1] +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 index 818a86edd8..2811185c09 100644 --- 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 @@ -3,26 +3,24 @@ #empty_field (empty) #unset_field - #path netcontrol -#open 2016-03-08-22-10-57 +#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 -1457475057.498655 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Debug-All -1457475057.498655 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All -1457475057.498655 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - - -1457475059.567575 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 30.000000 - Debug-All -1457475059.567575 worker-1:3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All -1457475059.567575 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 30.000000 - Debug-All -1457475059.567575 worker-1:3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All -1457475061.660987 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 30.000000 - Debug-All -1457475061.660987 worker-2:3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All -1457475061.660987 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 30.000000 - Debug-All -1457475061.660987 worker-2:3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All -1457475062.165525 worker-1:3 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All -1457475062.165525 worker-2:3 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All -1457475062.165525 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 30.000000 - Debug-All -1457475062.165525 worker-2: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 30.000000 - Debug-All -1457475062.165525 worker-1:3 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All -1457475062.165525 worker-2:3 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 15.000000 - Debug-All -1457475062.165525 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 30.000000 - Debug-All -1457475062.165525 worker-2: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 30.000000 - Debug-All -#close 2016-03-08-22-11-02 +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 index 4322b62392..846bb1b653 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/.stdout +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/.stdout @@ -1,21 +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_id=1] -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_id=1] -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_id=1] -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_id=1] -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_id=1] -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_id=1] -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_id=1] -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_id=1] -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_id=1] -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_id=1] -netcontrol debug (Debug-All): remove_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_id=1] -netcontrol debug (Debug-All): remove_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_id=1] -netcontrol debug (Debug-All): remove_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_id=1] -netcontrol debug (Debug-All): remove_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_id=1] -netcontrol debug (Debug-All): remove_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_id=1] -netcontrol debug (Debug-All): remove_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_id=1] -netcontrol debug (Debug-All): remove_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_id=1] -netcontrol debug (Debug-All): remove_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_id=1] -netcontrol debug (Debug-All): remove_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_id=1] -netcontrol debug (Debug-All): remove_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_id=1] +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 index cee95003b7..da4487f10f 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol.log +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.basic/netcontrol.log @@ -3,50 +3,30 @@ #empty_field (empty) #unset_field - #path netcontrol -#open 2016-03-08-21-39-06 +#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 -1457473146.241696 - NetControl::MESSAGE - - - - - - - activating plugin with priority 0 - - - Debug-All -1457473146.241696 - NetControl::MESSAGE - - - - - - - activation finished - - - Debug-All -1457473146.241696 - NetControl::MESSAGE - - - - - - - plugin initialization done - - - - -1457473146.241696 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 -1457473146.241696 3 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 1.1.2.2/32 - - 0 15.000000 Hi there Debug-All -1457473146.241696 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 1.2.3.4/32 - - 5 15.000000 - Debug-All -1457473146.241696 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 -1457473146.241696 6 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->*/* - - 0 15.000000 - Debug-All -1457473146.241696 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 -1457473146.241696 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 -1457473146.241696 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 -1457473146.241696 10 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::MAC FF:FF:FF:FF:FF:FF - - 0 15.000000 - Debug-All -1457473146.241696 11 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::FLOW */*->*/* (FF:FF:FF:FF:FF:FF->*) - - 0 15.000000 - Debug-All -1457473146.241696 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 -1457473146.241696 3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 1.1.2.2/32 - - 0 15.000000 Hi there Debug-All -1457473146.241696 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 1.2.3.4/32 - - 5 15.000000 - Debug-All -1457473146.241696 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 -1457473146.241696 6 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->*/* - - 0 15.000000 - Debug-All -1457473146.241696 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 -1457473146.241696 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 -1457473146.241696 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 -1457473146.241696 10 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::MAC FF:FF:FF:FF:FF:FF - - 0 15.000000 - Debug-All -1457473146.241696 11 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::FLOW */*->*/* (FF:FF:FF:FF:FF:FF->*) - - 0 15.000000 - Debug-All -1457473146.241696 7 NetControl::RULE REMOVE 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 -1457473146.241696 8 NetControl::RULE REMOVE 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 -1457473146.241696 3 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 1.1.2.2/32 - - 0 15.000000 Hi there Debug-All -1457473146.241696 9 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->127.0.0.3/32/80 - - 5 15.000000 - Debug-All -1457473146.241696 11 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::FLOW */*->*/* (FF:FF:FF:FF:FF:FF->*) - - 0 15.000000 - Debug-All -1457473146.241696 6 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->*/* - - 0 15.000000 - Debug-All -1457473146.241696 10 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::MAC FF:FF:FF:FF:FF:FF - - 0 15.000000 - Debug-All -1457473146.241696 4 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 1.2.3.4/32 - - 5 15.000000 - Debug-All -1457473146.241696 5 NetControl::RULE REMOVE 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 -1457473146.241696 2 NetControl::RULE REMOVE 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 -1457473146.241696 7 NetControl::RULE REMOVE 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 -1457473146.241696 8 NetControl::RULE REMOVE 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 -1457473146.241696 3 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 1.1.2.2/32 - - 0 15.000000 Hi there Debug-All -1457473146.241696 9 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->127.0.0.3/32/80 - - 5 15.000000 - Debug-All -1457473146.241696 11 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::FLOW */*->*/* (FF:FF:FF:FF:FF:FF->*) - - 0 15.000000 - Debug-All -1457473146.241696 6 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::FLOW 127.0.0.2/32/*->*/* - - 0 15.000000 - Debug-All -1457473146.241696 10 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::MAC FF:FF:FF:FF:FF:FF - - 0 15.000000 - Debug-All -1457473146.241696 4 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 1.2.3.4/32 - - 5 15.000000 - Debug-All -1457473146.241696 5 NetControl::RULE REMOVE 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 -1457473146.241696 2 NetControl::RULE REMOVE 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 -#close 2016-03-08-21-39-06 +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.broker/recv.recv.out b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/recv.recv.out index c6d61a3a14..3b02eef7c7 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/recv.recv.out +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/recv.recv.out @@ -1,5 +1,5 @@ BrokerComm::incoming_connection_established -add_rule, 0, [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[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=], expire=36000.0, priority=0, location=, out_port=, mod=, id=2, cid=2, _plugin_id=1] -add_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=3, cid=3, _plugin_id=1] -remove_rule, 0, [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[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=], expire=36000.0, priority=0, location=, out_port=, mod=, id=2, cid=2, _plugin_id=1] -remove_rule, 0, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=3, cid=3, _plugin_id=1] +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.send.out b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/send.send.out index 65f523ea94..31d94be31e 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/send.send.out +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.broker/send.send.out @@ -1,7 +1,7 @@ BrokerComm::outgoing_connection_established, 127.0.0.1, 9999/tcp -rule added, [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[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=], expire=36000.0, priority=0, location=, out_port=, mod=, id=2, cid=2, _plugin_id=1] -rule added, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=3, cid=3, _plugin_id=1] -rule timeout, [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[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=], expire=36000.0, priority=0, location=, out_port=, mod=, id=2, cid=2, _plugin_id=1], [duration=, packet_count=, byte_count=] -rule removed, [ty=NetControl::DROP, target=NetControl::MONITOR, entity=[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=], expire=36000.0, priority=0, location=, out_port=, mod=, id=2, cid=2, _plugin_id=1] -rule timeout, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=3, cid=3, _plugin_id=1], [duration=, packet_count=, byte_count=] -rule removed, [ty=NetControl::DROP, target=NetControl::FORWARD, entity=[ty=NetControl::ADDRESS, conn=, flow=, ip=10.10.1.4/32, mac=], expire=36000.0, priority=0, location=, out_port=, mod=, id=3, cid=3, _plugin_id=1] +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/.stdout b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.catch-and-release/.stdout deleted file mode 100644 index 17c390799f..0000000000 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.catch-and-release/.stdout +++ /dev/null @@ -1,11 +0,0 @@ -netcontrol debug (Debug-All): init -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=10.0 mins, priority=0, location=, out_port=, mod=, id=2, cid=2, _plugin_id=1] -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=1.0 hr, priority=0, location=Re-drop by catch-and-release, out_port=, mod=, id=3, cid=3, _plugin_id=1] -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=1.0 day, priority=0, location=Re-drop by catch-and-release, out_port=, mod=, id=4, cid=4, _plugin_id=1] -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=7.0 days, priority=0, location=Re-drop by catch-and-release, out_port=, mod=, id=5, cid=5, _plugin_id=1] -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=7.0 days, priority=0, location=Re-drop by catch-and-release, out_port=, mod=, id=6, cid=6, _plugin_id=1] -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=10.0 mins, priority=0, location=, out_port=, mod=, id=2, cid=2, _plugin_id=1] -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=1.0 hr, priority=0, location=Re-drop by catch-and-release, out_port=, mod=, id=3, cid=3, _plugin_id=1] -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=1.0 day, priority=0, location=Re-drop by catch-and-release, out_port=, mod=, id=4, cid=4, _plugin_id=1] -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=7.0 days, priority=0, location=Re-drop by catch-and-release, out_port=, mod=, id=6, cid=6, _plugin_id=1] -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=7.0 days, priority=0, location=Re-drop by catch-and-release, out_port=, mod=, id=5, cid=5, _plugin_id=1] 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 index 823a2e6cd7..f3bd6fafe0 100644 --- 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 @@ -3,30 +3,16 @@ #empty_field (empty) #unset_field - #path netcontrol -#open 2016-03-08-22-15-32 +#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 ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 3600.000000 Re-drop by catch-and-release Debug-All -1398529018.678276 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 86400.000000 Re-drop by catch-and-release Debug-All -1398529018.678276 5 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 604800.000000 Re-drop by catch-and-release Debug-All -1398529018.678276 6 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 604800.000000 Re-drop by catch-and-release 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 -1398529018.678276 3 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 3600.000000 Re-drop by catch-and-release Debug-All -1398529018.678276 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 86400.000000 Re-drop by catch-and-release Debug-All -1398529018.678276 5 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 604800.000000 Re-drop by catch-and-release Debug-All -1398529018.678276 6 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 604800.000000 Re-drop by catch-and-release Debug-All -1398529020.164464 2 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 600.000000 - Debug-All -1398529020.164464 3 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 3600.000000 Re-drop by catch-and-release Debug-All -1398529020.164464 4 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 86400.000000 Re-drop by catch-and-release Debug-All -1398529020.164464 6 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 604800.000000 Re-drop by catch-and-release Debug-All -1398529020.164464 5 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 604800.000000 Re-drop by catch-and-release Debug-All -1398529020.164464 2 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 600.000000 - Debug-All -1398529020.164464 3 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 3600.000000 Re-drop by catch-and-release Debug-All -1398529020.164464 4 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 86400.000000 Re-drop by catch-and-release Debug-All -1398529020.164464 6 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 604800.000000 Re-drop by catch-and-release Debug-All -1398529020.164464 5 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 604800.000000 Re-drop by catch-and-release Debug-All -#close 2016-03-08-22-15-32 +#close 2016-03-09-23-42-34 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.hook/netcontrol.log b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.hook/netcontrol.log index ce0d07a261..2936694e2a 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.hook/netcontrol.log +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.hook/netcontrol.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path netcontrol -#open 2016-03-08-22-00-47 +#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 @@ -13,8 +13,4 @@ 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 -1398529020.164464 5 NetControl::RULE REMOVE 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 -1398529020.164464 2 NetControl::RULE REMOVE 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 -1398529020.164464 5 NetControl::RULE REMOVE 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 -1398529020.164464 2 NetControl::RULE REMOVE 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 -#close 2016-03-08-22-00-47 +#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 index 0ffea89a1a..986c1cd5a2 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/netcontrol.log +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.multiple/netcontrol.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path netcontrol -#open 2016-03-08-22-46-38 +#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 @@ -16,31 +16,34 @@ 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 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Debug-All -1398529018.678276 4 NetControl::RULE ADD NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Openflow-Log-42 -1398529018.678276 6 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Debug-All -1398529018.678276 6 NetControl::RULE ADD NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Openflow-Log-42 -1398529018.678276 8 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 8 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 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 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Debug-All -1398529018.678276 6 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Debug-All -1398529018.678276 8 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 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 4 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Openflow-Log-42 -1398529018.678276 6 NetControl::RULE ADD NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Openflow-Log-42 -1398529018.678276 8 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 -1398529018.678429 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 -1398529018.678429 4 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Debug-All -1398529018.678429 6 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Debug-All -1398529018.678429 8 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 -1398529018.678429 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 -1398529018.678429 4 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Debug-All -1398529018.678429 6 NetControl::RULE REMOVE NetControl::SUCCEEDED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Debug-All -1398529018.678429 8 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.164464 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.164464 4 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::DROP NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 0 0.000000 - Openflow-Log-42 -1398529020.164464 6 NetControl::RULE REMOVE NetControl::REQUESTED NetControl::WHITELIST NetControl::FORWARD NetControl::ADDRESS 192.168.18.50/32 - - 5 0.000000 - Openflow-Log-42 -1398529020.164464 8 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.164464 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 -#close 2016-03-08-22-46-38 +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 index cec23634b4..abab12a0c9 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/netcontrol.log +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/netcontrol.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path netcontrol -#open 2016-03-08-22-47-07 +#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 @@ -11,15 +11,15 @@ 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 10.10.1.4/32 - - 0 15.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 10.10.1.4/32 - - 0 15.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.100/32 - - 0 15.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.100/32 - - 0 15.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 192.168.133.100/32 - - 0 15.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 192.168.133.100/32 - - 0 15.000000 - Openflow-Log-42 -#close 2016-03-08-22-47-07 +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 index 56274f20f8..6cff86bdb2 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/openflow.log +++ b/testing/btest/Baseline/scripts.base.frameworks.netcontrol.openflow/openflow.log @@ -3,16 +3,16 @@ #empty_field (empty) #unset_field - #path openflow -#open 2016-02-11-21-07-34 +#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 - - 10.10.1.4/32 - - - 4398046511110 - OpenFlow::OFPFC_ADD 0 15 0 - - 1 (empty) - - F - - - - - - - -1254722767.875996 42 - - - - - 2048 - - - 10.10.1.4/32 - - 4398046511111 - OpenFlow::OFPFC_ADD 0 15 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.100/32 - - - 4398046511114 - OpenFlow::OFPFC_ADD 0 15 0 - - 1 (empty) - - F - - - - - - - -1437831787.861602 42 - - - - - 2048 - - - 192.168.133.100/32 - - 4398046511115 - OpenFlow::OFPFC_ADD 0 15 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 - - 192.168.133.100/32 - - - 4398046511118 - OpenFlow::OFPFC_ADD 0 15 0 - - 1 (empty) - - F - - - - - - - -1437831799.610433 42 - - - - - 2048 - - - 192.168.133.100/32 - - 4398046511119 - OpenFlow::OFPFC_ADD 0 15 0 - - 1 (empty) - - F - - - - - - - -#close 2016-02-11-21-07-34 +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.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/scripts/base/frameworks/netcontrol/acld-hook.bro b/testing/btest/scripts/base/frameworks/netcontrol/acld-hook.bro index da0f74900e..566739c0b7 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/acld-hook.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/acld-hook.bro @@ -70,13 +70,13 @@ event connection_established(c: connection) event NetControl::rule_added(r: NetControl::Rule, p: NetControl::PluginState, msg: string) { - print "rule added", r; + 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; + print "rule removed", r$entity, r$ty; } @TEST-END-FILE @@ -103,14 +103,14 @@ event BrokerComm::incoming_connection_established(peer_name: string) event NetControl::acld_add_rule(id: count, r: NetControl::Rule, ar: NetControl::AclRule) { - print "add_rule", id, r, ar; + 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, ar; + 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)); diff --git a/testing/btest/scripts/base/frameworks/netcontrol/acld.bro b/testing/btest/scripts/base/frameworks/netcontrol/acld.bro index 33c943f68d..dfeaee1055 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/acld.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/acld.bro @@ -63,13 +63,13 @@ event connection_established(c: connection) event NetControl::rule_added(r: NetControl::Rule, p: NetControl::PluginState, msg: string) { - print "rule added", r; + 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; + print "rule removed", r$entity, r$ty; } @TEST-END-FILE @@ -96,14 +96,14 @@ event BrokerComm::incoming_connection_established(peer_name: string) event NetControl::acld_add_rule(id: count, r: NetControl::Rule, ar: NetControl::AclRule) { - print "add_rule", id, r, ar; + 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, ar; + 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)); diff --git a/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro b/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro index f255f619d8..c476751d57 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro @@ -30,8 +30,8 @@ event NetControl::init() 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::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() { diff --git a/testing/btest/scripts/base/frameworks/netcontrol/broker.bro b/testing/btest/scripts/base/frameworks/netcontrol/broker.bro index 30b9d18c1c..56a76433f2 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/broker.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/broker.bro @@ -49,18 +49,18 @@ event connection_established(c: connection) event NetControl::rule_added(r: NetControl::Rule, p: NetControl::PluginState, msg: string) { - print "rule added", r; + 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; + print "rule removed", r$entity, r$ty; } event NetControl::rule_timeout(r: NetControl::Rule, i: NetControl::FlowInfo, p: NetControl::PluginState) { - print "rule timeout", r, i; + print "rule timeout", r$entity, r$ty, i; } @TEST-END-FILE @@ -87,14 +87,14 @@ event BrokerComm::incoming_connection_established(peer_name: string) event NetControl::broker_add_rule(id: count, r: NetControl::Rule) { - print "add_rule", id, r; + 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; + 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, "")); diff --git a/testing/btest/scripts/base/frameworks/netcontrol/catch-and-release.bro b/testing/btest/scripts/base/frameworks/netcontrol/catch-and-release.bro index 0710fb6981..a809833ecf 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/catch-and-release.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/catch-and-release.bro @@ -1,6 +1,5 @@ # @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: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff .stdout @load base/frameworks/netcontrol 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/multiple.bro b/testing/btest/scripts/base/frameworks/netcontrol/multiple.bro index db98382615..56a764f2e9 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/multiple.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/multiple.bro @@ -1,5 +1,6 @@ # @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 @@ -22,6 +23,7 @@ event remove_all() NetControl::remove_rule(rules[i]); } + event connection_established(c: connection) { local id = c$id; @@ -30,6 +32,6 @@ event connection_established(c: connection) 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 10sec { remove_all() }; + schedule 1sec { remove_all() }; } diff --git a/testing/btest/scripts/base/frameworks/netcontrol/openflow.bro b/testing/btest/scripts/base/frameworks/netcontrol/openflow.bro index 47cb0fb9e4..36c06fcc3d 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/openflow.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/openflow.bro @@ -17,5 +17,5 @@ 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::drop_address(id$resp_h, 15sec); } 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); + } From 692662abcc489ef454cb1651dcc8fd362affb6e0 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 9 Mar 2016 16:52:25 -0800 Subject: [PATCH 74/93] Add check_subnet bif that allows exact membership test for subnet tables. This commit also fixes a few small bugs introduced in the last patricia tree commit. --- src/PrefixTable.cc | 10 ++--- src/bro.bif | 30 ++++++++++++++ .../btest/Baseline/bifs.check_subnet/output | 8 ++++ testing/btest/bifs/check_subnet.bro | 39 +++++++++++++++++++ 4 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 testing/btest/Baseline/bifs.check_subnet/output create mode 100644 testing/btest/bifs/check_subnet.bro diff --git a/src/PrefixTable.cc b/src/PrefixTable.cc index d2d5b286a5..2ef0d94f47 100644 --- a/src/PrefixTable.cc +++ b/src/PrefixTable.cc @@ -106,7 +106,7 @@ list PrefixTable::FindAll(const IPAddr& addr, int width) const list PrefixTable::FindAll(const SubNetVal* value) const { - return FindAll(value->AsSubNet().Prefix(), value->AsSubNet().LengthIPv6()); + return FindAll(value->AsSubNet().Prefix(), value->AsSubNet().Length()); } void* PrefixTable::Lookup(const IPAddr& addr, int width, bool exact) const @@ -132,12 +132,12 @@ void* PrefixTable::Lookup(const Val* value, bool exact) const switch ( value->Type()->Tag() ) { case TYPE_ADDR: - return Lookup(value->AsAddr(), 128, exact); + return Lookup(value->AsAddr(), value->AsAddr().GetFamily() == IPv4 ? 32 : 128, exact); break; case TYPE_SUBNET: return Lookup(value->AsSubNet().Prefix(), - value->AsSubNet().LengthIPv6(), exact); + value->AsSubNet().Length(), exact); break; default: @@ -171,12 +171,12 @@ void* PrefixTable::Remove(const Val* value) switch ( value->Type()->Tag() ) { case TYPE_ADDR: - return Remove(value->AsAddr(), 128); + return Remove(value->AsAddr(), value->AsAddr().GetFamily() == IPv4 ? 32 : 128); break; case TYPE_SUBNET: return Remove(value->AsSubNet().Prefix(), - value->AsSubNet().LengthIPv6()); + value->AsSubNet().Length()); break; default: diff --git a/src/bro.bif b/src/bro.bif index 793efc5eba..f57edd448d 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -1065,6 +1065,36 @@ function matching_subnets%(search: subnet, t: any%): subnet_vec return result_v; %} +## 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("matching_subnets needs to be called on a set[subnet]/table[subnet]."); + return nullptr; + } + + const PrefixTable* pt = t->AsTableVal()->Subnets(); + if ( !pt ) + { + reporter->Error("matching_subnets 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. 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/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); + } From 21c300c3332f7c9fd38583e668057c99341f1048 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 9 Mar 2016 21:32:15 -0800 Subject: [PATCH 75/93] NetControl: Add functions to search for rules affecting IPs/subnets Adds the functions NetControl::find_rules_addr and NetControl::fund_rules_subnet which return a vector containing all rules affecting a certain IP or subnet. --- scripts/base/frameworks/netcontrol/main.bro | 112 +++++++++++++++++- .../.stdout | 19 +++ .../out | 6 + .../netcontrol/delete-internal-state.bro | 54 +++++++++ .../base/frameworks/netcontrol/find-rules.bro | 34 ++++++ 5 files changed, 223 insertions(+), 2 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.delete-internal-state/.stdout create mode 100644 testing/btest/Baseline/scripts.base.frameworks.netcontrol.find-rules/out create mode 100644 testing/btest/scripts/base/frameworks/netcontrol/delete-internal-state.bro create mode 100644 testing/btest/scripts/base/frameworks/netcontrol/find-rules.bro diff --git a/scripts/base/frameworks/netcontrol/main.bro b/scripts/base/frameworks/netcontrol/main.bro index 92e33175e7..580d9b6d30 100644 --- a/scripts/base/frameworks/netcontrol/main.bro +++ b/scripts/base/frameworks/netcontrol/main.bro @@ -126,6 +126,20 @@ export { ## 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. @@ -271,8 +285,7 @@ global plugin_ids: table[count] of PluginState; global rules: table[string] of Rule; # Rules indexed by id and cid # All rules that apply to a certain subnet/IP address. -# Contains only succesfully added rules. -global rules_by_subnets: table[subnet] of set[Rule]; +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. @@ -563,6 +576,96 @@ function activate_impl(p: PluginState, priority: int) } +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 ) @@ -614,6 +717,9 @@ function add_rule_impl(rule: Rule) : string { rules[rule$id] = rule; rule_entities[rule$entity, rule$ty] = rule; + + add_subnet_entry(rule); + return rule$id; } @@ -703,6 +809,8 @@ 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]; } 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.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/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/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); + } + From dde52abb1ac1ccaf428550ff5d77e335fab3dc8c Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Thu, 10 Mar 2016 12:01:16 -0800 Subject: [PATCH 76/93] Updating submodule(s). [nomail] --- NEWS | 1 + aux/plugins | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index fecf7ad336..a394cb6e35 100644 --- a/NEWS +++ b/NEWS @@ -43,6 +43,7 @@ New Functionality - 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/aux/plugins b/aux/plugins index d251af520c..facb73d8c3 160000 --- a/aux/plugins +++ b/aux/plugins @@ -1 +1 @@ -Subproject commit d251af520ccdede694d7b3b7bcbc47df1080508c +Subproject commit facb73d8c39ec0b9e4865f7ce81c9238a5e7aa70 From 3d1b5814fd8d291a030a8f3ad26c960ce4d975de Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Thu, 10 Mar 2016 12:06:48 -0800 Subject: [PATCH 77/93] Updating submodule(s). [nomail] --- aux/plugins | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aux/plugins b/aux/plugins index facb73d8c3..55ba25273a 160000 --- a/aux/plugins +++ b/aux/plugins @@ -1 +1 @@ -Subproject commit facb73d8c39ec0b9e4865f7ce81c9238a5e7aa70 +Subproject commit 55ba25273a236de9db92d7d687b6c26de0d9f5f6 From 15c157d8ff1ba66428a33f5b378b11c6673656f2 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Thu, 10 Mar 2016 13:25:33 -0800 Subject: [PATCH 78/93] Updating submodule(s). [nomail] --- aux/plugins | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aux/plugins b/aux/plugins index 55ba25273a..ab61be0c4f 160000 --- a/aux/plugins +++ b/aux/plugins @@ -1 +1 @@ -Subproject commit 55ba25273a236de9db92d7d687b6c26de0d9f5f6 +Subproject commit ab61be0c4f128c976f72dfa5a09a87cd842f387a From ad9b0fc55056c1dc70eb78cef5bcf41a7de01819 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Fri, 11 Mar 2016 09:44:57 -0800 Subject: [PATCH 79/93] Move prefixtable back to all IPv6 internal handling. Changing that was just a bad idea and unnecessary. --- src/PrefixTable.cc | 46 ++++++++++++---------------------------------- 1 file changed, 12 insertions(+), 34 deletions(-) diff --git a/src/PrefixTable.cc b/src/PrefixTable.cc index 2ef0d94f47..bf51c5369e 100644 --- a/src/PrefixTable.cc +++ b/src/PrefixTable.cc @@ -5,39 +5,17 @@ prefix_t* PrefixTable::MakePrefix(const IPAddr& addr, int width) { prefix_t* prefix = (prefix_t*) safe_malloc(sizeof(prefix_t)); - if ( addr.GetFamily() == IPv4 ) - { - addr.CopyIPv4(&prefix->add.sin); - prefix->family = AF_INET; - prefix->bitlen = width; - prefix->ref_count = 1; - } - else - { - addr.CopyIPv6(&prefix->add.sin6); - prefix->family = AF_INET6; - prefix->bitlen = width; - prefix->ref_count = 1; - } + addr.CopyIPv6(&prefix->add.sin6); + prefix->family = AF_INET6; + prefix->bitlen = width; + prefix->ref_count = 1; return prefix; } IPPrefix PrefixTable::PrefixToIPPrefix(prefix_t* prefix) { - if ( prefix->family == AF_INET ) - { - return IPPrefix(IPAddr(IPv4, reinterpret_cast(&prefix->add.sin), IPAddr::Network), prefix->bitlen); - } - else if ( prefix->family == AF_INET6 ) - { - return IPPrefix(IPAddr(IPv6, reinterpret_cast(&prefix->add.sin6), IPAddr::Network), prefix->bitlen, 0); - } - else - { - reporter->InternalWarning("Unknown prefix family for PrefixToIPAddr"); - return IPPrefix(); - } + return IPPrefix(IPAddr(IPv6, reinterpret_cast(&prefix->add.sin6), IPAddr::Network), prefix->bitlen, 1); } void* PrefixTable::Insert(const IPAddr& addr, int width, void* data) @@ -70,12 +48,12 @@ void* PrefixTable::Insert(const Val* value, void* data) switch ( value->Type()->Tag() ) { case TYPE_ADDR: - return Insert(value->AsAddr(), value->AsAddr().GetFamily() == IPv4 ? 32 : 128, data); + return Insert(value->AsAddr(), 128, data); break; case TYPE_SUBNET: return Insert(value->AsSubNet().Prefix(), - value->AsSubNet().Length(), data); + value->AsSubNet().LengthIPv6(), data); break; default: @@ -106,7 +84,7 @@ list PrefixTable::FindAll(const IPAddr& addr, int width) const list PrefixTable::FindAll(const SubNetVal* value) const { - return FindAll(value->AsSubNet().Prefix(), value->AsSubNet().Length()); + return FindAll(value->AsSubNet().Prefix(), value->AsSubNet().LengthIPv6()); } void* PrefixTable::Lookup(const IPAddr& addr, int width, bool exact) const @@ -132,12 +110,12 @@ void* PrefixTable::Lookup(const Val* value, bool exact) const switch ( value->Type()->Tag() ) { case TYPE_ADDR: - return Lookup(value->AsAddr(), value->AsAddr().GetFamily() == IPv4 ? 32 : 128, exact); + return Lookup(value->AsAddr(), 128, exact); break; case TYPE_SUBNET: return Lookup(value->AsSubNet().Prefix(), - value->AsSubNet().Length(), exact); + value->AsSubNet().LengthIPv6(), exact); break; default: @@ -171,12 +149,12 @@ void* PrefixTable::Remove(const Val* value) switch ( value->Type()->Tag() ) { case TYPE_ADDR: - return Remove(value->AsAddr(), value->AsAddr().GetFamily() == IPv4 ? 32 : 128); + return Remove(value->AsAddr(), 128); break; case TYPE_SUBNET: return Remove(value->AsSubNet().Prefix(), - value->AsSubNet().Length()); + value->AsSubNet().LengthIPv6()); break; default: From 08399da6cbc5d11a60439ddd1808d825ed7bdec5 Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Fri, 11 Mar 2016 12:56:28 -0500 Subject: [PATCH 80/93] Files transferred over FTP were showing incorrect sizes. The server-reported file size was being collected poorly and if a file name had a number in it, that was reported as the file size instead of the actual size. A new test is included to avoid reintroducing the problem. --- scripts/base/protocols/ftp/main.bro | 2 +- scripts/base/utils/numbers.bro | 30 ++++++++++++++---- .../ftp.log | 15 +++++++++ .../ftp/ftp-with-numbers-in-filename.pcap | Bin 0 -> 750496 bytes .../base/protocols/ftp/ftp-get-file-size.bro | 5 +++ 5 files changed, 44 insertions(+), 8 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.ftp.ftp-get-file-size/ftp.log create mode 100644 testing/btest/Traces/ftp/ftp-with-numbers-in-filename.pcap create mode 100644 testing/btest/scripts/base/protocols/ftp/ftp-get-file-size.bro 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/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/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/Traces/ftp/ftp-with-numbers-in-filename.pcap b/testing/btest/Traces/ftp/ftp-with-numbers-in-filename.pcap new file mode 100644 index 0000000000000000000000000000000000000000..02b4254ef2d31f5c3be98af6f19529923032baa3 GIT binary patch literal 750496 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
!idwTa<;9 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 z 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 e>}|LIy*EOBe)g|^$qRq#li!l$=l@MP|NjD7&s Date: Fri, 11 Mar 2016 09:57:35 -0800 Subject: [PATCH 81/93] Update baselines and news Includes tiny patches to make all test succesfully pass. --- NEWS | 24 +++++++++++++++++++ scripts/base/frameworks/netcontrol/main.bro | 6 ++++- testing/btest/Baseline/plugins.hooks/output | 21 +++++++++++----- .../all-events-no-args.log | 1 + .../all-events.log | 1 + .../frameworks/netcontrol/basic-cluster.bro | 14 +++++++++++ 6 files changed, 60 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index a394cb6e35..aa7c86f74e 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,9 @@ New Dependencies New Functionality ----------------- +- Bro now includes the NetControl framework. The framework allows the 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,6 +40,27 @@ 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. + +- Several built-in functions for handline 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. diff --git a/scripts/base/frameworks/netcontrol/main.bro b/scripts/base/frameworks/netcontrol/main.bro index 580d9b6d30..5b60f8d955 100644 --- a/scripts/base/frameworks/netcontrol/main.bro +++ b/scripts/base/frameworks/netcontrol/main.bro @@ -515,7 +515,11 @@ function check_plugins() if ( all_active ) { plugins_active = T; - log_msg_no_plugin("plugin initialization done"); + + # Skip log message if there are no plugins + if ( |plugins| > 0 ) + log_msg_no_plugin("plugin initialization done"); + event NetControl::init_done(); } } diff --git a/testing/btest/Baseline/plugins.hooks/output b/testing/btest/Baseline/plugins.hooks/output index b247670177..25808a20d8 100644 --- a/testing/btest/Baseline/plugins.hooks/output +++ b/testing/btest/Baseline/plugins.hooks/output @@ -228,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=1455741196.212164, 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)) -> @@ -346,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=1455741196.212164, 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, )) -> @@ -624,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)) @@ -856,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=1455741196.212164, 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)) @@ -974,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=1455741196.212164, 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, )) @@ -1252,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) @@ -1483,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=1455741196.212164, 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) @@ -1601,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=1455741196.212164, 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, ) @@ -1640,6 +1648,7 @@ 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() -> 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/scripts/base/frameworks/netcontrol/basic-cluster.bro b/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro index c476751d57..5c42f0d8eb 100644 --- a/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro +++ b/testing/btest/scripts/base/frameworks/netcontrol/basic-cluster.bro @@ -21,12 +21,26 @@ redef Log::default_rotation_interval = 0secs; @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; From f5ce4785ea96b56643c092331a16308f071c8092 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Fri, 11 Mar 2016 15:08:20 -0800 Subject: [PATCH 82/93] Updating submodule(s). [nomail] --- aux/binpac | 2 +- aux/bro-aux | 2 +- aux/broccoli | 2 +- aux/broctl | 2 +- cmake | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) 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/cmake b/cmake index 392e6be9b7..537e45afe1 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 392e6be9b7e0ac2e7a892853ef185a7a927ea60e +Subproject commit 537e45afe1006a10f73847fab5f13d28ce43fc4d From a6cb85d86a0a4b233e71a99dbc3b8ac1dc24f823 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Wed, 16 Mar 2016 15:50:13 -0700 Subject: [PATCH 83/93] Add filter_subnet_table bif This bif works similar to the matching_subnet bif. The difference is that, instead of returning a vector of the subnets that match, we return a filtered view of the original set/table only containing the changed subnets. This commit also fixes a small bug in TableVal::UpdateTimestamp (ReadOperation only has to be called when LoggingAccess() is true). --- src/PrefixTable.cc | 8 +-- src/PrefixTable.h | 4 +- src/Val.cc | 50 ++++++++++++++++++- src/Val.h | 10 ++++ src/bro.bif | 35 +++++++------ .../Baseline/bifs.filter_subnet_table/output | 20 ++++++++ testing/btest/bifs/filter_subnet_table.bro | 49 ++++++++++++++++++ 7 files changed, 153 insertions(+), 23 deletions(-) create mode 100644 testing/btest/Baseline/bifs.filter_subnet_table/output create mode 100644 testing/btest/bifs/filter_subnet_table.bro diff --git a/src/PrefixTable.cc b/src/PrefixTable.cc index 27f7c48c36..007e08349c 100644 --- a/src/PrefixTable.cc +++ b/src/PrefixTable.cc @@ -62,9 +62,9 @@ void* PrefixTable::Insert(const Val* value, void* data) } } -list PrefixTable::FindAll(const IPAddr& addr, int width) const +list> PrefixTable::FindAll(const IPAddr& addr, int width) const { - std::list out; + std::list> out; prefix_t* prefix = MakePrefix(addr, width); int elems = 0; @@ -73,14 +73,14 @@ list PrefixTable::FindAll(const IPAddr& addr, int width) const patricia_search_all(tree, prefix, &list, &elems); for ( int i = 0; i < elems; ++i ) - out.push_back(PrefixToIPPrefix(list[i]->prefix)); + 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 +list> PrefixTable::FindAll(const SubNetVal* value) const { return FindAll(value->AsSubNet().Prefix(), value->AsSubNet().LengthIPv6()); } diff --git a/src/PrefixTable.h b/src/PrefixTable.h index 8c329c93a9..6606b77e81 100644 --- a/src/PrefixTable.h +++ b/src/PrefixTable.h @@ -37,8 +37,8 @@ public: 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; + 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); diff --git a/src/Val.cc b/src/Val.cc index 01a849c639..35233e9056 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -1833,6 +1833,54 @@ 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 ) + { + entry->SetExpireAccess(network_time); + if ( LoggingAccess() && attrs->FindAttr(ATTR_EXPIRE_READ) ) + ReadOperation(s, entry); + } + + Unref(s); // assign does not consume index + } + + return nt; + } + bool TableVal::UpdateTimestamp(Val* index) { TableEntryVal* v; @@ -1854,7 +1902,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; diff --git a/src/Val.h b/src/Val.h index fdc60436bf..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); diff --git a/src/bro.bif b/src/bro.bif index 38f588d675..2c55c2bc95 100644 --- a/src/bro.bif +++ b/src/bro.bif @@ -1031,7 +1031,7 @@ function clear_table%(v: any%): any return 0; %} -## Gets all subnets that match a given subnet from a set/table[subnet] +## Gets all subnets that contain a given subnet from a set/table[subnet] ## ## search: the subnet to search for. ## @@ -1046,23 +1046,26 @@ function matching_subnets%(search: subnet, t: any%): subnet_vec return nullptr; } - const PrefixTable* pt = t->AsTableVal()->Subnets(); - if ( ! pt ) + 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("matching_subnets encountered nonexisting prefix table."); + reporter->Error("filter_subnet_table needs to be called on a set[subnet]/table[subnet]."); return nullptr; } - VectorVal* result_v = new VectorVal(internal_type("subnet_vec")->AsVectorType()); - - auto matches = pt->FindAll(search); - for ( auto element : matches ) - { - SubNetVal* s = new SubNetVal(element); - result_v->Assign(result_v->Size(), s); - } - - return result_v; + return t->AsTableVal()->LookupSubnetValues(search); %} ## Checks if a specific subnet is a member of a set/table[subnet]. @@ -1078,14 +1081,14 @@ function check_subnet%(search: subnet, t: any%): bool %{ if ( t->Type()->Tag() != TYPE_TABLE || ! t->Type()->AsTableType()->IsSubNetIndex() ) { - reporter->Error("matching_subnets needs to be called on a set[subnet]/table[subnet]."); + 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("matching_subnets encountered nonexisting prefix table."); + reporter->Error("check_subnet encountered nonexisting prefix table."); return nullptr; } 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/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; + } From e8bdf14bfd2c08a43f9a26fa301ce253cf72e3ec Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Thu, 17 Mar 2016 13:49:06 -0500 Subject: [PATCH 84/93] Call ProtocolConfirmation in MySQL analyzer. --- src/analyzer/protocol/mysql/mysql-analyzer.pac | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/analyzer/protocol/mysql/mysql-analyzer.pac b/src/analyzer/protocol/mysql/mysql-analyzer.pac index 2108401436..cd3c6ffd5c 100644 --- a/src/analyzer/protocol/mysql/mysql-analyzer.pac +++ b/src/analyzer/protocol/mysql/mysql-analyzer.pac @@ -19,6 +19,10 @@ 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 ) From a5f4e8aafea1ab20fe266f384692904f4253b73a Mon Sep 17 00:00:00 2001 From: Jan Grashoefer Date: Thu, 17 Mar 2016 19:53:22 +0100 Subject: [PATCH 85/93] Added &read_expire testcase for subnet tables --- .../Baseline/language.expire_subnet/output | 27 ++++++ testing/btest/language/expire_subnet.test | 96 +++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 testing/btest/Baseline/language.expire_subnet/output create mode 100644 testing/btest/language/expire_subnet.test 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/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(); + } + } From d5034ccc19f8c5e4b48c0d8c2c03eb64caf662fd Mon Sep 17 00:00:00 2001 From: Jan Grashoefer Date: Thu, 17 Mar 2016 19:56:25 +0100 Subject: [PATCH 86/93] Fixed &read_expire for subnet-indexed tables --- src/Val.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Val.cc b/src/Val.cc index 35233e9056..ce15cb9179 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -1787,7 +1787,18 @@ Val* TableVal::Lookup(Val* index, bool use_default_val) { TableEntryVal* v = (TableEntryVal*) subnets->Lookup(index); if ( v ) + { + if ( attrs && + ! (attrs->FindAttr(ATTR_EXPIRE_WRITE) || + attrs->FindAttr(ATTR_EXPIRE_CREATE)) ) + { + v->SetExpireAccess(network_time); + if ( LoggingAccess() && expire_time ) + ReadOperation(index, v); + } + return v->Value() ? v->Value() : this; + } if ( ! use_default_val ) return 0; From 33f9eca0c8bc0a5850a5d1d3fc677031a35ab058 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Fri, 18 Mar 2016 11:23:44 -0700 Subject: [PATCH 87/93] Update TLS constants and extensions from IANA. --- scripts/base/protocols/ssl/consts.bro | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) 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", From 8de08047122ea105eed77815a479ee5bb866bd51 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Fri, 18 Mar 2016 12:33:59 -0700 Subject: [PATCH 88/93] Update NEWS --- NEWS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS b/NEWS index b2310b0f62..86c3b1891a 100644 --- a/NEWS +++ b/NEWS @@ -49,6 +49,9 @@ New Functionality - 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. From cfffb6e634eb40eb965461a7427a9f672fe32cc7 Mon Sep 17 00:00:00 2001 From: Johanna Amann Date: Fri, 18 Mar 2016 12:34:26 -0700 Subject: [PATCH 89/93] Check that there is only one of read, write, create_expire --- src/Attr.cc | 21 +++++++++++++++++++ .../language.expire_multiple-2/output | 1 + .../language.expire_multiple-3/output | 1 + .../Baseline/language.expire_multiple/output | 1 + testing/btest/language/expire_multiple.test | 12 +++++++++++ 5 files changed, 36 insertions(+) create mode 100644 testing/btest/Baseline/language.expire_multiple-2/output create mode 100644 testing/btest/Baseline/language.expire_multiple-3/output create mode 100644 testing/btest/Baseline/language.expire_multiple/output create mode 100644 testing/btest/language/expire_multiple.test 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/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/language/expire_multiple.test b/testing/btest/language/expire_multiple.test new file mode 100644 index 0000000000..2293873e59 --- /dev/null +++ b/testing/btest/language/expire_multiple.test @@ -0,0 +1,12 @@ +# @TEST-EXEC-FAIL: bro -b %INPUT >output 2>&1 +# @TEST-EXEC: 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; From 0588f3510bc69b018b5d6289db3fef7a9a9adf6f Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Mon, 21 Mar 2016 11:59:41 -0700 Subject: [PATCH 90/93] Updating submodule(s). [nomail] --- aux/broker | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 4e7e211ed0cc2a3e4085da4ca5b517d26b8025d2 Mon Sep 17 00:00:00 2001 From: Matthias Vallentin Date: Mon, 21 Mar 2016 16:54:12 -0700 Subject: [PATCH 91/93] Adapt to recent change in CAF CMake script Also deprecate --with-libcaf in favor of --with-caf, as already done in Broker. --- configure | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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 From 357d52fd7d8a66acacc51b7eeabd0b80aa078dc4 Mon Sep 17 00:00:00 2001 From: Matthias Vallentin Date: Mon, 21 Mar 2016 16:54:12 -0700 Subject: [PATCH 92/93] Adapt to recent change in CAF CMake script Also deprecate --with-libcaf in favor of --with-caf, as already done in Broker. --- configure | 6 +++++- src/broker/CMakeLists.txt | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) 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/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 From a9cb90b6f54b2cafd1127ab43f6b18e4038845dd Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Mon, 21 Mar 2016 21:08:42 -0700 Subject: [PATCH 93/93] Adding canonifier to test. --- testing/btest/language/expire_multiple.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/btest/language/expire_multiple.test b/testing/btest/language/expire_multiple.test index 2293873e59..1e4aaa0975 100644 --- a/testing/btest/language/expire_multiple.test +++ b/testing/btest/language/expire_multiple.test @@ -1,5 +1,5 @@ # @TEST-EXEC-FAIL: bro -b %INPUT >output 2>&1 -# @TEST-EXEC: btest-diff output +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff output global s: set[string] &create_expire=1secs &read_expire=1secs;