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:
Seth Hall 2018-02-02 10:14:15 -05:00
parent ba49ab8201
commit c2f35920fd
14 changed files with 728 additions and 498 deletions

View file

@ -7,14 +7,24 @@ export {
## Types of DHCP messages. See :rfc:`1533`.
const message_types = {
[1] = "DHCP_DISCOVER",
[2] = "DHCP_OFFER",
[3] = "DHCP_REQUEST",
[4] = "DHCP_DECLINE",
[5] = "DHCP_ACK",
[6] = "DHCP_NAK",
[7] = "DHCP_RELEASE",
[8] = "DHCP_INFORM",
[1] = "DHCP_DISCOVER",
[2] = "DHCP_OFFER",
[3] = "DHCP_REQUEST",
[4] = "DHCP_DECLINE",
[5] = "DHCP_ACK",
[6] = "DHCP_NAK",
[7] = "DHCP_RELEASE",
[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); };
}

View file

@ -59,91 +59,60 @@ redef record connection += {
const ports = { 67/udp, 68/udp };
redef likely_server_ports += { 67/udp };
global info: Info;
event bro_init() &priority=5
{
Log::create_stream(DHCP::LOG, [$columns=Info, $ev=log_dhcp, $path="dhcp"]);
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;
info$ts = network_time();
info$id = c$id;
info$uid = c$uid;
info$lease_time = lease;
info$trans_id = msg$xid;
info$msg_type = message_types[msg$m_type];
if ( msg$m_type == 5 ) # DHCP_ACK
{
local info = Info($ts = network_time(),
$id = c$id,
$uid = c$uid,
$trans_id = msg$xid);
info$server_id = serv_addr;
info$host_name = host_name;
if ( msg$h_addr != "" )
info$mac = msg$h_addr;
if ( msg$h_addr != "" )
info$mac = msg$h_addr;
if ( reverse_ip(msg$yiaddr) != 0.0.0.0 )
info$assigned_ip = reverse_ip(msg$yiaddr);
else
info$assigned_ip = c$id$orig_h;
if ( reverse_ip(msg$yiaddr) != 0.0.0.0 )
info$assigned_ip = reverse_ip(msg$yiaddr);
else
info$assigned_ip = c$id$orig_h;
if ( options?$lease )
info$lease_time = options$lease;
for (param in sub_opt)
{
#if ( sub_opt[param]$code == 1 )
#{
#print fmt("Relay Agent Information:");
#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 ( options?$sub_opt )
{
for ( param in options$sub_opt )
{
local sub_opt = options$sub_opt[param];
if ( sub_opt[param]$code == 6 )
info$subscriber_id = (sub_opt[param]$value);
#if ( sub_opt$code == 1 )
# {
# 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_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
{
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);
}