mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Merge remote-tracking branch 'origin/topic/robin/pacf' into topic/johanna/openflow
This commit is contained in:
commit
94c67dc030
9 changed files with 839 additions and 0 deletions
3
scripts/base/frameworks/pacf/__load__.bro
Normal file
3
scripts/base/frameworks/pacf/__load__.bro
Normal file
|
@ -0,0 +1,3 @@
|
|||
@load ./types
|
||||
@load ./main
|
||||
@load ./plugins
|
477
scripts/base/frameworks/pacf/main.bro
Normal file
477
scripts/base/frameworks/pacf/main.bro
Normal file
|
@ -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 = "<unknown entity type>";
|
||||
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="")
|
||||
{
|
||||
}
|
||||
|
||||
|
91
scripts/base/frameworks/pacf/plugin.bro
Normal file
91
scripts/base/frameworks/pacf/plugin.bro
Normal file
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
1
scripts/base/frameworks/pacf/plugins/__load__.bro
Normal file
1
scripts/base/frameworks/pacf/plugins/__load__.bro
Normal file
|
@ -0,0 +1 @@
|
|||
@load ./debug
|
119
scripts/base/frameworks/pacf/plugins/debug.bro
Normal file
119
scripts/base/frameworks/pacf/plugins/debug.bro
Normal file
|
@ -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;
|
||||
}
|
||||
|
||||
|
122
scripts/base/frameworks/pacf/types.bro
Normal file
122
scripts/base/frameworks/pacf/types.bro
Normal file
|
@ -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.
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -120,6 +120,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`.
|
||||
##
|
||||
|
|
|
@ -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
|
||||
|
|
13
src/bro.bif
13
src/bro.bif
|
@ -2366,6 +2366,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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue