zeek/scripts/base/frameworks/pacf-proto/plugins/openflow.bro

111 lines
3 KiB
Text

@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];
}