mirror of
https://github.com/zeek/zeek.git
synced 2025-10-05 16:18:19 +00:00
First step of DHCP analyzer rearchitecture.
Old event prototypes have changed and the events are broken right now and may be removed in favor of the new generic "dhcp_message" event. DHCP option parsing is abstracted from the main code base of the protocol parser and are all now located in their own file. Documentation, tests, and final code cleanup are still pending.
This commit is contained in:
parent
ba49ab8201
commit
c2f35920fd
14 changed files with 728 additions and 498 deletions
|
@ -3064,11 +3064,12 @@ export {
|
||||||
## A list of router addresses offered by a DHCP server.
|
## A list of router addresses offered by a DHCP server.
|
||||||
##
|
##
|
||||||
## .. bro:see:: dhcp_ack dhcp_offer
|
## .. bro:see:: dhcp_ack dhcp_offer
|
||||||
type DHCP::dhcp_router_list: table[count] of addr;
|
type DHCP::RouterList: table[count] of addr;
|
||||||
|
|
||||||
## A DHCP message.
|
## A DHCP message.
|
||||||
## .. bro:see:: dhcp_ack dhcp_decline dhcp_discover dhcp_inform dhcp_nak
|
## .. bro:see:: dhcp_ack dhcp_decline dhcp_discover dhcp_inform dhcp_nak
|
||||||
## dhcp_offer dhcp_release dhcp_request
|
## dhcp_offer dhcp_release dhcp_request
|
||||||
type DHCP::dhcp_msg: record {
|
type DHCP::Msg: record {
|
||||||
op: count; ##< Message OP code. 1 = BOOTREQUEST, 2 = BOOTREPLY
|
op: count; ##< Message OP code. 1 = BOOTREQUEST, 2 = BOOTREPLY
|
||||||
m_type: count; ##< The type of DHCP message.
|
m_type: count; ##< The type of DHCP message.
|
||||||
xid: count; ##< Transaction ID of a DHCP session.
|
xid: count; ##< Transaction ID of a DHCP session.
|
||||||
|
@ -3076,22 +3077,55 @@ export {
|
||||||
ciaddr: addr; ##< Original IP address of the client.
|
ciaddr: addr; ##< Original IP address of the client.
|
||||||
yiaddr: addr; ##< IP address assigned to the client.
|
yiaddr: addr; ##< IP address assigned to the client.
|
||||||
};
|
};
|
||||||
## DHCP Paremeter Reuqest list (Option 55)
|
|
||||||
|
## DHCP Parameter Request list (Option 55)
|
||||||
## .. bro:see:: dhcp_request dhcp_discover
|
## .. bro:see:: dhcp_request dhcp_discover
|
||||||
type DHCP::dhcp_params_list: table[count] of count;
|
type DHCP::ParamsList: table[count] of count;
|
||||||
|
|
||||||
## DHCP Relay Agent Information Option (Option 82)
|
## DHCP Relay Agent Information Option (Option 82)
|
||||||
## .. bro:see:: dhcp_ack
|
## .. bro:see:: dhcp_ack
|
||||||
type DHCP::dhcp_sub_opt: record {
|
type DHCP::SubOpt: record {
|
||||||
code: count;
|
code: count;
|
||||||
value: string;
|
value: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
## DHCP Client Identifier (Option 61)
|
## DHCP Client Identifier (Option 61)
|
||||||
## .. bro:see:: dhcp_request dhcp_discover
|
## .. bro:see:: dhcp_request dhcp_discover
|
||||||
type DHCP::dhcp_client_id: record {
|
type DHCP::ClientID: record {
|
||||||
hwtype: count;
|
hwtype: count;
|
||||||
hwaddr: string;
|
hwaddr: string;
|
||||||
};
|
};
|
||||||
type DHCP::dhcp_sub_opt_list: table[count] of DHCP::dhcp_sub_opt;
|
|
||||||
|
type DHCP::SubOptList: table[count] of DHCP::SubOpt;
|
||||||
|
|
||||||
|
type DHCP::Options: record {
|
||||||
|
subnet_mask: addr &optional;
|
||||||
|
|
||||||
|
host_name: string &optional;
|
||||||
|
|
||||||
|
req_addr: addr &optional;
|
||||||
|
|
||||||
|
router_list: DHCP::RouterList &optional;
|
||||||
|
|
||||||
|
lease: interval &optional;
|
||||||
|
|
||||||
|
serv_addr: addr &optional;
|
||||||
|
|
||||||
|
## DHCP Parameter Request list (Option 55)
|
||||||
|
param_list: DHCP::ParamsList &optional;
|
||||||
|
|
||||||
|
ren_time: interval &optional;
|
||||||
|
|
||||||
|
reb_time: interval &optional;
|
||||||
|
|
||||||
|
## DHCP Client Identifier (Option 61)
|
||||||
|
client_id: DHCP::ClientID &optional;
|
||||||
|
|
||||||
|
## DHCP Relay Agent Information Option (Option 82)
|
||||||
|
sub_opt: DHCP::SubOptList &optional;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module GLOBAL;
|
module GLOBAL;
|
||||||
|
|
|
@ -7,14 +7,24 @@ export {
|
||||||
|
|
||||||
## Types of DHCP messages. See :rfc:`1533`.
|
## Types of DHCP messages. See :rfc:`1533`.
|
||||||
const message_types = {
|
const message_types = {
|
||||||
[1] = "DHCP_DISCOVER",
|
[1] = "DHCP_DISCOVER",
|
||||||
[2] = "DHCP_OFFER",
|
[2] = "DHCP_OFFER",
|
||||||
[3] = "DHCP_REQUEST",
|
[3] = "DHCP_REQUEST",
|
||||||
[4] = "DHCP_DECLINE",
|
[4] = "DHCP_DECLINE",
|
||||||
[5] = "DHCP_ACK",
|
[5] = "DHCP_ACK",
|
||||||
[6] = "DHCP_NAK",
|
[6] = "DHCP_NAK",
|
||||||
[7] = "DHCP_RELEASE",
|
[7] = "DHCP_RELEASE",
|
||||||
[8] = "DHCP_INFORM",
|
[8] = "DHCP_INFORM",
|
||||||
|
[9] = "DHCP_FORCERENEW",
|
||||||
|
[10] = "DHCP_LEASEQUERY",
|
||||||
|
[11] = "DHCP_LEASEUNASSIGNED",
|
||||||
|
[12] = "DHCP_DHCPLEASEUNKNOWN",
|
||||||
|
[13] = "DHCP_LEASEACTIVE",
|
||||||
|
[14] = "DHCP_BULKLEASEQUERY",
|
||||||
|
[15] = "DHCP_LEASEQUERYDONE",
|
||||||
|
[16] = "DHCP_ACTIVELEASEQUERY",
|
||||||
|
[17] = "DHCP_LEASEQUERYSTATUS",
|
||||||
|
[18] = "DHCP_TLS",
|
||||||
} &default = function(n: count): string { return fmt("unknown-message-type-%d", n); };
|
} &default = function(n: count): string { return fmt("unknown-message-type-%d", n); };
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,91 +59,60 @@ redef record connection += {
|
||||||
const ports = { 67/udp, 68/udp };
|
const ports = { 67/udp, 68/udp };
|
||||||
redef likely_server_ports += { 67/udp };
|
redef likely_server_ports += { 67/udp };
|
||||||
|
|
||||||
global info: Info;
|
|
||||||
|
|
||||||
event bro_init() &priority=5
|
event bro_init() &priority=5
|
||||||
{
|
{
|
||||||
Log::create_stream(DHCP::LOG, [$columns=Info, $ev=log_dhcp, $path="dhcp"]);
|
Log::create_stream(DHCP::LOG, [$columns=Info, $ev=log_dhcp, $path="dhcp"]);
|
||||||
Analyzer::register_for_ports(Analyzer::ANALYZER_DHCP, ports);
|
Analyzer::register_for_ports(Analyzer::ANALYZER_DHCP, ports);
|
||||||
}
|
}
|
||||||
|
|
||||||
event dhcp_ack(c: connection, msg: dhcp_msg, mask: addr, router: dhcp_router_list, lease: interval, serv_addr: addr, host_name: string, reb_time: count, ren_time: count, sub_opt: dhcp_sub_opt_list) &priority=5
|
event dhcp_message(c: connection, is_orig: bool, msg: DHCP::Msg, options: DHCP::Options) &priority=-5
|
||||||
{
|
{
|
||||||
#local info: Info;
|
if ( msg$m_type == 5 ) # DHCP_ACK
|
||||||
info$ts = network_time();
|
{
|
||||||
info$id = c$id;
|
local info = Info($ts = network_time(),
|
||||||
info$uid = c$uid;
|
$id = c$id,
|
||||||
info$lease_time = lease;
|
$uid = c$uid,
|
||||||
info$trans_id = msg$xid;
|
$trans_id = msg$xid);
|
||||||
info$msg_type = message_types[msg$m_type];
|
|
||||||
|
|
||||||
info$server_id = serv_addr;
|
if ( msg$h_addr != "" )
|
||||||
info$host_name = host_name;
|
info$mac = msg$h_addr;
|
||||||
|
|
||||||
if ( msg$h_addr != "" )
|
if ( reverse_ip(msg$yiaddr) != 0.0.0.0 )
|
||||||
info$mac = msg$h_addr;
|
info$assigned_ip = reverse_ip(msg$yiaddr);
|
||||||
|
else
|
||||||
|
info$assigned_ip = c$id$orig_h;
|
||||||
|
|
||||||
if ( reverse_ip(msg$yiaddr) != 0.0.0.0 )
|
if ( options?$lease )
|
||||||
info$assigned_ip = reverse_ip(msg$yiaddr);
|
info$lease_time = options$lease;
|
||||||
else
|
|
||||||
info$assigned_ip = c$id$orig_h;
|
|
||||||
|
|
||||||
for (param in sub_opt)
|
if ( options?$sub_opt )
|
||||||
{
|
{
|
||||||
#if ( sub_opt[param]$code == 1 )
|
for ( param in options$sub_opt )
|
||||||
#{
|
{
|
||||||
#print fmt("Relay Agent Information:");
|
local sub_opt = options$sub_opt[param];
|
||||||
#print fmt( "sub option: code=%d circuit id=%s",sub_opt[param]$code,sub_opt[param]$value );
|
|
||||||
#}
|
|
||||||
if ( sub_opt[param]$code == 2 )
|
|
||||||
info$agent_remote_id = bytestring_to_hexstr(sub_opt[param]$value);
|
|
||||||
|
|
||||||
if ( sub_opt[param]$code == 6 )
|
#if ( sub_opt$code == 1 )
|
||||||
info$subscriber_id = (sub_opt[param]$value);
|
# {
|
||||||
|
# print fmt("Relay Agent Information:");
|
||||||
|
# print fmt( "sub option: code=%d circuit id=%s",sub_opt$code,sub_opt$value );
|
||||||
|
# }
|
||||||
|
|
||||||
|
if ( sub_opt$code == 2 )
|
||||||
|
info$agent_remote_id = bytestring_to_hexstr(sub_opt$value);
|
||||||
|
|
||||||
|
if ( sub_opt$code == 6 )
|
||||||
|
info$subscriber_id = (sub_opt$value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c$dhcp = info;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c$dhcp = info;
|
event dhcp_message(c: connection, is_orig: bool, msg: DHCP::Msg, options: DHCP::Options) &priority=-5
|
||||||
}
|
|
||||||
|
|
||||||
event dhcp_ack(c: connection, msg: dhcp_msg, mask: addr, router: dhcp_router_list, lease: interval, serv_addr: addr, host_name: string, reb_time: count, ren_time: count, sub_opt: dhcp_sub_opt_list) &priority=-5
|
|
||||||
{
|
{
|
||||||
Log::write(DHCP::LOG, c$dhcp);
|
if ( msg$m_type == 5 ) # DHCP_ACK
|
||||||
|
{
|
||||||
|
Log::write(DHCP::LOG, c$dhcp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
event dhcp_request(c: connection, msg: dhcp_msg, req_addr: addr, serv_addr: addr, host_name: string, c_id: dhcp_client_id, req_params: table[count] of count) &priority=5
|
|
||||||
{
|
|
||||||
info$ts = network_time();
|
|
||||||
info$id = c$id;
|
|
||||||
info$uid = c$uid;
|
|
||||||
info$trans_id = msg$xid;
|
|
||||||
info$msg_type = message_types[msg$m_type];
|
|
||||||
info$server_id = serv_addr;
|
|
||||||
info$host_name = host_name;
|
|
||||||
info$client_id = c_id$hwaddr;
|
|
||||||
|
|
||||||
c$dhcp = info;
|
|
||||||
}
|
|
||||||
|
|
||||||
event dhcp_request(c: connection, msg: dhcp_msg, req_addr: addr, serv_addr: addr, host_name: string, c_id: dhcp_client_id, req_params: table[count] of count) &priority=-5
|
|
||||||
{
|
|
||||||
Log::write(DHCP::LOG, c$dhcp);
|
|
||||||
}
|
|
||||||
|
|
||||||
event dhcp_discover(c: connection, msg: dhcp_msg, req_addr: addr, host_name: string, c_id: dhcp_client_id, req_params: table[count] of count) &priority=5
|
|
||||||
{
|
|
||||||
info$ts = network_time();
|
|
||||||
info$id = c$id;
|
|
||||||
info$uid = c$uid;
|
|
||||||
info$trans_id = msg$xid;
|
|
||||||
info$msg_type = message_types[msg$m_type];
|
|
||||||
info$host_name = host_name;
|
|
||||||
info$client_id = c_id$hwaddr;
|
|
||||||
|
|
||||||
c$dhcp = info;
|
|
||||||
}
|
|
||||||
|
|
||||||
event dhcp_discover(c: connection, msg: dhcp_msg, req_addr: addr, host_name: string, c_id: dhcp_client_id, req_params: table[count] of count) &priority=-5
|
|
||||||
{
|
|
||||||
Log::write(DHCP::LOG, c$dhcp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -110,9 +110,6 @@ RecordType* geo_location;
|
||||||
|
|
||||||
RecordType* entropy_test_result;
|
RecordType* entropy_test_result;
|
||||||
|
|
||||||
TableType* dhcp_router_list;
|
|
||||||
RecordType* dhcp_msg;
|
|
||||||
|
|
||||||
RecordType* dns_msg;
|
RecordType* dns_msg;
|
||||||
RecordType* dns_answer;
|
RecordType* dns_answer;
|
||||||
RecordType* dns_soa;
|
RecordType* dns_soa;
|
||||||
|
@ -426,9 +423,6 @@ void init_net_var()
|
||||||
|
|
||||||
entropy_test_result = internal_type("entropy_test_result")->AsRecordType();
|
entropy_test_result = internal_type("entropy_test_result")->AsRecordType();
|
||||||
|
|
||||||
dhcp_router_list = internal_type("DHCP::dhcp_router_list")->AsTableType();
|
|
||||||
dhcp_msg = internal_type("DHCP::dhcp_msg")->AsRecordType();
|
|
||||||
|
|
||||||
dns_msg = internal_type("dns_msg")->AsRecordType();
|
dns_msg = internal_type("dns_msg")->AsRecordType();
|
||||||
dns_answer = internal_type("dns_answer")->AsRecordType();
|
dns_answer = internal_type("dns_answer")->AsRecordType();
|
||||||
dns_soa = internal_type("dns_soa")->AsRecordType();
|
dns_soa = internal_type("dns_soa")->AsRecordType();
|
||||||
|
|
|
@ -113,9 +113,6 @@ extern RecordType* geo_location;
|
||||||
|
|
||||||
extern RecordType* entropy_test_result;
|
extern RecordType* entropy_test_result;
|
||||||
|
|
||||||
extern TableType* dhcp_router_list;
|
|
||||||
extern RecordType* dhcp_msg;
|
|
||||||
|
|
||||||
extern RecordType* dns_msg;
|
extern RecordType* dns_msg;
|
||||||
extern RecordType* dns_answer;
|
extern RecordType* dns_answer;
|
||||||
extern RecordType* dns_soa;
|
extern RecordType* dns_soa;
|
||||||
|
|
|
@ -7,5 +7,5 @@ bro_plugin_begin(Bro DHCP)
|
||||||
bro_plugin_cc(DHCP.cc Plugin.cc)
|
bro_plugin_cc(DHCP.cc Plugin.cc)
|
||||||
bro_plugin_bif(events.bif)
|
bro_plugin_bif(events.bif)
|
||||||
bro_plugin_bif(types.bif)
|
bro_plugin_bif(types.bif)
|
||||||
bro_plugin_pac(dhcp.pac dhcp-protocol.pac dhcp-analyzer.pac)
|
bro_plugin_pac(dhcp.pac dhcp-protocol.pac dhcp-analyzer.pac dhcp-options.pac)
|
||||||
bro_plugin_end()
|
bro_plugin_end()
|
||||||
|
|
|
@ -25,5 +25,14 @@ void DHCP_Analyzer::DeliverPacket(int len, const u_char* data,
|
||||||
bool orig, uint64 seq, const IP_Hdr* ip, int caplen)
|
bool orig, uint64 seq, const IP_Hdr* ip, int caplen)
|
||||||
{
|
{
|
||||||
Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen);
|
Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen);
|
||||||
interp->NewData(orig, data, data + len);
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
interp->NewData(orig, data, data + len);
|
||||||
|
}
|
||||||
|
catch ( const binpac::Exception& e )
|
||||||
|
{
|
||||||
|
ProtocolViolation(fmt("Binpac exception: %s", e.c_msg()));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,11 @@ namespace analyzer { namespace dhcp {
|
||||||
class DHCP_Analyzer : public analyzer::Analyzer {
|
class DHCP_Analyzer : public analyzer::Analyzer {
|
||||||
public:
|
public:
|
||||||
DHCP_Analyzer(Connection* conn);
|
DHCP_Analyzer(Connection* conn);
|
||||||
virtual ~DHCP_Analyzer();
|
~DHCP_Analyzer() override;
|
||||||
|
|
||||||
virtual void Done();
|
void Done() override;
|
||||||
virtual void DeliverPacket(int len, const u_char* data, bool orig,
|
void DeliverPacket(int len, const u_char* data, bool orig,
|
||||||
uint64 seq, const IP_Hdr* ip, int caplen);
|
uint64 seq, const IP_Hdr* ip, int caplen) override;
|
||||||
|
|
||||||
static analyzer::Analyzer* Instantiate(Connection* conn)
|
static analyzer::Analyzer* Instantiate(Connection* conn)
|
||||||
{ return new DHCP_Analyzer(conn); }
|
{ return new DHCP_Analyzer(conn); }
|
||||||
|
|
|
@ -1,284 +1,140 @@
|
||||||
connection DHCP_Conn(bro_analyzer: BroAnalyzer) {
|
|
||||||
upflow = DHCP_Flow(true);
|
|
||||||
downflow = DHCP_Flow(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
flow DHCP_Flow(is_orig: bool) {
|
|
||||||
datagram = DHCP_Message withcontext(connection, this);
|
|
||||||
|
|
||||||
|
refine flow DHCP_Flow += {
|
||||||
%member{
|
%member{
|
||||||
BroVal dhcp_msg_val_;
|
RecordVal *dhcp_msg_val;
|
||||||
uint8 sum_len;
|
RecordVal *options;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%init{
|
%init{
|
||||||
dhcp_msg_val_ = 0;
|
dhcp_msg_val = 0;
|
||||||
sum_len = 0;
|
options = 0;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%cleanup{
|
%cleanup{
|
||||||
Unref(dhcp_msg_val_);
|
Unref(dhcp_msg_val);
|
||||||
dhcp_msg_val_ = 0;
|
dhcp_msg_val = 0;
|
||||||
sum_len = 0;
|
|
||||||
|
Unref(options);
|
||||||
|
options = 0;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
function get_dhcp_sumlen(len: uint8): uint8
|
function parse_request(options: Option[], type: uint8): bool
|
||||||
%{
|
%{
|
||||||
sum_len = len + sum_len;
|
// // Requested IP address to the server.
|
||||||
return sum_len;
|
// ::uint32 req_addr = 0, serv_addr = 0;
|
||||||
%}
|
// StringVal* host_name = new StringVal("");
|
||||||
|
//
|
||||||
function get_dhcp_msgtype(options: DHCP_Option[]): uint8
|
// TableVal* params_list = 0;
|
||||||
%{
|
// RecordVal* client_id = new RecordVal(BifType::Record::DHCP::ClientID);
|
||||||
vector<DHCP_Option*>::const_iterator ptr;
|
// client_id->Assign(0,0);
|
||||||
uint8 type = 0;
|
// client_id->Assign(1,new StringVal(""));
|
||||||
|
//
|
||||||
// Leave the for loop if the message type is found.
|
// switch ( type )
|
||||||
bool parsed = false;
|
// {
|
||||||
|
// case DHCPDISCOVER:
|
||||||
for ( ptr = options->begin();
|
// BifEvent::generate_dhcp_discover(connection()->bro_analyzer(),
|
||||||
ptr != options->end() && ! (*ptr)->last(); ++ptr )
|
// connection()->bro_analyzer()->Conn(),
|
||||||
{
|
// dhcp_msg_val->Ref(), new AddrVal(req_addr),
|
||||||
// We use a switch for future expandability.
|
// host_name, client_id, params_list);
|
||||||
switch ( (*ptr)->code() ) {
|
// break;
|
||||||
case MSG_TYPE_OPTION:
|
//
|
||||||
type = (*ptr)->info()->msg_type();
|
// case DHCPREQUEST:
|
||||||
parsed = true;
|
// BifEvent::generate_dhcp_request(connection()->bro_analyzer(),
|
||||||
break;
|
// connection()->bro_analyzer()->Conn(),
|
||||||
}
|
// dhcp_msg_val->Ref(), new AddrVal(req_addr),
|
||||||
|
// new AddrVal(serv_addr), host_name, client_id, params_list);
|
||||||
if ( parsed )
|
// break;
|
||||||
break;
|
//
|
||||||
}
|
// case DHCPDECLINE:
|
||||||
|
// BifEvent::generate_dhcp_decline(connection()->bro_analyzer(),
|
||||||
if ( type == 0 )
|
// connection()->bro_analyzer()->Conn(),
|
||||||
connection()->bro_analyzer()->ProtocolViolation("no DHCP message type option");
|
// dhcp_msg_val->Ref(), host_name);
|
||||||
|
// break;
|
||||||
return type;
|
//
|
||||||
%}
|
// case DHCPRELEASE:
|
||||||
|
// BifEvent::generate_dhcp_release(connection()->bro_analyzer(),
|
||||||
function parse_request(options: DHCP_Option[], type: uint8): bool
|
// connection()->bro_analyzer()->Conn(),
|
||||||
%{
|
// dhcp_msg_val->Ref(), host_name);
|
||||||
vector<DHCP_Option*>::const_iterator ptr;
|
// break;
|
||||||
|
//
|
||||||
// Requested IP address to the server.
|
// case DHCPINFORM:
|
||||||
::uint32 req_addr = 0, serv_addr = 0;
|
// BifEvent::generate_dhcp_inform(connection()->bro_analyzer(),
|
||||||
StringVal* host_name = new StringVal("");
|
// connection()->bro_analyzer()->Conn(),
|
||||||
|
// dhcp_msg_val->Ref(), host_name, params_list);
|
||||||
TableVal* params_list = 0;
|
// break;
|
||||||
RecordVal* client_id = new RecordVal(BifType::Record::DHCP::dhcp_client_id);
|
//
|
||||||
client_id->Assign(0,0);
|
// default:
|
||||||
client_id->Assign(1,new StringVal(""));
|
// Unref(host_name);
|
||||||
|
// break;
|
||||||
for ( ptr = options->begin(); ptr != options->end() && ! (*ptr)->last(); ++ptr )
|
// }
|
||||||
{
|
|
||||||
switch ( (*ptr)->code() )
|
|
||||||
{
|
|
||||||
case REQ_IP_OPTION:
|
|
||||||
req_addr = htonl((*ptr)->info()->req_addr());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SERV_ID_OPTION:
|
|
||||||
serv_addr = htonl((*ptr)->info()->serv_addr());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HOST_NAME_OPTION:
|
|
||||||
host_name = new StringVal((*ptr)->info()->host_name().length(),
|
|
||||||
(const char*) (*ptr)->info()->host_name().begin());
|
|
||||||
break;
|
|
||||||
case CLIENT_ID_OPTION:
|
|
||||||
client_id->Assign(0, new Val((*ptr)->info()->client_id()->hwtype(), TYPE_COUNT));
|
|
||||||
client_id->Assign(1, new StringVal(fmt_mac((*ptr)->info()->client_id()->hwaddr().begin(), (*ptr)->info()->client_id()->hwaddr().length())));
|
|
||||||
break;
|
|
||||||
case PAR_REQ_LIST:
|
|
||||||
params_list = new TableVal(BifType::Table::DHCP::dhcp_params_list);
|
|
||||||
int num_parms = (*ptr)->info()->par_req_list()->size();
|
|
||||||
for (int i=0; i < num_parms; ++i)
|
|
||||||
{
|
|
||||||
vector<uint8>* plist = (*ptr)->info()->par_req_list();
|
|
||||||
uint8 param = (*plist)[i];
|
|
||||||
Val* index = new Val(i+1, TYPE_COUNT);
|
|
||||||
params_list->Assign(index, new Val(param, TYPE_COUNT));
|
|
||||||
Unref(index);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ( type )
|
|
||||||
{
|
|
||||||
case DHCPDISCOVER:
|
|
||||||
BifEvent::generate_dhcp_discover(connection()->bro_analyzer(),
|
|
||||||
connection()->bro_analyzer()->Conn(),
|
|
||||||
dhcp_msg_val_->Ref(), new AddrVal(req_addr),
|
|
||||||
host_name, client_id, params_list);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DHCPREQUEST:
|
|
||||||
BifEvent::generate_dhcp_request(connection()->bro_analyzer(),
|
|
||||||
connection()->bro_analyzer()->Conn(),
|
|
||||||
dhcp_msg_val_->Ref(), new AddrVal(req_addr),
|
|
||||||
new AddrVal(serv_addr), host_name, client_id, params_list);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DHCPDECLINE:
|
|
||||||
BifEvent::generate_dhcp_decline(connection()->bro_analyzer(),
|
|
||||||
connection()->bro_analyzer()->Conn(),
|
|
||||||
dhcp_msg_val_->Ref(), host_name);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DHCPRELEASE:
|
|
||||||
BifEvent::generate_dhcp_release(connection()->bro_analyzer(),
|
|
||||||
connection()->bro_analyzer()->Conn(),
|
|
||||||
dhcp_msg_val_->Ref(), host_name);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DHCPINFORM:
|
|
||||||
BifEvent::generate_dhcp_inform(connection()->bro_analyzer(),
|
|
||||||
connection()->bro_analyzer()->Conn(),
|
|
||||||
dhcp_msg_val_->Ref(), host_name, params_list);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
Unref(host_name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
function parse_reply(options: DHCP_Option[], type: uint8): bool
|
function parse_reply(options: Option[], type: uint8): bool
|
||||||
%{
|
%{
|
||||||
vector<DHCP_Option*>::const_iterator ptr;
|
// // RFC 1533 allows a list of router addresses.
|
||||||
vector<Relay_Agent_SubOption*>::const_iterator ptrsubopt;
|
// TableVal* router_list = 0;
|
||||||
|
//
|
||||||
|
// ::uint32 subnet_mask = 0, serv_addr = 0;
|
||||||
|
//
|
||||||
|
// uint32 lease = 0;
|
||||||
|
// StringVal* host_name = 0;
|
||||||
|
//
|
||||||
|
// uint32 reb_time = 0;
|
||||||
|
// uint32 ren_time = 0;
|
||||||
|
// StringVal* agent_cir = 0;
|
||||||
|
// StringVal* agent_rem = 0;
|
||||||
|
// StringVal* agent_sub_opt = 0;
|
||||||
|
// TableVal* relay_agent_sub_opt = new TableVal(BifType::Table::DHCP::SubOptList);
|
||||||
|
//
|
||||||
|
// if ( host_name == nullptr )
|
||||||
|
// host_name = new StringVal("");
|
||||||
|
//
|
||||||
|
// switch ( type )
|
||||||
|
// {
|
||||||
|
// case DHCPOFFER:
|
||||||
|
// if ( ! router_list )
|
||||||
|
// router_list = new TableVal(BifType::Table::DHCP::RouterList);
|
||||||
|
//
|
||||||
|
// BifEvent::generate_dhcp_offer(connection()->bro_analyzer(),
|
||||||
|
// connection()->bro_analyzer()->Conn(),
|
||||||
|
// dhcp_msg_val->Ref(), new AddrVal(subnet_mask),
|
||||||
|
// router_list, lease, new AddrVal(serv_addr), host_name);
|
||||||
|
// break;
|
||||||
|
//
|
||||||
|
// case DHCPACK:
|
||||||
|
// if ( ! router_list )
|
||||||
|
// router_list = new TableVal(BifType::Table::DHCP::RouterList);
|
||||||
|
//
|
||||||
|
// BifEvent::generate_dhcp_ack(connection()->bro_analyzer(),
|
||||||
|
// connection()->bro_analyzer()->Conn(),
|
||||||
|
// dhcp_msg_val->Ref(), new AddrVal(subnet_mask),
|
||||||
|
// router_list, lease, new AddrVal(serv_addr), host_name, reb_time, ren_time, relay_agent_sub_opt);
|
||||||
|
// break;
|
||||||
|
//
|
||||||
|
// case DHCPNAK:
|
||||||
|
// //Unref(router_list);
|
||||||
|
// BifEvent::generate_dhcp_nak(connection()->bro_analyzer(),
|
||||||
|
// connection()->bro_analyzer()->Conn(),
|
||||||
|
// dhcp_msg_val->Ref(), host_name);
|
||||||
|
// break;
|
||||||
|
//
|
||||||
|
// default:
|
||||||
|
// //Unref(router_list);
|
||||||
|
// //Unref(host_name);
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
|
||||||
// RFC 1533 allows a list of router addresses.
|
function create_options(): bool
|
||||||
TableVal* router_list = 0;
|
%{
|
||||||
|
if ( options == nullptr )
|
||||||
::uint32 subnet_mask = 0, serv_addr = 0;
|
options = new RecordVal(BifType::Record::DHCP::Options);
|
||||||
|
|
||||||
uint32 lease = 0;
|
|
||||||
StringVal* host_name = 0;
|
|
||||||
|
|
||||||
uint32 reb_time = 0;
|
|
||||||
uint32 ren_time = 0;
|
|
||||||
StringVal* agent_cir = 0;
|
|
||||||
StringVal* agent_rem = 0;
|
|
||||||
StringVal* agent_sub_opt = 0;
|
|
||||||
TableVal* relay_agent_sub_opt = new TableVal(BifType::Table::DHCP::dhcp_sub_opt_list);
|
|
||||||
|
|
||||||
for ( ptr = options->begin();
|
|
||||||
ptr != options->end() && ! (*ptr)->last(); ++ptr )
|
|
||||||
{
|
|
||||||
switch ( (*ptr)->code() )
|
|
||||||
{
|
|
||||||
case SUBNET_OPTION:
|
|
||||||
subnet_mask = htonl((*ptr)->info()->mask());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ROUTER_OPTION:
|
|
||||||
// Let's hope there aren't multiple
|
|
||||||
// such options.
|
|
||||||
//Unref(router_list);
|
|
||||||
router_list = new TableVal(dhcp_router_list);
|
|
||||||
|
|
||||||
{
|
|
||||||
int num_routers = (*ptr)->info()->router_list()->size();
|
|
||||||
|
|
||||||
for ( int i = 0; i < num_routers; ++i )
|
|
||||||
{
|
|
||||||
vector<uint32>* rlist = (*ptr)->info()->router_list();
|
|
||||||
|
|
||||||
uint32 raddr = (*rlist)[i];
|
|
||||||
::uint32 tmp_addr;
|
|
||||||
tmp_addr = htonl(raddr);
|
|
||||||
|
|
||||||
// index starting from 1
|
|
||||||
Val* index = new Val(i + 1, TYPE_COUNT);
|
|
||||||
router_list->Assign(index, new AddrVal(tmp_addr));
|
|
||||||
Unref(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LEASE_OPTION:
|
|
||||||
lease = (*ptr)->info()->lease();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SERV_ID_OPTION:
|
|
||||||
serv_addr = htonl((*ptr)->info()->serv_addr());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HOST_NAME_OPTION:
|
|
||||||
host_name = new StringVal((*ptr)->info()->host_name().length(),
|
|
||||||
(const char*) (*ptr)->info()->host_name().begin());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case REB_TIME_OPTION:
|
|
||||||
reb_time = (*ptr)->info()->reb_time();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case REN_TIME_OPTION:
|
|
||||||
ren_time = (*ptr)->info()->ren_time();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RELAY_AGENT_INF:
|
|
||||||
RecordVal* r = new RecordVal(BifType::Record::DHCP::dhcp_sub_opt);
|
|
||||||
uint i = 0;
|
|
||||||
for( ptrsubopt = (*ptr)->info()->relay_agent_inf()->begin(); ptrsubopt != (*ptr)->info()->relay_agent_inf()->end(); ++ptrsubopt)
|
|
||||||
{
|
|
||||||
r = new RecordVal(BifType::Record::DHCP::dhcp_sub_opt);
|
|
||||||
Val* index = new Val(i + 1, TYPE_COUNT);
|
|
||||||
r->Assign(0, new Val((*ptrsubopt)->code(), TYPE_COUNT));
|
|
||||||
r->Assign(1, bytestring_to_val((*ptrsubopt)->value()));
|
|
||||||
relay_agent_sub_opt->Assign(index, r);
|
|
||||||
Unref(index);
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( host_name == 0 )
|
|
||||||
host_name = new StringVal("");
|
|
||||||
|
|
||||||
switch ( type )
|
|
||||||
{
|
|
||||||
case DHCPOFFER:
|
|
||||||
if ( ! router_list )
|
|
||||||
router_list = new TableVal(dhcp_router_list);
|
|
||||||
|
|
||||||
BifEvent::generate_dhcp_offer(connection()->bro_analyzer(),
|
|
||||||
connection()->bro_analyzer()->Conn(),
|
|
||||||
dhcp_msg_val_->Ref(), new AddrVal(subnet_mask),
|
|
||||||
router_list, lease, new AddrVal(serv_addr), host_name);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DHCPACK:
|
|
||||||
if ( ! router_list )
|
|
||||||
router_list = new TableVal(dhcp_router_list);
|
|
||||||
|
|
||||||
BifEvent::generate_dhcp_ack(connection()->bro_analyzer(),
|
|
||||||
connection()->bro_analyzer()->Conn(),
|
|
||||||
dhcp_msg_val_->Ref(), new AddrVal(subnet_mask),
|
|
||||||
router_list, lease, new AddrVal(serv_addr), host_name, reb_time, ren_time, relay_agent_sub_opt);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DHCPNAK:
|
|
||||||
//Unref(router_list);
|
|
||||||
BifEvent::generate_dhcp_nak(connection()->bro_analyzer(),
|
|
||||||
connection()->bro_analyzer()->Conn(),
|
|
||||||
dhcp_msg_val_->Ref(), host_name);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
//Unref(router_list);
|
|
||||||
//Unref(host_name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
function process_dhcp_message(msg: DHCP_Message): bool
|
function process_dhcp_message(msg: DHCP_Message): bool
|
||||||
|
@ -292,55 +148,81 @@ flow DHCP_Flow(is_orig: bool) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Unref(dhcp_msg_val_);
|
Unref(dhcp_msg_val);
|
||||||
|
|
||||||
std::string mac_str = fmt_mac(${msg.chaddr}.data(), ${msg.chaddr}.length());
|
std::string mac_str = fmt_mac(${msg.chaddr}.data(), ${msg.chaddr}.length());
|
||||||
|
|
||||||
RecordVal* r = new RecordVal(dhcp_msg);
|
dhcp_msg_val = new RecordVal(BifType::Record::DHCP::Msg);
|
||||||
r->Assign(0, new Val(${msg.op}, TYPE_COUNT));
|
dhcp_msg_val->Assign(0, new Val(${msg.op}, TYPE_COUNT));
|
||||||
r->Assign(1, new Val(${msg.type}, TYPE_COUNT));
|
dhcp_msg_val->Assign(1, new Val(${msg.type}, TYPE_COUNT));
|
||||||
r->Assign(2, new Val(${msg.xid}, TYPE_COUNT));
|
dhcp_msg_val->Assign(2, new Val(${msg.xid}, TYPE_COUNT));
|
||||||
r->Assign(3, new StringVal(mac_str));
|
dhcp_msg_val->Assign(3, new StringVal(mac_str));
|
||||||
r->Assign(4, new AddrVal(${msg.ciaddr}));
|
dhcp_msg_val->Assign(4, new AddrVal(${msg.ciaddr}));
|
||||||
r->Assign(5, new AddrVal(${msg.yiaddr}));
|
dhcp_msg_val->Assign(5, new AddrVal(${msg.yiaddr}));
|
||||||
|
|
||||||
dhcp_msg_val_ = r;
|
if ( dhcp_message )
|
||||||
|
BifEvent::generate_dhcp_message(connection()->bro_analyzer(),
|
||||||
|
connection()->bro_analyzer()->Conn(),
|
||||||
|
${msg.is_orig},
|
||||||
|
dhcp_msg_val->Ref(),
|
||||||
|
options->Ref());
|
||||||
|
|
||||||
switch ( ${msg.op} )
|
Unref(dhcp_msg_val);
|
||||||
{
|
dhcp_msg_val = 0;
|
||||||
case BOOTREQUEST: // presumably from client to server
|
Unref(options);
|
||||||
if ( ${msg.type} == DHCPDISCOVER ||
|
options = 0;
|
||||||
${msg.type} == DHCPREQUEST ||
|
|
||||||
${msg.type} == DHCPDECLINE ||
|
|
||||||
${msg.type} == DHCPRELEASE ||
|
|
||||||
${msg.type} == DHCPINFORM )
|
|
||||||
parse_request(${msg.options}, ${msg.type});
|
|
||||||
else
|
|
||||||
connection()->bro_analyzer()->ProtocolViolation(fmt("unknown DHCP message type option for BOOTREQUEST (%d)",
|
|
||||||
${msg.type}));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BOOTREPLY: // presumably from server to client
|
//switch ( ${msg.op} )
|
||||||
if ( ${msg.type} == DHCPOFFER ||
|
// {
|
||||||
${msg.type} == DHCPACK ||
|
// case BOOTREQUEST: // presumably from client to server
|
||||||
${msg.type} == DHCPNAK ||
|
// if ( ${msg.type} == DHCPDISCOVER ||
|
||||||
${msg.type} == DHCPLEASEUNASSIGNED ||
|
// ${msg.type} == DHCPREQUEST ||
|
||||||
${msg.type} == DHCPLEASEUNKNOWN ||
|
// ${msg.type} == DHCPDECLINE ||
|
||||||
${msg.type} == DHCPLEASEACTIVE )
|
// ${msg.type} == DHCPRELEASE ||
|
||||||
parse_reply(${msg.options}, ${msg.type});
|
// ${msg.type} == DHCPINFORM )
|
||||||
else
|
// {
|
||||||
connection()->bro_analyzer()->ProtocolViolation(fmt("unknown DHCP message type option for BOOTREPLY (%d)",
|
// parse_request(${msg.options}, ${msg.type});
|
||||||
${msg.type}));
|
// }
|
||||||
|
// else
|
||||||
break;
|
// {
|
||||||
|
// connection()->bro_analyzer()->ProtocolViolation(fmt("unknown DHCP message type option for BOOTREQUEST (%d)",
|
||||||
default:
|
// ${msg.type}));
|
||||||
connection()->bro_analyzer()->ProtocolViolation(fmt("unknown DHCP message op code (%d). Known codes: 1=BOOTREQUEST, 2=BOOTREPLY",
|
// }
|
||||||
${msg.op}));
|
// break;
|
||||||
break;
|
//
|
||||||
}
|
// case BOOTREPLY: // presumably from server to client
|
||||||
|
// if ( ${msg.type} == DHCPOFFER ||
|
||||||
|
// ${msg.type} == DHCPACK ||
|
||||||
|
// ${msg.type} == DHCPNAK ||
|
||||||
|
// ${msg.type} == DHCPLEASEUNASSIGNED ||
|
||||||
|
// ${msg.type} == DHCPLEASEUNKNOWN ||
|
||||||
|
// ${msg.type} == DHCPLEASEACTIVE )
|
||||||
|
// {
|
||||||
|
// parse_reply(${msg.options}, ${msg.type});
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// connection()->bro_analyzer()->ProtocolViolation(fmt("unknown DHCP message type option for BOOTREPLY (%d)",
|
||||||
|
// ${msg.type}));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// break;
|
||||||
|
//
|
||||||
|
// default:
|
||||||
|
// // Removing this because I've seen some packets with weird values
|
||||||
|
// // but they still parse fine.
|
||||||
|
// //connection()->bro_analyzer()->ProtocolViolation(fmt("unknown DHCP message op code (%d). Known codes: 1=BOOTREQUEST, 2=BOOTREPLY",
|
||||||
|
// // ${msg.op}));
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// A single message reaching this point is enough to confirm the protocol
|
||||||
|
// because it's not uncommon to see a single DHCP message
|
||||||
|
// on a "connection".
|
||||||
|
// The binpac analyzer would have thrown an error before this point
|
||||||
|
// if there was a problem too (and subsequently called ProtocolViolation).
|
||||||
connection()->bro_analyzer()->ProtocolConfirmation();
|
connection()->bro_analyzer()->ProtocolConfirmation();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
%}
|
%}
|
||||||
};
|
};
|
||||||
|
@ -348,3 +230,8 @@ flow DHCP_Flow(is_orig: bool) {
|
||||||
refine typeattr DHCP_Message += &let {
|
refine typeattr DHCP_Message += &let {
|
||||||
proc_dhcp_message = $context.flow.process_dhcp_message(this);
|
proc_dhcp_message = $context.flow.process_dhcp_message(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
refine typeattr Option += &let {
|
||||||
|
proc_create_options = $context.flow.create_options();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
327
src/analyzer/protocol/dhcp/dhcp-options.pac
Normal file
327
src/analyzer/protocol/dhcp/dhcp-options.pac
Normal file
|
@ -0,0 +1,327 @@
|
||||||
|
|
||||||
|
##############################
|
||||||
|
# SUBNET OPTION
|
||||||
|
##############################
|
||||||
|
let SUBNET_OPTION = 1;
|
||||||
|
|
||||||
|
# Parse the option
|
||||||
|
refine casetype OptionValue += {
|
||||||
|
SUBNET_OPTION -> mask : uint32;
|
||||||
|
};
|
||||||
|
|
||||||
|
refine flow DHCP_Flow += {
|
||||||
|
function process_subnet_option(v: OptionValue): bool
|
||||||
|
%{
|
||||||
|
${context.flow}->options->Assign(0, new AddrVal(htonl(${v.mask})));
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
};
|
||||||
|
|
||||||
|
refine typeattr Option += &let {
|
||||||
|
proc_subnet_option = $context.flow.process_subnet_option(info) &if(code==SUBNET_OPTION);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
##############################
|
||||||
|
# HOST NAME OPTION
|
||||||
|
##############################
|
||||||
|
let HOST_NAME_OPTION = 12;
|
||||||
|
|
||||||
|
# Parse the option
|
||||||
|
refine casetype OptionValue += {
|
||||||
|
HOST_NAME_OPTION -> host_name : bytestring &length=length;
|
||||||
|
};
|
||||||
|
|
||||||
|
refine flow DHCP_Flow += {
|
||||||
|
function process_host_name_option(v: OptionValue): bool
|
||||||
|
%{
|
||||||
|
${context.flow}->options->Assign(1, new StringVal(${v.host_name}.length(), (const char*) ${v.host_name}.begin()));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
};
|
||||||
|
|
||||||
|
refine typeattr Option += &let {
|
||||||
|
proc_host_name_option = $context.flow.process_host_name_option(info) &if(code==HOST_NAME_OPTION);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
##############################
|
||||||
|
# REQ IP OPTION
|
||||||
|
##############################
|
||||||
|
let REQ_IP_OPTION = 50;
|
||||||
|
|
||||||
|
# Parse the option
|
||||||
|
refine casetype OptionValue += {
|
||||||
|
REQ_IP_OPTION -> req_addr : uint32;
|
||||||
|
};
|
||||||
|
|
||||||
|
refine flow DHCP_Flow += {
|
||||||
|
function process_req_ip_option(v: OptionValue): bool
|
||||||
|
%{
|
||||||
|
${context.flow}->options->Assign(2, new AddrVal(htonl(${v.req_addr})));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
};
|
||||||
|
|
||||||
|
refine typeattr Option += &let {
|
||||||
|
proc_req_ip_option = $context.flow.process_req_ip_option(info) &if(code==REQ_IP_OPTION);
|
||||||
|
};
|
||||||
|
|
||||||
|
##############################
|
||||||
|
# ROUTER OPTION
|
||||||
|
##############################
|
||||||
|
let ROUTER_OPTION = 3;
|
||||||
|
|
||||||
|
# Parse the option
|
||||||
|
refine casetype OptionValue += {
|
||||||
|
ROUTER_OPTION -> router_list : uint32[length/4];
|
||||||
|
};
|
||||||
|
|
||||||
|
refine flow DHCP_Flow += {
|
||||||
|
function process_router_option(v: OptionValue): bool
|
||||||
|
%{
|
||||||
|
TableVal* router_list = new TableVal(BifType::Table::DHCP::RouterList);
|
||||||
|
int num_routers = ${v.router_list}->size();
|
||||||
|
vector<uint32>* rlist = ${v.router_list};
|
||||||
|
|
||||||
|
for ( int i = 0; i < num_routers; ++i )
|
||||||
|
{
|
||||||
|
uint32 raddr = (*rlist)[i];
|
||||||
|
::uint32 tmp_addr;
|
||||||
|
tmp_addr = htonl(raddr);
|
||||||
|
// index starting from 1
|
||||||
|
Val* index = new Val(i + 1, TYPE_COUNT);
|
||||||
|
router_list->Assign(index, new AddrVal(tmp_addr));
|
||||||
|
Unref(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
${context.flow}->options->Assign(3, router_list);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
};
|
||||||
|
|
||||||
|
refine typeattr Option += &let {
|
||||||
|
proc_router_option = $context.flow.process_router_option(info) &if(code==ROUTER_OPTION);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
##############################
|
||||||
|
# LEASE_OPTION OPTION
|
||||||
|
##############################
|
||||||
|
let LEASE_OPTION = 51;
|
||||||
|
|
||||||
|
# Parse the option
|
||||||
|
refine casetype OptionValue += {
|
||||||
|
LEASE_OPTION -> lease : uint32;
|
||||||
|
};
|
||||||
|
|
||||||
|
refine flow DHCP_Flow += {
|
||||||
|
function process_lease_option(v: OptionValue): bool
|
||||||
|
%{
|
||||||
|
double lease = static_cast<double>(${v.lease});
|
||||||
|
${context.flow}->options->Assign(4, new Val(lease, TYPE_INTERVAL));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
};
|
||||||
|
|
||||||
|
refine typeattr Option += &let {
|
||||||
|
proc_lease_option = $context.flow.process_lease_option(info) &if(code==LEASE_OPTION);
|
||||||
|
};
|
||||||
|
|
||||||
|
##############################
|
||||||
|
# SERV_ID_OPTION OPTION
|
||||||
|
##############################
|
||||||
|
let SERV_ID_OPTION = 54;
|
||||||
|
|
||||||
|
# Parse the option
|
||||||
|
refine casetype OptionValue += {
|
||||||
|
SERV_ID_OPTION -> serv_addr : uint32;
|
||||||
|
};
|
||||||
|
|
||||||
|
refine flow DHCP_Flow += {
|
||||||
|
function process_serv_id_option(v: OptionValue): bool
|
||||||
|
%{
|
||||||
|
${context.flow}->options->Assign(5, new AddrVal(htonl(${v.serv_addr})));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
};
|
||||||
|
|
||||||
|
refine typeattr Option += &let {
|
||||||
|
proc_serv_id_option = $context.flow.process_serv_id_option(info) &if(code==SERV_ID_OPTION);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
##############################
|
||||||
|
# PAR_REQ_LIST OPTION
|
||||||
|
##############################
|
||||||
|
let PAR_REQ_LIST_OPTION = 55;
|
||||||
|
|
||||||
|
# Parse the option
|
||||||
|
refine casetype OptionValue += {
|
||||||
|
PAR_REQ_LIST_OPTION -> par_req_list : uint8[length];
|
||||||
|
};
|
||||||
|
|
||||||
|
refine flow DHCP_Flow += {
|
||||||
|
function process_par_req_list_option(v: OptionValue): bool
|
||||||
|
%{
|
||||||
|
TableVal* params_list = new TableVal(BifType::Table::DHCP::ParamsList);
|
||||||
|
int num_parms = ${v.par_req_list}->size();
|
||||||
|
vector<uint8>* plist = ${v.par_req_list};
|
||||||
|
|
||||||
|
for (int i=0; i < num_parms; ++i)
|
||||||
|
{
|
||||||
|
uint8 param = (*plist)[i];
|
||||||
|
Val* index = new Val(i+1, TYPE_COUNT);
|
||||||
|
params_list->Assign(index, new Val(param, TYPE_COUNT));
|
||||||
|
Unref(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
${context.flow}->options->Assign(6, params_list);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
};
|
||||||
|
|
||||||
|
refine typeattr Option += &let {
|
||||||
|
proc_par_req_list_option = $context.flow.process_par_req_list_option(info) &if(code==PAR_REQ_LIST_OPTION);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
##############################
|
||||||
|
# REN_TIME_OPTION OPTION
|
||||||
|
##############################
|
||||||
|
let REN_TIME_OPTION = 58;
|
||||||
|
|
||||||
|
# Parse the option
|
||||||
|
refine casetype OptionValue += {
|
||||||
|
REN_TIME_OPTION -> ren_time : uint32;
|
||||||
|
};
|
||||||
|
|
||||||
|
refine flow DHCP_Flow += {
|
||||||
|
function process_ren_time_option(v: OptionValue): bool
|
||||||
|
%{
|
||||||
|
double ren_time = static_cast<double>(${v.ren_time});
|
||||||
|
${context.flow}->options->Assign(7, new Val(ren_time, TYPE_INTERVAL));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
};
|
||||||
|
|
||||||
|
refine typeattr Option += &let {
|
||||||
|
proc_ren_time_option = $context.flow.process_ren_time_option(info) &if(code==REN_TIME_OPTION);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
##############################
|
||||||
|
# REB_TIME_OPTION OPTION
|
||||||
|
##############################
|
||||||
|
let REB_TIME_OPTION = 59;
|
||||||
|
|
||||||
|
# Parse the option
|
||||||
|
refine casetype OptionValue += {
|
||||||
|
REB_TIME_OPTION -> reb_time : uint32;
|
||||||
|
};
|
||||||
|
|
||||||
|
refine flow DHCP_Flow += {
|
||||||
|
function process_reb_time_option(v: OptionValue): bool
|
||||||
|
%{
|
||||||
|
double reb_time = static_cast<double>(${v.reb_time});
|
||||||
|
${context.flow}->options->Assign(8, new Val(reb_time, TYPE_INTERVAL));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
};
|
||||||
|
|
||||||
|
refine typeattr Option += &let {
|
||||||
|
proc_reb_time_option = $context.flow.process_reb_time_option(info) &if(code==REB_TIME_OPTION);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
##############################
|
||||||
|
# CLIENT_ID_OPTION OPTION
|
||||||
|
##############################
|
||||||
|
let CLIENT_ID_OPTION = 61;
|
||||||
|
|
||||||
|
type Client_Identifier(length: uint8) = record {
|
||||||
|
hwtype : uint8;
|
||||||
|
hwaddr : bytestring &length = length - 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Parse the option
|
||||||
|
refine casetype OptionValue += {
|
||||||
|
CLIENT_ID_OPTION -> client_id : Client_Identifier(length);
|
||||||
|
};
|
||||||
|
|
||||||
|
refine flow DHCP_Flow += {
|
||||||
|
function process_client_id_option(v: OptionValue): bool
|
||||||
|
%{
|
||||||
|
RecordVal* client_id = new RecordVal(BifType::Record::DHCP::ClientID);
|
||||||
|
client_id->Assign(0, new Val(${v.client_id.hwtype}, TYPE_COUNT));
|
||||||
|
client_id->Assign(1, new StringVal(fmt_mac(${v.client_id.hwaddr}.begin(), ${v.client_id.hwaddr}.length())));
|
||||||
|
|
||||||
|
${context.flow}->options->Assign(9, client_id);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
};
|
||||||
|
|
||||||
|
refine typeattr Option += &let {
|
||||||
|
proc_client_id_option = $context.flow.process_client_id_option(info) &if(code==CLIENT_ID_OPTION);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##############################
|
||||||
|
# RELAY_AGENT_INF OPTION
|
||||||
|
##############################
|
||||||
|
let RELAY_AGENT_INF_OPTION = 82;
|
||||||
|
|
||||||
|
type Relay_Agent_SubOption(tot_len: uint8) = record {
|
||||||
|
code : uint8;
|
||||||
|
length : uint8;
|
||||||
|
value : bytestring &length = length;
|
||||||
|
} &let {
|
||||||
|
sum_len: uint8 = $context.flow.get_dhcp_sumlen(length + 2);
|
||||||
|
last: bool = (sum_len == tot_len);
|
||||||
|
};
|
||||||
|
|
||||||
|
# Parse the option
|
||||||
|
refine casetype OptionValue += {
|
||||||
|
RELAY_AGENT_INF_OPTION -> relay_agent_inf : Relay_Agent_SubOption(length)[] &until($element.last);
|
||||||
|
};
|
||||||
|
|
||||||
|
refine flow DHCP_Flow += {
|
||||||
|
function process_relay_agent_inf_option(v: OptionValue): bool
|
||||||
|
%{
|
||||||
|
TableVal* relay_agent_sub_opt = new TableVal(BifType::Table::DHCP::SubOptList);
|
||||||
|
RecordVal* r = new RecordVal(BifType::Record::DHCP::SubOpt);
|
||||||
|
uint i = 1;
|
||||||
|
for ( auto ptrsubopt = ${v.relay_agent_inf}->begin();
|
||||||
|
ptrsubopt != ${v.relay_agent_inf}->end(); ++ptrsubopt )
|
||||||
|
{
|
||||||
|
r = new RecordVal(BifType::Record::DHCP::SubOpt);
|
||||||
|
r->Assign(0, new Val((*ptrsubopt)->code(), TYPE_COUNT));
|
||||||
|
r->Assign(1, bytestring_to_val((*ptrsubopt)->value()));
|
||||||
|
|
||||||
|
Val* index = new Val(i, TYPE_COUNT);
|
||||||
|
relay_agent_sub_opt->Assign(index, r);
|
||||||
|
Unref(index);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
${context.flow}->options->Assign(10, relay_agent_sub_opt);
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
};
|
||||||
|
|
||||||
|
refine typeattr Option += &let {
|
||||||
|
proc_relay_agent_info_option = $context.flow.process_relay_agent_inf_option(info) &if(code==RELAY_AGENT_INF_OPTION);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,24 +6,7 @@ enum OP_type {
|
||||||
BOOTREPLY = 2
|
BOOTREPLY = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
# Refer to RFC 1533 for option types.
|
let MSG_TYPE_OPTION = 53;
|
||||||
# The option types are by no means complete.
|
|
||||||
# Anyone can add a new option type in RFC 1533 to be parsed here.
|
|
||||||
enum OPTION_type {
|
|
||||||
SUBNET_OPTION = 1,
|
|
||||||
ROUTER_OPTION = 3,
|
|
||||||
HOST_NAME_OPTION = 12,
|
|
||||||
REQ_IP_OPTION = 50,
|
|
||||||
LEASE_OPTION = 51,
|
|
||||||
MSG_TYPE_OPTION = 53,
|
|
||||||
SERV_ID_OPTION = 54, # Server address, actually :)
|
|
||||||
PAR_REQ_LIST = 55, # Parameters Request List - NEW
|
|
||||||
REN_TIME_OPTION = 58, # Renewal time - NEW
|
|
||||||
REB_TIME_OPTION = 59, # Rebinding time - NEW
|
|
||||||
CLIENT_ID_OPTION = 61, # Client Identifier - NEW
|
|
||||||
RELAY_AGENT_INF = 82, # Relay Agent Information - NEW
|
|
||||||
END_OPTION = 255
|
|
||||||
};
|
|
||||||
|
|
||||||
enum DHCP_message_type {
|
enum DHCP_message_type {
|
||||||
DHCPDISCOVER = 1,
|
DHCPDISCOVER = 1,
|
||||||
|
@ -41,74 +24,82 @@ enum DHCP_message_type {
|
||||||
DHCPLEASEACTIVE = 13 # RFC 4388
|
DHCPLEASEACTIVE = 13 # RFC 4388
|
||||||
};
|
};
|
||||||
|
|
||||||
type Relay_Agent_SubOption(tot_len: uint8) = record {
|
type OptionValue(code: uint8, length: uint8) = case code of {
|
||||||
code : uint8;
|
# This is extended in dhcp-options.pac
|
||||||
length : uint8;
|
MSG_TYPE_OPTION -> msg_type : uint8;
|
||||||
value : bytestring &length = length;
|
default -> other : bytestring &length = length;
|
||||||
} &let {
|
|
||||||
sum_len: uint8 = $context.flow.get_dhcp_sumlen(length + 2);
|
|
||||||
last: bool = (sum_len == tot_len);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
type Client_Identifier(length: uint8) = record {
|
type Option = record {
|
||||||
hwtype : uint8;
|
code : uint8;
|
||||||
hwaddr : bytestring &length = length -1;
|
length : uint8;
|
||||||
};
|
data : case code of {
|
||||||
|
0, 255 -> none : empty;
|
||||||
enum DHCP_hardware_type
|
default -> info : OptionValue(code, length);
|
||||||
{
|
|
||||||
ETHERNET = 1,
|
|
||||||
EXPERIMENTAL_ETHERNET = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
type Option_Info(code: uint8) = record {
|
|
||||||
length : uint8;
|
|
||||||
value : case code of {
|
|
||||||
SUBNET_OPTION -> mask : uint32;
|
|
||||||
ROUTER_OPTION -> router_list : uint32[length/4];
|
|
||||||
REQ_IP_OPTION -> req_addr : uint32;
|
|
||||||
LEASE_OPTION -> lease : uint32;
|
|
||||||
MSG_TYPE_OPTION -> msg_type : uint8;
|
|
||||||
SERV_ID_OPTION -> serv_addr : uint32;
|
|
||||||
HOST_NAME_OPTION -> host_name : bytestring &length = length;
|
|
||||||
PAR_REQ_LIST -> par_req_list : uint8[length];
|
|
||||||
REB_TIME_OPTION -> reb_time : uint32;
|
|
||||||
REN_TIME_OPTION -> ren_time : uint32;
|
|
||||||
CLIENT_ID_OPTION -> client_id : Client_Identifier(length);
|
|
||||||
RELAY_AGENT_INF -> relay_agent_inf : Relay_Agent_SubOption(length)[] &until($element.last);
|
|
||||||
default -> other : bytestring &length = length;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
type DHCP_Option = record {
|
|
||||||
code : uint8;
|
|
||||||
data : case code of {
|
|
||||||
0, 255 -> none : empty;
|
|
||||||
default -> info : Option_Info(code);
|
|
||||||
};
|
};
|
||||||
} &let {
|
} &let {
|
||||||
last: bool = (code == END_OPTION); # Mark the end of a list of options
|
last = (code == 255); # Mark the end of a list of options
|
||||||
};
|
};
|
||||||
|
|
||||||
type DHCP_Message = record {
|
type DHCP_Message(is_orig: bool) = record {
|
||||||
op : uint8;
|
op : uint8;
|
||||||
htype : uint8;
|
htype : uint8;
|
||||||
hlen : uint8;
|
hlen : uint8;
|
||||||
hops : uint8;
|
hops : uint8;
|
||||||
xid : uint32;
|
xid : uint32;
|
||||||
secs : uint16;
|
secs : uint16;
|
||||||
flags : uint16;
|
flags : uint16;
|
||||||
ciaddr : uint32;
|
ciaddr : uint32;
|
||||||
yiaddr : uint32;
|
yiaddr : uint32;
|
||||||
siaddr : uint32;
|
siaddr : uint32;
|
||||||
giaddr : uint32;
|
giaddr : uint32;
|
||||||
chaddr : bytestring &length = 16;
|
chaddr : bytestring &length = 16;
|
||||||
sname : bytestring &length = 64;
|
sname : bytestring &length = 64;
|
||||||
file : bytestring &length = 128;
|
file : bytestring &length = 128;
|
||||||
# Cookie belongs to options in RFC 2131, but we separate
|
# Cookie belongs to options in RFC 2131, but we separate
|
||||||
# them here for easy parsing.
|
# them here for easy parsing.
|
||||||
cookie : uint32;
|
cookie : uint32;
|
||||||
options : DHCP_Option[] &until($element.last);
|
options : Option[] &until($element.last);
|
||||||
} &let {
|
} &let {
|
||||||
type : uint8 = $context.flow.get_dhcp_msgtype(options);
|
type = $context.flow.get_dhcp_msgtype(options);
|
||||||
} &byteorder = bigendian;
|
} &byteorder = bigendian;
|
||||||
|
|
||||||
|
refine flow DHCP_Flow += {
|
||||||
|
%member{
|
||||||
|
uint8 sum_len;
|
||||||
|
%}
|
||||||
|
|
||||||
|
%init{
|
||||||
|
sum_len = 0;
|
||||||
|
%}
|
||||||
|
|
||||||
|
%cleanup{
|
||||||
|
sum_len = 0;
|
||||||
|
%}
|
||||||
|
|
||||||
|
function get_dhcp_sumlen(len: uint8): uint8
|
||||||
|
%{
|
||||||
|
sum_len = len + sum_len;
|
||||||
|
return sum_len;
|
||||||
|
%}
|
||||||
|
|
||||||
|
function get_dhcp_msgtype(options: Option[]): uint8
|
||||||
|
%{
|
||||||
|
uint8 type = 0;
|
||||||
|
for ( auto ptr = options->begin();
|
||||||
|
ptr != options->end() && ! (*ptr)->last(); ++ptr )
|
||||||
|
{
|
||||||
|
if ( (*ptr)->code() == MSG_TYPE_OPTION )
|
||||||
|
{
|
||||||
|
type = (*ptr)->info()->msg_type();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( type == 0 )
|
||||||
|
connection()->bro_analyzer()->ProtocolViolation("no DHCP message type option");
|
||||||
|
|
||||||
|
return type;
|
||||||
|
%}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
@ -11,5 +11,15 @@ analyzer DHCP withcontext {
|
||||||
flow: DHCP_Flow;
|
flow: DHCP_Flow;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
connection DHCP_Conn(bro_analyzer: BroAnalyzer) {
|
||||||
|
upflow = DHCP_Flow(true);
|
||||||
|
downflow = DHCP_Flow(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
flow DHCP_Flow(is_orig: bool) {
|
||||||
|
datagram = DHCP_Message(is_orig) withcontext(connection, this);
|
||||||
|
};
|
||||||
|
|
||||||
%include dhcp-protocol.pac
|
%include dhcp-protocol.pac
|
||||||
%include dhcp-analyzer.pac
|
%include dhcp-analyzer.pac
|
||||||
|
%include dhcp-options.pac
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
|
||||||
|
event dhcp_message%(c: connection, is_orig: bool, msg: DHCP::Msg, options: DHCP::Options%);
|
||||||
|
|
||||||
## Generated for DHCP messages of type *DHCPDISCOVER* (client broadcast to locate
|
## Generated for DHCP messages of type *DHCPDISCOVER* (client broadcast to locate
|
||||||
## available servers).
|
## available servers).
|
||||||
##
|
##
|
||||||
|
@ -20,7 +23,7 @@
|
||||||
## protocol). It treats broadcast addresses just like any other and
|
## protocol). It treats broadcast addresses just like any other and
|
||||||
## associates packets into transport-level flows in the same way as usual.
|
## associates packets into transport-level flows in the same way as usual.
|
||||||
##
|
##
|
||||||
event dhcp_discover%(c: connection, msg: DHCP::dhcp_msg, req_addr: addr, host_name: string, client_id: DHCP::dhcp_client_id, req_params: DHCP::dhcp_params_list%);
|
event dhcp_discover%(c: connection, msg: DHCP::Msg, req_addr: addr, host_name: string, client_id: DHCP::ClientID, req_params: DHCP::ParamsList%);
|
||||||
|
|
||||||
## Generated for DHCP messages of type *DHCPOFFER* (server to client in response
|
## Generated for DHCP messages of type *DHCPOFFER* (server to client in response
|
||||||
## to DHCPDISCOVER with offer of configuration parameters).
|
## to DHCPDISCOVER with offer of configuration parameters).
|
||||||
|
@ -47,7 +50,7 @@ event dhcp_discover%(c: connection, msg: DHCP::dhcp_msg, req_addr: addr, host_na
|
||||||
## protocol). It treats broadcast addresses just like any other and
|
## protocol). It treats broadcast addresses just like any other and
|
||||||
## associates packets into transport-level flows in the same way as usual.
|
## associates packets into transport-level flows in the same way as usual.
|
||||||
##
|
##
|
||||||
event dhcp_offer%(c: connection, msg: DHCP::dhcp_msg, mask: addr, router: DHCP::dhcp_router_list, lease: interval, serv_addr: addr, host_name: string%);
|
event dhcp_offer%(c: connection, msg: DHCP::Msg, mask: addr, router: DHCP::RouterList, lease: interval, serv_addr: addr, host_name: string%);
|
||||||
|
|
||||||
## Generated for DHCP messages of type *DHCPREQUEST* (Client message to servers either
|
## Generated for DHCP messages of type *DHCPREQUEST* (Client message to servers either
|
||||||
## (a) requesting offered parameters from one server and implicitly declining offers
|
## (a) requesting offered parameters from one server and implicitly declining offers
|
||||||
|
@ -75,7 +78,7 @@ event dhcp_offer%(c: connection, msg: DHCP::dhcp_msg, mask: addr, router: DHCP::
|
||||||
## protocol). It treats broadcast addresses just like any other and
|
## protocol). It treats broadcast addresses just like any other and
|
||||||
## associates packets into transport-level flows in the same way as usual.
|
## associates packets into transport-level flows in the same way as usual.
|
||||||
##
|
##
|
||||||
event dhcp_request%(c: connection, msg: DHCP::dhcp_msg, req_addr: addr, serv_addr: addr, host_name: string, client_id: DHCP::dhcp_client_id, req_params: DHCP::dhcp_params_list%);
|
event dhcp_request%(c: connection, msg: DHCP::Msg, req_addr: addr, serv_addr: addr, host_name: string, client_id: DHCP::ClientID, req_params: DHCP::ParamsList%);
|
||||||
|
|
||||||
## Generated for DHCP messages of type *DHCPDECLINE* (Client to server indicating
|
## Generated for DHCP messages of type *DHCPDECLINE* (Client to server indicating
|
||||||
## network address is already in use).
|
## network address is already in use).
|
||||||
|
@ -93,7 +96,7 @@ event dhcp_request%(c: connection, msg: DHCP::dhcp_msg, req_addr: addr, serv_add
|
||||||
## protocol). It treats broadcast addresses just like any other and
|
## protocol). It treats broadcast addresses just like any other and
|
||||||
## associates packets into transport-level flows in the same way as usual.
|
## associates packets into transport-level flows in the same way as usual.
|
||||||
##
|
##
|
||||||
event dhcp_decline%(c: connection, msg: DHCP::dhcp_msg, host_name: string%);
|
event dhcp_decline%(c: connection, msg: DHCP::Msg, host_name: string%);
|
||||||
|
|
||||||
## Generated for DHCP messages of type *DHCPACK* (Server to client with configuration
|
## Generated for DHCP messages of type *DHCPACK* (Server to client with configuration
|
||||||
## parameters, including committed network address).
|
## parameters, including committed network address).
|
||||||
|
@ -127,7 +130,7 @@ event dhcp_decline%(c: connection, msg: DHCP::dhcp_msg, host_name: string%);
|
||||||
## .. bro:see:: dhcp_discover dhcp_offer dhcp_request dhcp_decline dhcp_nak
|
## .. bro:see:: dhcp_discover dhcp_offer dhcp_request dhcp_decline dhcp_nak
|
||||||
## dhcp_release dhcp_inform
|
## dhcp_release dhcp_inform
|
||||||
##
|
##
|
||||||
event dhcp_ack%(c: connection, msg: DHCP::dhcp_msg, mask: addr, router: DHCP::dhcp_router_list, lease: interval, serv_addr: addr, host_name: string, reb_time: count, ren_time: count, sub_opt: DHCP::dhcp_sub_opt_list%);
|
event dhcp_ack%(c: connection, msg: DHCP::Msg, mask: addr, router: DHCP::RouterList, lease: interval, serv_addr: addr, host_name: string%);
|
||||||
|
|
||||||
## Generated for DHCP messages of type *DHCPNAK* (Server to client indicating client's
|
## Generated for DHCP messages of type *DHCPNAK* (Server to client indicating client's
|
||||||
## notion of network address is incorrect (e.g., client has moved to new subnet) or
|
## notion of network address is incorrect (e.g., client has moved to new subnet) or
|
||||||
|
@ -146,7 +149,7 @@ event dhcp_ack%(c: connection, msg: DHCP::dhcp_msg, mask: addr, router: DHCP::dh
|
||||||
## protocol). It treats broadcast addresses just like any other and
|
## protocol). It treats broadcast addresses just like any other and
|
||||||
## associates packets into transport-level flows in the same way as usual.
|
## associates packets into transport-level flows in the same way as usual.
|
||||||
##
|
##
|
||||||
event dhcp_nak%(c: connection, msg: DHCP::dhcp_msg, host_name: string%);
|
event dhcp_nak%(c: connection, msg: DHCP::Msg, host_name: string%);
|
||||||
|
|
||||||
## Generated for DHCP messages of type *DHCPRELEASE* (Client to server relinquishing
|
## Generated for DHCP messages of type *DHCPRELEASE* (Client to server relinquishing
|
||||||
## network address and cancelling remaining lease).
|
## network address and cancelling remaining lease).
|
||||||
|
@ -160,7 +163,7 @@ event dhcp_nak%(c: connection, msg: DHCP::dhcp_msg, host_name: string%);
|
||||||
## .. bro:see:: dhcp_discover dhcp_offer dhcp_request dhcp_decline dhcp_ack dhcp_nak
|
## .. bro:see:: dhcp_discover dhcp_offer dhcp_request dhcp_decline dhcp_ack dhcp_nak
|
||||||
## dhcp_inform
|
## dhcp_inform
|
||||||
##
|
##
|
||||||
event dhcp_release%(c: connection, msg: DHCP::dhcp_msg, host_name: string%);
|
event dhcp_release%(c: connection, msg: DHCP::Msg, host_name: string%);
|
||||||
|
|
||||||
## Generated for DHCP messages of type *DHCPINFORM* (Client to server, asking only for
|
## Generated for DHCP messages of type *DHCPINFORM* (Client to server, asking only for
|
||||||
## local configuration parameters; client already has externally configured network
|
## local configuration parameters; client already has externally configured network
|
||||||
|
@ -181,5 +184,5 @@ event dhcp_release%(c: connection, msg: DHCP::dhcp_msg, host_name: string%);
|
||||||
## protocol). It treats broadcast addresses just like any other and
|
## protocol). It treats broadcast addresses just like any other and
|
||||||
## associates packets into transport-level flows in the same way as usual.
|
## associates packets into transport-level flows in the same way as usual.
|
||||||
##
|
##
|
||||||
event dhcp_inform%(c: connection, msg: DHCP::dhcp_msg, host_name: string, req_params: DHCP::dhcp_params_list%);
|
event dhcp_inform%(c: connection, msg: DHCP::Msg, host_name: string%);
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
module DHCP;
|
module DHCP;
|
||||||
|
|
||||||
type dhcp_msg: record;
|
type Msg: record;
|
||||||
type dhcp_router_list: table;
|
type RouterList: table;
|
||||||
type dhcp_params_list: table;
|
type ParamsList: table;
|
||||||
type dhcp_sub_opt_list: table;
|
type SubOptList: table;
|
||||||
type dhcp_sub_opt: record;
|
type SubOpt: record;
|
||||||
type dhcp_client_id: record;
|
type ClientID: record;
|
||||||
|
type Options: record;
|
||||||
module GLOBAL;
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue