Rework to the DHCP analyzer.

Highlights:
 - Reduced all DHCP events into a single dhcp_message event. (removed legacy events since they weren't widely used anyway)
 - Support many more DHCP options.
 - DHCP log is completely reworked and now represents DHCP sessions
   based on the transaction ID (and works on clusters).
 - Removed the known-devices-and-hostnames script since it's generally
   less relevant now with the updated log.
This commit is contained in:
Seth Hall 2018-03-01 08:36:32 -08:00
parent c2f35920fd
commit e76b56ce53
28 changed files with 1234 additions and 732 deletions

View file

@ -3061,10 +3061,11 @@ module GLOBAL;
module DHCP; module DHCP;
export { export {
## A list of router addresses offered by a DHCP server. ## A list of addresses offered by a DHCP server. Could be routers,
## DNS servers, or other.
## ##
## .. bro:see:: dhcp_ack dhcp_offer ## .. bro:see:: dhcp_ack dhcp_offer
type DHCP::RouterList: table[count] of addr; type DHCP::Addrs: vector 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
@ -3073,20 +3074,17 @@ export {
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.
h_addr: string; ##< Hardware address of the client. ## Number of seconds since client began address acquisition
## or renewal process
secs: interval;
flags: count;
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.
}; siaddr: addr; ##< IP address of the server.
giaddr: addr; ##< IP address of the relaying gateway.
## DHCP Parameter Request list (Option 55) chaddr: string; ##< Client hardware address.
## .. bro:see:: dhcp_request dhcp_discover sname: string &default=""; ##< Server host name.
type DHCP::ParamsList: table[count] of count; file_n: string &default=""; ##< Boot file name.
## DHCP Relay Agent Information Option (Option 82)
## .. bro:see:: dhcp_ack
type DHCP::SubOpt: record {
code: count;
value: string;
}; };
## DHCP Client Identifier (Option 61) ## DHCP Client Identifier (Option 61)
@ -3096,36 +3094,113 @@ export {
hwaddr: string; hwaddr: string;
}; };
type DHCP::SubOptList: table[count] of DHCP::SubOpt; ## DHCP Client FQDN Option information (Option 81)
type DHCP::ClientFQDN: record {
## An unparsed bitfield of flags (refer to RFC 4702).
flags: count;
## This field is deprecated in the standard.
rcode1: count;
## This field is deprecated in the standard.
rcode2: count;
## The Domain Name part of the option carries all or part of the FQDN of
## a DHCP client.
domain_name: string;
};
## DHCP Relay Agent Information Option (Option 82)
## .. bro:see:: dhcp_ack
type DHCP::SubOpt: record {
code: count;
value: string;
};
type DHCP::SubOpts: vector of DHCP::SubOpt;
type DHCP::Options: record { type DHCP::Options: record {
## The ordered list of DHCP all DHCP options numbers.
options: index_vec &optional;
## Subnet Mask Value (option 1)
subnet_mask: addr &optional; subnet_mask: addr &optional;
## Router addresses (option 3)
routers: DHCP::Addrs &optional;
## DNS Server addresses (option 6)
dns_servers: DHCP::Addrs &optional;
## The Hostname of the client (option 12)
host_name: string &optional; host_name: string &optional;
req_addr: addr &optional; ## The DNS domain name of the client (option 15)
domain_name: string &optional;
router_list: DHCP::RouterList &optional; ## Enable/Disable IP Forwarding (option 19)
forwarding: bool &optional;
## Broadcast Address (option 28)
broadcast: addr &optional;
## Vendor specific data. This can frequently
## be unparsed binary data. (option 43)
vendor: string &optional;
## NETBIOS name server list (option 44)
nbns: DHCP::Addrs &optional;
## Address requested by the client (option 50)
addr_request: addr &optional;
## Lease time offered by the server. (option 51)
lease: interval &optional; lease: interval &optional;
## Server address to allow clients to distinguish
## between lease offers. (option 54)
serv_addr: addr &optional; serv_addr: addr &optional;
## DHCP Parameter Request list (Option 55) ## DHCP Parameter Request list (option 55)
param_list: DHCP::ParamsList &optional; param_list: index_vec &optional;
ren_time: interval &optional; ## Textual error message (option 56)
message: string &optional;
reb_time: interval &optional; ## Maximum Message Size (option 57)
max_msg_size: count &optional;
## This option specifies the time interval from address
## assignment until the client transitions to the
## RENEWING state. (option 58)
renewal_time: interval &optional;
## This option specifies the time interval from address
## assignment until the client transitions to the
## REBINDING state. (option 59)
rebinding_time: interval &optional;
## This option is used by DHCP clients to optionally
## identify the vendor type and configuration of a DHCP
## client. (option 60)
vendor_class: string &optional;
## DHCP Client Identifier (Option 61) ## DHCP Client Identifier (Option 61)
client_id: DHCP::ClientID &optional; client_id: DHCP::ClientID &optional;
## User Class opaque value (Option 77)
user_class: string &optional;
## DHCP Client FQDN (Option 81)
client_fqdn: DHCP::ClientFQDN &optional;
## DHCP Relay Agent Information Option (Option 82) ## DHCP Relay Agent Information Option (Option 82)
sub_opt: DHCP::SubOptList &optional; sub_opt: DHCP::SubOpts &optional;
## Auto Config option to let host know if it's allowed to
## auto assign an IP address. (Option 116)
auto_config: bool &optional;
## URL to find a proxy.pac for auto proxy config (Option 252)
auto_proxy_config: string &optional;
}; };
} }
module GLOBAL; module GLOBAL;

View file

@ -4,27 +4,186 @@
module DHCP; module DHCP;
export { export {
## Types of DHCP messages. See :rfc:`1533`, :rfc:`3203`,
## Types of DHCP messages. See :rfc:`1533`. ## :rfc:`4388`, :rfc:`6926`, and :rfc:`7724`.
const message_types = { const message_types = {
[1] = "DHCP_DISCOVER", [1] = "DISCOVER",
[2] = "DHCP_OFFER", [2] = "OFFER",
[3] = "DHCP_REQUEST", [3] = "REQUEST",
[4] = "DHCP_DECLINE", [4] = "DECLINE",
[5] = "DHCP_ACK", [5] = "ACK",
[6] = "DHCP_NAK", [6] = "NAK",
[7] = "DHCP_RELEASE", [7] = "RELEASE",
[8] = "DHCP_INFORM", [8] = "INFORM",
[9] = "DHCP_FORCERENEW", [9] = "FORCERENEW", # RFC3203
[10] = "DHCP_LEASEQUERY", [10] = "LEASEQUERY", # RFC4388
[11] = "DHCP_LEASEUNASSIGNED", [11] = "LEASEUNASSIGNED", # RFC4388
[12] = "DHCP_DHCPLEASEUNKNOWN", [12] = "LEASEUNKNOWN", # RFC4388
[13] = "DHCP_LEASEACTIVE", [13] = "LEASEACTIVE", # RFC4388
[14] = "DHCP_BULKLEASEQUERY", [14] = "BULKLEASEQUERY", # RFC6926
[15] = "DHCP_LEASEQUERYDONE", [15] = "LEASEQUERYDONE", # RFC6926
[16] = "DHCP_ACTIVELEASEQUERY", [16] = "ACTIVELEASEQUERY", # RFC7724
[17] = "DHCP_LEASEQUERYSTATUS", [17] = "LEASEQUERYSTATUS", # RFC7724
[18] = "DHCP_TLS", [18] = "TLS", # RFC7724
} &default = function(n: count): string { return fmt("unknown-message-type-%d", n); }; } &default = function(n: count): string { return fmt("unknown-message-type-%d", n); };
## Option types mapped to their names.
const option_types: table[int] of string = {
[0] = "Pad",
[1] = "Subnet Mask",
[2] = "Time Offset",
[3] = "Router",
[4] = "Time Server",
[5] = "Name Server",
[6] = "Domain Server",
[7] = "Log Server",
[8] = "Quotes Server",
[9] = "LPR Server",
[10] = "Impress Server",
[11] = "RLP Server",
[12] = "Hostname",
[13] = "Boot File Size",
[14] = "Merit Dump File",
[15] = "Domain Name",
[16] = "Swap Server",
[17] = "Root Path",
[18] = "Extension File",
[19] = "Forward On/Off",
[20] = "SrcRte On/Off",
[21] = "Policy Filter",
[22] = "Max DG Assembly",
[23] = "Default IP TTL",
[24] = "MTU Timeout",
[25] = "MTU Plateau",
[26] = "MTU Interface",
[27] = "MTU Subnet",
[28] = "Broadcast Address",
[29] = "Mask Discovery",
[30] = "Mask Supplier",
[31] = "Router Discovery",
[32] = "Router Request",
[33] = "Static Route",
[34] = "Trailers",
[35] = "ARP Timeout",
[36] = "Ethernet",
[37] = "Default TCP TTL",
[38] = "Keepalive Time",
[39] = "Keepalive Data",
[40] = "NIS Domain",
[41] = "NIS Servers",
[42] = "NTP Servers",
[43] = "Vendor Specific",
[44] = "NETBIOS Name Srv",
[45] = "NETBIOS Dist Srv",
[46] = "NETBIOS Node Type",
[47] = "NETBIOS Scope",
[48] = "X Window Font",
[49] = "X Window Manager",
[50] = "Address Request",
[51] = "Address Time",
[52] = "Overload",
[53] = "DHCP Msg Type",
[54] = "DHCP Server Id",
[55] = "Parameter List",
[56] = "DHCP Message",
[57] = "DHCP Max Msg Size",
[58] = "Renewal Time",
[59] = "Rebinding Time",
[60] = "Class Id",
[61] = "Client Id",
[62] = "NetWare/IP Domain",
[63] = "NetWare/IP Option",
[64] = "NIS-Domain-Name",
[65] = "NIS-Server-Addr",
[66] = "Server-Name",
[67] = "Bootfile-Name",
[68] = "Home-Agent-Addrs",
[69] = "SMTP-Server",
[70] = "POP3-Server",
[71] = "NNTP-Server",
[72] = "WWW-Server",
[73] = "Finger-Server",
[74] = "IRC-Server",
[75] = "StreetTalk-Server",
[76] = "STDA-Server",
[77] = "User-Class",
[78] = "Directory Agent",
[79] = "Service Scope",
[80] = "Rapid Commit",
[81] = "Client FQDN",
[82] = "Relay Agent Information",
[83] = "iSNS",
[85] = "NDS Servers",
[86] = "NDS Tree Name",
[87] = "NDS Context",
[88] = "BCMCS Controller Domain Name list",
[89] = "BCMCS Controller IPv4 address option",
[90] = "Authentication",
[91] = "client-last-transaction-time option",
[92] = "associated-ip option",
[93] = "Client System",
[94] = "Client NDI",
[95] = "LDAP",
[97] = "UUID/GUID",
[98] = "User-Auth",
[99] = "GEOCONF_CIVIC",
[100] = "PCode",
[101] = "TCode",
[112] = "Netinfo Address",
[113] = "Netinfo Tag",
[114] = "URL",
[116] = "Auto-Config",
[117] = "Name Service Search",
[118] = "Subnet Selection Option",
[119] = "Domain Search",
[120] = "SIP Servers DHCP Option",
[121] = "Classless Static Route Option",
[122] = "CCC",
[123] = "GeoConf Option",
[124] = "V-I Vendor Class",
[125] = "V-I Vendor-Specific Information",
[128] = "PXE - undefined (vendor specific)",
[129] = "PXE - undefined (vendor specific)",
[130] = "PXE - undefined (vendor specific)",
[131] = "PXE - undefined (vendor specific)",
[132] = "IEEE 802.1Q VLAN ID",
[133] = "IEEE 802.1D/p Layer 2 Priority",
[134] = "Diffserv Code Point (DSCP) for VoIP signalling and media streams",
[135] = "HTTP Proxy for phone-specific applications",
[136] = "OPTION_PANA_AGENT",
[137] = "OPTION_V4_LOST",
[138] = "OPTION_CAPWAP_AC_V4",
[139] = "OPTION-IPv4_Address-MoS",
[140] = "OPTION-IPv4_FQDN-MoS",
[141] = "SIP UA Configuration Service Domains",
[142] = "OPTION-IPv4_Address-ANDSF",
[144] = "GeoLoc",
[145] = "FORCERENEW_NONCE_CAPABLE",
[146] = "RDNSS Selection",
[150] = "TFTP server address",
[151] = "status-code",
[152] = "base-time",
[153] = "start-time-of-state",
[154] = "query-start-time",
[155] = "query-end-time",
[156] = "dhcp-state",
[157] = "data-source",
[158] = "OPTION_V4_PCP_SERVER",
[159] = "OPTION_V4_PORTPARAMS",
[160] = "DHCP Captive-Portal",
[161] = "OPTION_MUD_URL_V4 (TEMPORARY - registered 2016-11-17)",
[175] = "Etherboot (Tentatively Assigned - 2005-06-23)",
[176] = "IP Telephone (Tentatively Assigned - 2005-06-23)",
[177] = "PacketCable and CableHome (replaced by 122)",
[208] = "PXELINUX Magic",
[209] = "Configuration File",
[210] = "Path Prefix",
[211] = "Reboot Time",
[212] = "OPTION_6RD",
[213] = "OPTION_V4_ACCESS_DOMAIN",
[220] = "Subnet Allocation Option",
[221] = "Virtual Subnet Selection (VSS) Option",
[252] = "auto-proxy-config",
[255] = "End",
} &default = function(n: int): string { return fmt("unknown-option-type-%d", n); };
} }

View file

@ -1,5 +1,5 @@
signature dhcp_cookie { signature dhcp_cookie {
ip-proto == udp ip-proto == udp
payload /^.*\x63\x82\x53\x63/ payload /^.{236}\x63\x82\x53\x63/
enable "dhcp" enable "dhcp"
} }

View file

@ -1,12 +1,11 @@
##! Analyzes DHCP traffic in order to log DHCP leases given to clients. ##! Analyze DHCP traffic and provide a log that is organized around
##! This script ignores large swaths of the protocol, since it is rather ##! the idea of a DHCP "conversation" defined by messaes exchanged within
##! noisy on most networks, and focuses on the end-result: assigned leases. ##! a relatively short period of time using the same transaction ID.
##! ##! The log will have information from clients and servers to give a more
##! If you'd like to track known DHCP devices and to log the hostname ##! complete picture of what happened.
##! supplied by the client, see
##! :doc:`/scripts/policy/protocols/dhcp/known-devices-and-hostnames.bro`.
@load ./utils.bro @load base/frameworks/cluster
@load ./consts
module DHCP; module DHCP;
@ -18,33 +17,80 @@ export {
## The earliest time at which a DHCP message over the ## The earliest time at which a DHCP message over the
## associated connection is observed. ## associated connection is observed.
ts: time &log; ts: time &log;
## A unique identifier of the connection over which DHCP is
## occurring. ## A series of unique identifiers of the connections over which
uid: string &log; ## DHCP is occurring. This behavior with multiple connections is
## The connection's 4-tuple of endpoint addresses/ports. ## unique to DHCP because of the way it uses broadcast packets
id: conn_id &log; ## on local networks.
uids: set[string] &log;
## IP address of the client. If a transaction
## is only a client sending INFORM messages then
## there is no lease information exchanged so this
## is helpful to know who sent the messages.
## Getting an address in this field does require
## that the client sources at least one DHCP message
## using a non-broadcast address.
client_addr: addr &log &optional;
## IP address of the server involved in actually
## handing out the lease. There could be other
## servers replying with OFFER messages which won't
## be represented here. Getting an address in this
## field also requires that the server handing out
## the lease also sources packets from a non-broadcast
## IP address.
server_addr: addr &log &optional;
## Client's hardware address. ## Client's hardware address.
mac: string &log &optional; mac: string &log &optional;
## Client's actual assigned IP address.
assigned_ip: addr &log &optional; ## Name given by client in Hostname option 12.
host_name: string &log &optional;
## FQDN given by client in Client FQDN option 81.
client_fqdn: string &log &optional;
## Domain given by the server in option 15.
domain: string &log &optional;
## IP address requested by the client.
requested_addr: addr &log &optional;
## IP address assigned by the server.
assigned_addr: addr &log &optional;
## IP address lease interval. ## IP address lease interval.
lease_time: interval &log &optional; lease_time: interval &log &optional;
## A random number chosen by the client for this transaction.
trans_id: count &log; ## Message typically accompanied with a DHCP_DECLINE
## the message type ## so the client can tell the server why it rejected
msg_type: string &log &optional; ## an address.
## client ID client_message: string &log &optional;
client_id: string &log &optional; ## Message typically accompanied with a DHCP_NAK to let
## the server ID ## the client know why it rejected the request.
server_id: addr &log &optional; server_message: string &log &optional;
## the host name
host_name: string &log &optional; ## The DHCP message types seen by this DHCP transaction
## the subscriber id (if present) msg_types: vector of string &log &default=string_vec();
subscriber_id: string &log &optional;
## the agent remote id (if present) ## Duration of the DHCP "session" representing the
agent_remote_id: string &log &optional; ## time from the first message to the last.
duration: interval &log &default=0secs;
}; };
## The maximum amount of time that a transation ID will be watched
## for to try and tie messages together into a single DHCP
## transaction narrative.
const DHCP::max_txid_watch_time = 30secs &redef;
## This event is used internally to distribute data around clusters
## since DHCP doesn't follow the normal "connection" model used by
## most protocols. It can also be handled to extend the DHCP log.
## bro:see::`DHCP::log_info`.
global DHCP::aggregate_msgs: event(ts: time, id: conn_id, uid: string, is_orig: bool, msg: DHCP::Msg, options: DHCP::Options);
## This is a global variable that is only to be used in the
## :bro::see::`DHCP::aggregate_msgs` event. It can be used to avoid
## looking up the info record for a transaction ID in every event handler
## for :bro:see::`DHCP::aggregate_msgs`.
global DHCP::log_info: Info;
## Event that can be handled to access the DHCP ## Event that can be handled to access the DHCP
## record as it is sent on to the logging framework. ## record as it is sent on to the logging framework.
global log_dhcp: event(rec: Info); global log_dhcp: event(rec: Info);
@ -55,8 +101,13 @@ redef record connection += {
dhcp: Info &optional; dhcp: Info &optional;
}; };
redef record Info += {
last_message_ts: time &optional;
};
# 67/udp is the server's port, 68/udp the client. # 67/udp is the server's port, 68/udp the client.
const ports = { 67/udp, 68/udp }; # 4011/udp seems to be some proxyDHCP thing.
const ports = { 67/udp, 68/udp, 4011/udp };
redef likely_server_ports += { 67/udp }; redef likely_server_ports += { 67/udp };
event bro_init() &priority=5 event bro_init() &priority=5
@ -65,54 +116,144 @@ event bro_init() &priority=5
Analyzer::register_for_ports(Analyzer::ANALYZER_DHCP, ports); Analyzer::register_for_ports(Analyzer::ANALYZER_DHCP, ports);
} }
event dhcp_message(c: connection, is_orig: bool, msg: DHCP::Msg, options: DHCP::Options) &priority=-5 # Setup the clusterized config that is needed to tie messages together on a cluster.
{ redef Cluster::worker2manager_events += /DHCP::aggregate_msgs/;
if ( msg$m_type == 5 ) # DHCP_ACK
{
local info = Info($ts = network_time(),
$id = c$id,
$uid = c$uid,
$trans_id = msg$xid);
if ( msg$h_addr != "" ) function join_data_expiration(t: table[count] of Info, idx: count): interval
info$mac = msg$h_addr; {
local info = t[idx];
if ( reverse_ip(msg$yiaddr) != 0.0.0.0 ) local now = network_time();
info$assigned_ip = reverse_ip(msg$yiaddr); # If a message hasn't been seen in the past 5 seconds or the
# total time watching has been more than the maximum time
# allowed by the configuration then log this data and expire it.
# Also, if Bro is shutting down.
if ( (now - info$last_message_ts) > 5sec ||
(now - info$ts) > max_txid_watch_time ||
bro_is_terminating() )
{
Log::write(LOG, info);
# Go ahead and expire the data now that the log
# entry has been written.
return 0secs;
}
else else
info$assigned_ip = c$id$orig_h; {
return 5secs;
}
}
# This is where the data is stored as it's centralized. All data for a log must
# arrive within the expiration interval if it's to be logged fully. On a cluster,
# this data is only maintained on the manager.
global join_data: table[count] of Info = table()
&create_expire=10secs &expire_func=join_data_expiration;
@if ( ! Cluster::is_enabled() || Cluster::local_node_type() == Cluster::MANAGER )
# We are handling this event at priority 1000 because we really want
# the DHCP::log_info global to be set correctly before a user might try
# to access it.
event DHCP::aggregate_msgs(ts: time, id: conn_id, uid: string, is_orig: bool, msg: DHCP::Msg, options: DHCP::Options) &priority=1000
{
if ( msg$xid !in join_data )
{
join_data[msg$xid] = Info($ts=ts,
$uids=set(uid));
}
log_info = join_data[msg$xid];
}
event DHCP::aggregate_msgs(ts: time, id: conn_id, uid: string, is_orig: bool, msg: DHCP::Msg, options: DHCP::Options) &priority=5
{
log_info$duration = ts - log_info$ts;
if ( uid !in log_info$uids )
add log_info$uids[uid];
log_info$msg_types[|log_info$msg_types|] = DHCP::message_types[msg$m_type];
# Let's watch for messages in any DHCP message type
# and split them out based on client and server.
if ( options?$message )
{
if ( is_orig )
log_info$client_message = options$message;
else
log_info$server_message = options$message;
}
# Update the last message time so that we can do some data
# expiration handling.
log_info$last_message_ts = ts;
if ( is_orig ) # client requests
{
# Assign the client addr in case this is a session
# of only INFORM messages (no lease handed out).
# This also works if a normal lease handout uses
# unicast.
if ( id$orig_h != 0.0.0.0 && id$orig_h != 255.255.255.255 )
log_info$client_addr = id$orig_h;
if ( options?$host_name )
log_info$host_name = options$host_name;
if ( options?$client_fqdn )
log_info$client_fqdn = options$client_fqdn$domain_name;
if ( options?$client_id &&
options$client_id$hwtype == 1 ) # ETHERNET
log_info$mac = options$client_id$hwaddr;
if ( options?$addr_request )
log_info$requested_addr = options$addr_request;
}
else # server reply messages
{
# Only log the address of the server if it handed out
# an IP address.
if ( msg$yiaddr != 0.0.0.0 &&
id$resp_h != 255.255.255.255 )
{
log_info$server_addr = id$resp_h;
}
# Only use the client hardware address from the server
# if we didn't already pick one up from the client.
if ( msg$chaddr != "" && !log_info?$mac )
log_info$mac = msg$chaddr;
if ( msg$yiaddr != 0.0.0.0 )
log_info$assigned_addr = msg$yiaddr;
# If no client address has been seen yet, let's use the assigned addr.
if ( ! log_info?$client_addr && log_info?$assigned_addr )
log_info$client_addr = log_info$assigned_addr;
if ( options?$domain_name )
log_info$domain = options$domain_name;
if ( options?$lease ) if ( options?$lease )
info$lease_time = options$lease; log_info$lease_time = options$lease;
if ( options?$sub_opt )
{
for ( param in options$sub_opt )
{
local sub_opt = options$sub_opt[param];
#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);
} }
} }
@endif
c$dhcp = info;
}
}
# Aggregate DHCP messages to the manager.
event dhcp_message(c: connection, is_orig: bool, msg: DHCP::Msg, options: DHCP::Options) &priority=-5 event dhcp_message(c: connection, is_orig: bool, msg: DHCP::Msg, options: DHCP::Options) &priority=-5
{ {
if ( msg$m_type == 5 ) # DHCP_ACK event DHCP::aggregate_msgs(network_time(), c$id, c$uid, is_orig, msg, options);
}
event bro_done() &priority=-5
{ {
Log::write(DHCP::LOG, c$dhcp); # Log any remaining data that hasn't already been logged!
} for ( i in DHCP::join_data )
join_data_expiration(DHCP::join_data, i);
} }

View file

@ -1,19 +0,0 @@
##! Utilities specific for DHCP processing.
module DHCP;
export {
## Reverse the octets of an IPv4 address.
##
## ip: An IPv4 address.
##
## Returns: A reversed IPv4 address.
global reverse_ip: function(ip: addr): addr;
}
function reverse_ip(ip: addr): addr
{
local octets = split_string(cat(ip), /\./);
return to_addr(cat(octets[3], ".", octets[2], ".", octets[1], ".", octets[0]));
}

View file

@ -2,12 +2,6 @@
##! been able to determine the MAC address, and it logs them once per day (by ##! been able to determine the MAC address, and it logs them once per day (by
##! default). The log that is output provides an easy way to determine a count ##! default). The log that is output provides an easy way to determine a count
##! of the devices in use on a network per day. ##! of the devices in use on a network per day.
##!
##! .. note::
##!
##! This script will not generate any logs on its own, it needs to be
##! supplied with information from elsewhere, such as
##! :doc:`/scripts/policy/protocols/dhcp/known-devices-and-hostnames.bro`.
module Known; module Known;

View file

@ -1,37 +0,0 @@
##! Tracks MAC address with hostnames seen in DHCP traffic. They are logged into
##! ``devices.log``.
@load policy/misc/known-devices
module Known;
export {
redef record DevicesInfo += {
## The value of the DHCP host name option, if seen.
dhcp_host_name: string &log &optional;
};
}
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)
{
if ( msg$h_addr == "" )
return;
if ( msg$h_addr !in known_devices )
{
add known_devices[msg$h_addr];
Log::write(Known::DEVICES_LOG, [$ts=network_time(), $mac=msg$h_addr, $dhcp_host_name=host_name]);
}
}
event dhcp_inform(c: connection, msg: DHCP::dhcp_msg, host_name: string, req_params: DHCP::dhcp_params_list)
{
if ( msg$h_addr == "" )
return;
if ( msg$h_addr !in known_devices )
{
add known_devices[msg$h_addr];
Log::write(Known::DEVICES_LOG, [$ts=network_time(), $mac=msg$h_addr, $dhcp_host_name=host_name]);
}
}

View file

@ -0,0 +1,21 @@
##! Add a field that logs the order of hosts sending messages
##! using the same DHCP transaction ID. This information is
##! occasionally needed on some networks to fully explain the
##! DHCP sequence.
@load base/protocols/dhcp
module DHCP;
export {
redef record DHCP::Info += {
## The address that originated each message from the
## `msg_types` field.
msg_orig: vector of addr &log &default=addr_vec();
};
}
event DHCP::aggregate_msgs(ts: time, id: conn_id, uid: string, is_orig: bool, msg: DHCP::Msg, options: DHCP::Options) &priority=3
{
log_info$msg_orig[|log_info$msg_orig|] = is_orig ? id$orig_h : id$resp_h;
}

View file

@ -0,0 +1,63 @@
##! Software identification and extraction for DHCP traffic.
@load base/protocols/dhcp
@load base/frameworks/software
module DHCP;
export {
redef enum Software::Type += {
## Identifier for web servers in the software framework.
DHCP::SERVER,
## Identifier for web browsers in the software framework.
DHCP::CLIENT,
};
redef record DHCP::Info += {
## Software reported by the client in the `vendor_class` option.
client_software: string &log &optional;
## Software reported by the server in the `vendor_class` option.
server_software: string &log &optional;
};
}
event DHCP::aggregate_msgs(ts: time, id: conn_id, uid: string, is_orig: bool, msg: DHCP::Msg, options: DHCP::Options) &priority=5
{
if ( options?$vendor_class )
{
if ( is_orig )
log_info$client_software = options$vendor_class;
else
{
log_info$server_software = options$vendor_class;
Software::found(id, [$unparsed_version=options$vendor_class,
$host=id$resp_h,
$software_type=DHCP::SERVER]);
}
}
}
event DHCP::log_dhcp(rec: DHCP::Info)
{
if ( rec?$assigned_addr && rec?$server_addr &&
(rec?$client_software || rec?$server_software) )
{
# Not quite right to just blindly use 67 and 68 as the ports
local id: conn_id = [$orig_h=rec$assigned_addr, $orig_p=68/udp,
$resp_h=rec$server_addr, $resp_p=67/udp];
if ( rec?$client_software && rec$assigned_addr != 255.255.255.255 )
{
Software::found(id, [$unparsed_version=rec$client_software,
$host=rec$assigned_addr,
$software_type=DHCP::CLIENT]);
}
if ( rec?$server_software )
{
Software::found(id, [$unparsed_version=rec$server_software,
$host=rec$server_addr,
$software_type=DHCP::SERVER]);
}
}
}

View file

@ -0,0 +1,45 @@
@load base/protocols/dhcp
module DHCP;
export {
redef record DHCP::Info += {
## Added by DHCP relay agents which terminate switched or
## permanent circuits. It encodes an agent-local identifier
## of the circuit from which a DHCP client-to-server packet was
## received. Typically it should represent a router or switch
## interface number.
circuit_id: string &log &optional;
## A globally unique identifier added by relay agents to identify
## the remote host end of the circuit.
agent_remote_id: string &log &optional;
## The subscriber ID is a value independent of the physical
## network configuration so that a customer's DHCP configuration
## can be given to them correctly no matter where they are
## physically connected.
subscriber_id: string &log &optional;
};
}
event DHCP::aggregate_msgs(ts: time, id: conn_id, uid: string, is_orig: bool, msg: DHCP::Msg, options: DHCP::Options)
{
if ( options?$sub_opt )
{
for ( i in options$sub_opt )
{
local sub_opt = options$sub_opt[i];
if ( sub_opt$code == 1 )
DHCP::log_info$circuit_id = sub_opt$value;
if ( sub_opt$code == 2 )
DHCP::log_info$agent_remote_id = sub_opt$value;
if ( sub_opt$code == 6 )
DHCP::log_info$subscriber_id = sub_opt$value;
}
}
}

View file

@ -60,7 +60,9 @@
@load protocols/conn/mac-logging.bro @load protocols/conn/mac-logging.bro
@load protocols/conn/vlan-logging.bro @load protocols/conn/vlan-logging.bro
@load protocols/conn/weirds.bro @load protocols/conn/weirds.bro
@load protocols/dhcp/known-devices-and-hostnames.bro @load protocols/dhcp/msg-orig.bro
@load protocols/dhcp/software.bro
@load protocols/dhcp/sub-opts.bro
@load protocols/dns/auth-addl.bro @load protocols/dns/auth-addl.bro
@load protocols/dns/detect-external-names.bro @load protocols/dns/detect-external-names.bro
@load protocols/ftp/detect-bruteforcing.bro @load protocols/ftp/detect-bruteforcing.bro

View file

@ -3,11 +3,13 @@ refine flow DHCP_Flow += {
%member{ %member{
RecordVal *dhcp_msg_val; RecordVal *dhcp_msg_val;
RecordVal *options; RecordVal *options;
VectorVal* all_options;
%} %}
%init{ %init{
dhcp_msg_val = 0; dhcp_msg_val = 0;
options = 0; options = 0;
all_options = 0;
%} %}
%cleanup{ %cleanup{
@ -16,123 +18,22 @@ refine flow DHCP_Flow += {
Unref(options); Unref(options);
options = 0; options = 0;
Unref(all_options);
all_options = 0;
%} %}
function parse_request(options: Option[], type: uint8): bool function create_options(code: uint8): bool
%{
// // Requested IP address to the server.
// ::uint32 req_addr = 0, serv_addr = 0;
// StringVal* host_name = new StringVal("");
//
// TableVal* params_list = 0;
// RecordVal* client_id = new RecordVal(BifType::Record::DHCP::ClientID);
// client_id->Assign(0,0);
// client_id->Assign(1,new StringVal(""));
//
// 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;
%}
function parse_reply(options: Option[], type: uint8): bool
%{
// // RFC 1533 allows a list of router addresses.
// 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;
%}
function create_options(): bool
%{ %{
if ( options == nullptr ) if ( options == nullptr )
{
options = new RecordVal(BifType::Record::DHCP::Options); options = new RecordVal(BifType::Record::DHCP::Options);
all_options = new VectorVal(index_vec);
options->Assign(0, all_options->Ref());
}
if ( code != 255 )
all_options->Assign(all_options->Size(), new Val(code, TYPE_COUNT));
return true; return true;
%} %}
@ -148,19 +49,47 @@ refine flow DHCP_Flow += {
return false; return false;
} }
if ( dhcp_message )
{
// Since this is a new message, let's make sure an old
// one is gone.
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());
double secs = static_cast<double>(${msg.secs});
dhcp_msg_val = new RecordVal(BifType::Record::DHCP::Msg); dhcp_msg_val = new RecordVal(BifType::Record::DHCP::Msg);
dhcp_msg_val->Assign(0, new Val(${msg.op}, TYPE_COUNT)); dhcp_msg_val->Assign(0, new Val(${msg.op}, TYPE_COUNT));
dhcp_msg_val->Assign(1, new Val(${msg.type}, TYPE_COUNT)); dhcp_msg_val->Assign(1, new Val(${msg.type}, TYPE_COUNT));
dhcp_msg_val->Assign(2, new Val(${msg.xid}, TYPE_COUNT)); dhcp_msg_val->Assign(2, new Val(${msg.xid}, TYPE_COUNT));
dhcp_msg_val->Assign(3, new StringVal(mac_str)); dhcp_msg_val->Assign(3, new Val(secs, TYPE_INTERVAL));
dhcp_msg_val->Assign(4, new AddrVal(${msg.ciaddr})); dhcp_msg_val->Assign(4, new Val(${msg.flags}, TYPE_COUNT));
dhcp_msg_val->Assign(5, new AddrVal(${msg.yiaddr})); dhcp_msg_val->Assign(5, new AddrVal(htonl(${msg.ciaddr})));
dhcp_msg_val->Assign(6, new AddrVal(htonl(${msg.yiaddr})));
dhcp_msg_val->Assign(7, new AddrVal(htonl(${msg.siaddr})));
dhcp_msg_val->Assign(8, new AddrVal(htonl(${msg.giaddr})));
dhcp_msg_val->Assign(9, new StringVal(mac_str));
int last_non_null = 0;
for ( int i=0; i < ${msg.sname}.length(); i++ )
{
if ( *(${msg.sname}.begin()+i) != 0 )
last_non_null = i;
}
if ( last_non_null > 0 )
dhcp_msg_val->Assign(10, new StringVal(last_non_null+1,
reinterpret_cast<const char*>(${msg.sname}.begin())));
last_non_null = 0;
for ( int i=0; i < ${msg.file_n}.length(); i++ )
{
if ( *(${msg.file_n}.begin()+i) != 0 )
last_non_null = i;
}
if ( last_non_null > 0 )
dhcp_msg_val->Assign(11, new StringVal(last_non_null+1,
reinterpret_cast<const char*>(${msg.file_n}.begin())));
if ( dhcp_message )
BifEvent::generate_dhcp_message(connection()->bro_analyzer(), BifEvent::generate_dhcp_message(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(), connection()->bro_analyzer()->Conn(),
${msg.is_orig}, ${msg.is_orig},
@ -171,50 +100,9 @@ refine flow DHCP_Flow += {
dhcp_msg_val = 0; dhcp_msg_val = 0;
Unref(options); Unref(options);
options = 0; options = 0;
Unref(all_options);
//switch ( ${msg.op} ) all_options = 0;
// { }
// case BOOTREQUEST: // presumably from client to server
// if ( ${msg.type} == DHCPDISCOVER ||
// ${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
// 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 // A single message reaching this point is enough to confirm the protocol
// because it's not uncommon to see a single DHCP message // because it's not uncommon to see a single DHCP message
@ -232,6 +120,6 @@ refine typeattr DHCP_Message += &let {
}; };
refine typeattr Option += &let { refine typeattr Option += &let {
proc_create_options = $context.flow.create_options(); proc_create_options = $context.flow.create_options(code);
}; };

View file

@ -1,4 +1,3 @@
############################## ##############################
# SUBNET OPTION # SUBNET OPTION
############################## ##############################
@ -6,19 +5,86 @@ let SUBNET_OPTION = 1;
# Parse the option # Parse the option
refine casetype OptionValue += { refine casetype OptionValue += {
SUBNET_OPTION -> mask : uint32; SUBNET_OPTION -> subnet : uint32;
}; };
refine flow DHCP_Flow += { refine flow DHCP_Flow += {
function process_subnet_option(v: OptionValue): bool function process_subnet_option(v: OptionValue): bool
%{ %{
${context.flow}->options->Assign(0, new AddrVal(htonl(${v.mask}))); ${context.flow}->options->Assign(1, new AddrVal(htonl(${v.subnet})));
return true; return true;
%} %}
}; };
refine typeattr Option += &let { refine typeattr Option += &let {
proc_subnet_option = $context.flow.process_subnet_option(info) &if(code==SUBNET_OPTION); proc_subnet_option = $context.flow.process_subnet_option(info.value) &if(code==SUBNET_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
%{
VectorVal* router_list = new VectorVal(BifType::Vector::DHCP::Addrs);
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];
router_list->Assign(i, new AddrVal(htonl(raddr)));
}
${context.flow}->options->Assign(2, router_list);
return true;
%}
};
refine typeattr Option += &let {
proc_router_option = $context.flow.process_router_option(info.value) &if(code==ROUTER_OPTION);
};
##############################
# DNS SERVER OPTION
##############################
let DNS_SERVER_OPTION = 6;
# Parse the option
refine casetype OptionValue += {
DNS_SERVER_OPTION -> dns_server_list : uint32[length/4];
};
refine flow DHCP_Flow += {
function process_dns_server_option(v: OptionValue): bool
%{
VectorVal* server_list = new VectorVal(BifType::Vector::DHCP::Addrs);
int num_servers = ${v.dns_server_list}->size();
vector<uint32>* rlist = ${v.dns_server_list};
for ( int i = 0; i < num_servers; ++i )
{
uint32 raddr = (*rlist)[i];
server_list->Assign(i, new AddrVal(htonl(raddr)));
}
${context.flow}->options->Assign(3, server_list);
return true;
%}
};
refine typeattr Option += &let {
proc_dns_server_option = $context.flow.process_dns_server_option(info.value) &if(code==DNS_SERVER_OPTION);
}; };
@ -35,76 +101,177 @@ refine casetype OptionValue += {
refine flow DHCP_Flow += { refine flow DHCP_Flow += {
function process_host_name_option(v: OptionValue): bool 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())); ${context.flow}->options->Assign(4, new StringVal(${v.host_name}.length(),
reinterpret_cast<const char*>(${v.host_name}.begin())));
return true; return true;
%} %}
}; };
refine typeattr Option += &let { refine typeattr Option += &let {
proc_host_name_option = $context.flow.process_host_name_option(info) &if(code==HOST_NAME_OPTION); proc_host_name_option = $context.flow.process_host_name_option(info.value) &if(code==HOST_NAME_OPTION);
}; };
############################## ##############################
# REQ IP OPTION # DOMAIN NAME OPTION
############################## ##############################
let REQ_IP_OPTION = 50; let DOMAIN_NAME_OPTION = 15;
# Parse the option # Parse the option
refine casetype OptionValue += { refine casetype OptionValue += {
REQ_IP_OPTION -> req_addr : uint32; DOMAIN_NAME_OPTION -> domain_name : bytestring &length=length;
}; };
refine flow DHCP_Flow += { refine flow DHCP_Flow += {
function process_req_ip_option(v: OptionValue): bool function process_domain_name_option(v: OptionValue): bool
%{ %{
${context.flow}->options->Assign(2, new AddrVal(htonl(${v.req_addr}))); int last_non_null = 0;
for ( int i=0; i < ${v.domain_name}.length(); i++)
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]; if ( *(${v.domain_name}.begin()+i) != 0 )
::uint32 tmp_addr; last_non_null = i;
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); ${context.flow}->options->Assign(5, new StringVal(last_non_null == 0 ? 0 : last_non_null+1,
reinterpret_cast<const char*>(${v.domain_name}.begin())));
return true; return true;
%} %}
}; };
refine typeattr Option += &let { refine typeattr Option += &let {
proc_router_option = $context.flow.process_router_option(info) &if(code==ROUTER_OPTION); proc_domain_name_option = $context.flow.process_domain_name_option(info.value) &if(code==DOMAIN_NAME_OPTION);
};
##############################
# FORWARDING OPTION
##############################
let FORWARDING_OPTION = 19;
# Parse the option
refine casetype OptionValue += {
FORWARDING_OPTION -> forwarding : uint8;
};
refine flow DHCP_Flow += {
function process_forwarding_option(v: OptionValue): bool
%{
${context.flow}->options->Assign(6, new Val(${v.forwarding} == 0 ? false : true, TYPE_BOOL));
return true;
%}
};
refine typeattr Option += &let {
proc_forwarding_option = $context.flow.process_forwarding_option(info.value) &if(code==FORWARDING_OPTION);
};
##############################
# BROADCAST ADDRESS OPTION
##############################
let BROADCAST_ADDRESS_OPTION = 28;
# Parse the option
refine casetype OptionValue += {
BROADCAST_ADDRESS_OPTION -> broadcast_address : uint32;
};
refine flow DHCP_Flow += {
function process_broadcast_address_option(v: OptionValue): bool
%{
${context.flow}->options->Assign(7, new AddrVal(htonl(${v.broadcast_address})));
return true;
%}
};
refine typeattr Option += &let {
proc_broadcast_address_option = $context.flow.process_broadcast_address_option(info.value) &if(code==BROADCAST_ADDRESS_OPTION);
};
##############################
# VENDOR SPECIFIC OPTION
##############################
let VENDOR_SPECIFIC_OPTION = 43;
# Parse the option
refine casetype OptionValue += {
VENDOR_SPECIFIC_OPTION -> vendor_specific : bytestring &length=length;
};
refine flow DHCP_Flow += {
function process_vendor_specific_option(v: OptionValue): bool
%{
${context.flow}->options->Assign(8, new StringVal(${v.vendor_specific}.length(),
reinterpret_cast<const char*>(${v.vendor_specific}.begin())));
return true;
%}
};
refine typeattr Option += &let {
proc_vendor_specific_option = $context.flow.process_vendor_specific_option(info.value) &if(code==VENDOR_SPECIFIC_OPTION);
};
##############################
# NETBIOS NAME SERVER OPTION
##############################
let NBNS_OPTION = 44;
# Parse the option
refine casetype OptionValue += {
NBNS_OPTION -> nbns : uint32[length/4];
};
refine flow DHCP_Flow += {
function process_nbns_option(v: OptionValue): bool
%{
VectorVal* server_list = new VectorVal(BifType::Vector::DHCP::Addrs);
int num_servers = ${v.nbns}->size();
vector<uint32>* rlist = ${v.nbns};
for ( int i = 0; i < num_servers; ++i )
{
uint32 raddr = (*rlist)[i];
server_list->Assign(i, new AddrVal(htonl(raddr)));
}
${context.flow}->options->Assign(9, server_list);
return true;
%}
};
refine typeattr Option += &let {
proc_nbns_option = $context.flow.process_nbns_option(info.value) &if(code==NBNS_OPTION);
};
##############################
# ADDR REQUEST OPTION
##############################
let ADDR_REQUEST_OPTION = 50;
# Parse the option
refine casetype OptionValue += {
ADDR_REQUEST_OPTION -> addr_request : uint32;
};
refine flow DHCP_Flow += {
function process_addr_request_option(v: OptionValue): bool
%{
${context.flow}->options->Assign(10, new AddrVal(htonl(${v.addr_request})));
return true;
%}
};
refine typeattr Option += &let {
proc_addr_request_option = $context.flow.process_addr_request_option(info.value) &if(code==ADDR_REQUEST_OPTION);
}; };
@ -122,16 +289,17 @@ refine flow DHCP_Flow += {
function process_lease_option(v: OptionValue): bool function process_lease_option(v: OptionValue): bool
%{ %{
double lease = static_cast<double>(${v.lease}); double lease = static_cast<double>(${v.lease});
${context.flow}->options->Assign(4, new Val(lease, TYPE_INTERVAL)); ${context.flow}->options->Assign(11, new Val(lease, TYPE_INTERVAL));
return true; return true;
%} %}
}; };
refine typeattr Option += &let { refine typeattr Option += &let {
proc_lease_option = $context.flow.process_lease_option(info) &if(code==LEASE_OPTION); proc_lease_option = $context.flow.process_lease_option(info.value) &if(code==LEASE_OPTION);
}; };
############################## ##############################
# SERV_ID_OPTION OPTION # SERV_ID_OPTION OPTION
############################## ##############################
@ -145,14 +313,14 @@ refine casetype OptionValue += {
refine flow DHCP_Flow += { refine flow DHCP_Flow += {
function process_serv_id_option(v: OptionValue): bool function process_serv_id_option(v: OptionValue): bool
%{ %{
${context.flow}->options->Assign(5, new AddrVal(htonl(${v.serv_addr}))); ${context.flow}->options->Assign(12, new AddrVal(htonl(${v.serv_addr})));
return true; return true;
%} %}
}; };
refine typeattr Option += &let { refine typeattr Option += &let {
proc_serv_id_option = $context.flow.process_serv_id_option(info) &if(code==SERV_ID_OPTION); proc_serv_id_option = $context.flow.process_serv_id_option(info.value) &if(code==SERV_ID_OPTION);
}; };
@ -169,76 +337,148 @@ refine casetype OptionValue += {
refine flow DHCP_Flow += { refine flow DHCP_Flow += {
function process_par_req_list_option(v: OptionValue): bool function process_par_req_list_option(v: OptionValue): bool
%{ %{
TableVal* params_list = new TableVal(BifType::Table::DHCP::ParamsList); VectorVal* params = new VectorVal(index_vec);
int num_parms = ${v.par_req_list}->size(); int num_parms = ${v.par_req_list}->size();
vector<uint8>* plist = ${v.par_req_list}; vector<uint8>* plist = ${v.par_req_list};
for (int i=0; i < num_parms; ++i) for (int i=0; i < num_parms; ++i)
{ {
uint8 param = (*plist)[i]; uint8 param = (*plist)[i];
Val* index = new Val(i+1, TYPE_COUNT); params->Assign(i, new Val(param, TYPE_COUNT));
params_list->Assign(index, new Val(param, TYPE_COUNT));
Unref(index);
} }
${context.flow}->options->Assign(6, params_list); ${context.flow}->options->Assign(13, params);
return true; return true;
%} %}
}; };
refine typeattr Option += &let { refine typeattr Option += &let {
proc_par_req_list_option = $context.flow.process_par_req_list_option(info) &if(code==PAR_REQ_LIST_OPTION); proc_par_req_list_option = $context.flow.process_par_req_list_option(info.value) &if(code==PAR_REQ_LIST_OPTION);
}; };
############################## ##############################
# REN_TIME_OPTION OPTION # MESSAGE OPTION
############################## ##############################
let REN_TIME_OPTION = 58; let MESSAGE_OPTION = 56;
# Parse the option # Parse the option
refine casetype OptionValue += { refine casetype OptionValue += {
REN_TIME_OPTION -> ren_time : uint32; MESSAGE_OPTION -> message : bytestring &length=length;
}; };
refine flow DHCP_Flow += { refine flow DHCP_Flow += {
function process_ren_time_option(v: OptionValue): bool function process_message_option(v: OptionValue): bool
%{ %{
double ren_time = static_cast<double>(${v.ren_time}); ${context.flow}->options->Assign(14, new StringVal(${v.message}.length(),
${context.flow}->options->Assign(7, new Val(ren_time, TYPE_INTERVAL)); reinterpret_cast<const char*>(${v.message}.begin())));
return true; return true;
%} %}
}; };
refine typeattr Option += &let { refine typeattr Option += &let {
proc_ren_time_option = $context.flow.process_ren_time_option(info) &if(code==REN_TIME_OPTION); proc_message_option = $context.flow.process_message_option(info.value) &if(code==MESSAGE_OPTION);
}; };
############################## ##############################
# REB_TIME_OPTION OPTION # MAX MESSAGE SIZE OPTION
############################## ##############################
let REB_TIME_OPTION = 59; let MAX_MESSAGE_SIZE_OPTION = 57;
# Parse the option # Parse the option
refine casetype OptionValue += { refine casetype OptionValue += {
REB_TIME_OPTION -> reb_time : uint32; MAX_MESSAGE_SIZE_OPTION -> max_msg_size : uint16;
}; };
refine flow DHCP_Flow += { refine flow DHCP_Flow += {
function process_reb_time_option(v: OptionValue): bool function process_max_message_size_option(v: OptionValue): bool
%{ %{
double reb_time = static_cast<double>(${v.reb_time}); ${context.flow}->options->Assign(15, new Val(${v.max_msg_size}, TYPE_COUNT));
${context.flow}->options->Assign(8, new Val(reb_time, TYPE_INTERVAL));
return true; return true;
%} %}
}; };
refine typeattr Option += &let { refine typeattr Option += &let {
proc_reb_time_option = $context.flow.process_reb_time_option(info) &if(code==REB_TIME_OPTION); proc_max_message_size_option = $context.flow.process_max_message_size_option(info.value) &if(code==MAX_MESSAGE_SIZE_OPTION);
};
##############################
# RENEWAL_TIME_OPTION OPTION
##############################
let RENEWAL_TIME_OPTION = 58;
# Parse the option
refine casetype OptionValue += {
RENEWAL_TIME_OPTION -> renewal_time : uint32;
};
refine flow DHCP_Flow += {
function process_renewal_time_option(v: OptionValue): bool
%{
double renewal_time = static_cast<double>(${v.renewal_time});
${context.flow}->options->Assign(16, new Val(renewal_time, TYPE_INTERVAL));
return true;
%}
};
refine typeattr Option += &let {
proc_renewal_time_option = $context.flow.process_renewal_time_option(info.value) &if(code==RENEWAL_TIME_OPTION);
};
##############################
# REBINDING_TIME_OPTION OPTION
##############################
let REBINDING_TIME_OPTION = 59;
# Parse the option
refine casetype OptionValue += {
REBINDING_TIME_OPTION -> rebinding_time : uint32;
};
refine flow DHCP_Flow += {
function process_rebinding_time_option(v: OptionValue): bool
%{
double rebinding_time = static_cast<double>(${v.rebinding_time});
${context.flow}->options->Assign(17, new Val(rebinding_time, TYPE_INTERVAL));
return true;
%}
};
refine typeattr Option += &let {
proc_rebinding_time_option = $context.flow.process_rebinding_time_option(info.value) &if(code==REBINDING_TIME_OPTION);
};
##############################
# VENDOR CLASS OPTION
##############################
let VENDOR_CLASS_OPTION = 60;
# Parse the option
refine casetype OptionValue += {
VENDOR_CLASS_OPTION -> vendor_class : bytestring &length=length;
};
refine flow DHCP_Flow += {
function process_vendor_class_option(v: OptionValue): bool
%{
${context.flow}->options->Assign(18, new StringVal(${v.vendor_class}.length(),
reinterpret_cast<const char*>(${v.vendor_class}.begin())));
return true;
%}
};
refine typeattr Option += &let {
proc_vendor_class_option = $context.flow.process_vendor_class_option(info.value) &if(code==VENDOR_CLASS_OPTION);
}; };
@ -264,17 +504,79 @@ refine flow DHCP_Flow += {
client_id->Assign(0, new Val(${v.client_id.hwtype}, TYPE_COUNT)); 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()))); 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); ${context.flow}->options->Assign(19, client_id);
return true; return true;
%} %}
}; };
refine typeattr Option += &let { refine typeattr Option += &let {
proc_client_id_option = $context.flow.process_client_id_option(info) &if(code==CLIENT_ID_OPTION); proc_client_id_option = $context.flow.process_client_id_option(info.value) &if(code==CLIENT_ID_OPTION);
}; };
##############################
# USER CLASS OPTION
##############################
let USER_CLASS_OPTION = 77;
# Parse the option
refine casetype OptionValue += {
USER_CLASS_OPTION -> user_class : bytestring &length=length;
};
refine flow DHCP_Flow += {
function process_user_class_option(v: OptionValue): bool
%{
${context.flow}->options->Assign(20, new StringVal(${v.user_class}.length(),
reinterpret_cast<const char*>(${v.user_class}.begin())));
return true;
%}
};
refine typeattr Option += &let {
proc_user_class_option = $context.flow.process_user_class_option(info.value) &if(code==USER_CLASS_OPTION);
};
##############################
# CLIENT FQDN OPTION
##############################
let CLIENT_FQDN_OPTION = 81;
type Client_FQDN(length: uint8) = record {
flags : uint8;
rcode1 : uint8;
rcode2 : uint8;
domain_name : bytestring &length=length-3;
};
# Parse the option
refine casetype OptionValue += {
CLIENT_FQDN_OPTION -> client_fqdn : Client_FQDN(length);
};
refine flow DHCP_Flow += {
function process_client_fqdn_option(v: OptionValue): bool
%{
RecordVal* client_fqdn = new RecordVal(BifType::Record::DHCP::ClientFQDN);
client_fqdn->Assign(0, new Val(${v.client_fqdn.flags}, TYPE_COUNT));
client_fqdn->Assign(1, new Val(${v.client_fqdn.rcode1}, TYPE_COUNT));
client_fqdn->Assign(2, new Val(${v.client_fqdn.rcode2}, TYPE_COUNT));
const char* domain_name = reinterpret_cast<const char*>(${v.client_fqdn.domain_name}.begin());
client_fqdn->Assign(3, new StringVal(${v.client_fqdn.domain_name}.length(), domain_name));
${context.flow}->options->Assign(21, client_fqdn);
return true;
%}
};
refine typeattr Option += &let {
proc_client_fqdn_option = $context.flow.process_client_fqdn_option(info.value) &if(code==CLIENT_FQDN_OPTION);
};
############################## ##############################
# RELAY_AGENT_INF OPTION # RELAY_AGENT_INF OPTION
@ -296,11 +598,30 @@ refine casetype OptionValue += {
}; };
refine flow DHCP_Flow += { 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 process_relay_agent_inf_option(v: OptionValue): bool function process_relay_agent_inf_option(v: OptionValue): bool
%{ %{
TableVal* relay_agent_sub_opt = new TableVal(BifType::Table::DHCP::SubOptList); VectorVal* relay_agent_sub_opt = new VectorVal(BifType::Vector::DHCP::SubOpts);
RecordVal* r = new RecordVal(BifType::Record::DHCP::SubOpt); RecordVal* r = new RecordVal(BifType::Record::DHCP::SubOpt);
uint i = 1;
uint16 i = 0;
for ( auto ptrsubopt = ${v.relay_agent_inf}->begin(); for ( auto ptrsubopt = ${v.relay_agent_inf}->begin();
ptrsubopt != ${v.relay_agent_inf}->end(); ++ptrsubopt ) ptrsubopt != ${v.relay_agent_inf}->end(); ++ptrsubopt )
{ {
@ -308,20 +629,69 @@ refine flow DHCP_Flow += {
r->Assign(0, new Val((*ptrsubopt)->code(), TYPE_COUNT)); r->Assign(0, new Val((*ptrsubopt)->code(), TYPE_COUNT));
r->Assign(1, bytestring_to_val((*ptrsubopt)->value())); r->Assign(1, bytestring_to_val((*ptrsubopt)->value()));
Val* index = new Val(i, TYPE_COUNT); relay_agent_sub_opt->Assign(i, r);
relay_agent_sub_opt->Assign(index, r);
Unref(index);
++i; ++i;
} }
${context.flow}->options->Assign(10, relay_agent_sub_opt); ${context.flow}->options->Assign(22, relay_agent_sub_opt);
return true; return true;
%} %}
}; };
refine typeattr Option += &let { refine typeattr Option += &let {
proc_relay_agent_info_option = $context.flow.process_relay_agent_inf_option(info) &if(code==RELAY_AGENT_INF_OPTION); proc_relay_agent_info_option = $context.flow.process_relay_agent_inf_option(info.value) &if(code==RELAY_AGENT_INF_OPTION);
}; };
##############################
# AUTO_CONFIG OPTION
##############################
let AUTO_CONFIG_OPTION = 116;
# Parse the option
refine casetype OptionValue += {
AUTO_CONFIG_OPTION -> auto_config : uint8;
};
refine flow DHCP_Flow += {
function process_auto_config_option(v: OptionValue): bool
%{
${context.flow}->options->Assign(23, new Val(${v.auto_config} == 0 ? false : true, TYPE_BOOL));
return true;
%}
};
refine typeattr Option += &let {
proc_auto_config_option = $context.flow.process_auto_config_option(info.value) &if(code==AUTO_CONFIG_OPTION);
};
##############################
# AUTO PROXY CONFIG OPTION
##############################
let AUTO_PROXY_CONFIG_OPTION = 252;
# Parse the option
refine casetype OptionValue += {
AUTO_PROXY_CONFIG_OPTION -> auto_proxy_config : bytestring &length=length;
};
refine flow DHCP_Flow += {
function process_auto_proxy_config_option(v: OptionValue): bool
%{
int string_len = ${v.auto_proxy_config}.length();
const char* last_char = reinterpret_cast<const char*>(${v.auto_proxy_config}.begin()+${v.auto_proxy_config}.length());
bool has_newline = strncmp(last_char, "\x0a", 1);
${context.flow}->options->Assign(24, new StringVal(string_len - (has_newline ? 1 : 0),
reinterpret_cast<const char*>(${v.auto_proxy_config}.begin())));
return true;
%}
};
refine typeattr Option += &let {
proc_auto_proxy_config_option = $context.flow.process_auto_proxy_config_option(info.value) &if(code==AUTO_PROXY_CONFIG_OPTION);
};

View file

@ -8,34 +8,22 @@ enum OP_type {
let MSG_TYPE_OPTION = 53; let MSG_TYPE_OPTION = 53;
enum DHCP_message_type {
DHCPDISCOVER = 1,
DHCPOFFER = 2,
DHCPREQUEST = 3,
DHCPDECLINE = 4,
DHCPACK = 5,
DHCPNAK = 6,
DHCPRELEASE = 7,
DHCPINFORM = 8,
DHCPFORCERENEW = 9, # RFC 2132
DHCPLEASEQUERY = 10, # RFC 4388
DHCPLEASEUNASSIGNED = 11, # RFC 4388
DHCPLEASEUNKNOWN = 12, # RFC 4388
DHCPLEASEACTIVE = 13 # RFC 4388
};
type OptionValue(code: uint8, length: uint8) = case code of { type OptionValue(code: uint8, length: uint8) = case code of {
# This is extended in dhcp-options.pac # This is extended in dhcp-options.pac
MSG_TYPE_OPTION -> msg_type : uint8; MSG_TYPE_OPTION -> msg_type : uint8;
default -> other : bytestring &length = length; default -> other : bytestring &length = length;
}; };
type OptionValueWrapper(code: uint8) = record {
length : uint8;
value : OptionValue(code, length);
};
type Option = record { type Option = record {
code : uint8; code : uint8;
length : uint8;
data : case code of { data : case code of {
0, 255 -> none : empty; 0, 255 -> none : empty;
default -> info : OptionValue(code, length); default -> info : OptionValueWrapper(code);
}; };
} &let { } &let {
last = (code == 255); # Mark the end of a list of options last = (code == 255); # Mark the end of a list of options
@ -55,7 +43,7 @@ type DHCP_Message(is_orig: bool) = record {
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_n : 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;
@ -65,24 +53,6 @@ type DHCP_Message(is_orig: bool) = record {
} &byteorder = bigendian; } &byteorder = bigendian;
refine flow DHCP_Flow += { 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 function get_dhcp_msgtype(options: Option[]): uint8
%{ %{
uint8 type = 0; uint8 type = 0;
@ -91,7 +61,7 @@ refine flow DHCP_Flow += {
{ {
if ( (*ptr)->code() == MSG_TYPE_OPTION ) if ( (*ptr)->code() == MSG_TYPE_OPTION )
{ {
type = (*ptr)->info()->msg_type(); type = (*ptr)->info()->value()->msg_type();
break; break;
} }
} }

View file

@ -1,188 +1,12 @@
## Generated for all DHCP messages.
##
## c: The connection record describing the underlying UDP flow.
##
## is_orig: Indicate if the message came in a packet from the originator/client
## of the udp flow or the responder/server.
##
## msg: The parsed type-independent part of the DHCP message. The message type
## is indicated in this record.
##
## options: The full set of supported and parsed DHCP options.
event dhcp_message%(c: connection, is_orig: bool, msg: DHCP::Msg, options: DHCP::Options%); 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
## available servers).
##
## c: The connection record describing the underlying UDP flow.
##
## msg: The parsed type-independent part of the DHCP message.
##
## req_addr: The specific address requested by the client.
##
## host_name: The value of the host name option, if specified by the client.
##
## client_id: The value of the client id (usually the MAC ADDRESS).
##
## req_params: The Parameters Request List.
##
## .. bro:see:: dhcp_discover dhcp_offer dhcp_request dhcp_decline dhcp_ack dhcp_nak
## dhcp_release dhcp_inform
##
## .. note:: Bro does not support broadcast packets (as used by the DHCP
## protocol). It treats broadcast addresses just like any other and
## associates packets into transport-level flows in the same way as usual.
##
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
## to DHCPDISCOVER with offer of configuration parameters).
##
## c: The connection record describing the underlying UDP flow.
##
## msg: The parsed type-independent part of the DHCP message.
##
## mask: The subnet mask specified by the message.
##
## router: The list of routers specified by the message.
##
## lease: The least interval specified by the message.
##
## serv_addr: The server address specified by the message.
##
## host_name: Optional host name value. May differ from the host name requested
## from the client.
##
## .. bro:see:: dhcp_discover dhcp_request dhcp_decline dhcp_ack dhcp_nak
## dhcp_release dhcp_inform
##
## .. note:: Bro does not support broadcast packets (as used by the DHCP
## protocol). It treats broadcast addresses just like any other and
## associates packets into transport-level flows in the same way as usual.
##
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
## (a) requesting offered parameters from one server and implicitly declining offers
## from all others, (b) confirming correctness of previously allocated address after,
## e.g., system reboot, or (c) extending the lease on a particular network address.)
##
## c: The connection record describing the underlying UDP flow.
##
## msg: The parsed type-independent part of the DHCP message.
##
## req_addr: The client address specified by the message.
##
## serv_addr: The server address specified by the message.
##
## host_name: The value of the host name option, if specified by the client.
##
## client_id: The client id.
##
## req_parms: The Parameters Request List.
##
## .. bro:see:: dhcp_discover dhcp_offer dhcp_decline dhcp_ack dhcp_nak
## dhcp_release dhcp_inform
##
## .. note:: Bro does not support broadcast packets (as used by the DHCP
## protocol). It treats broadcast addresses just like any other and
## associates packets into transport-level flows in the same way as usual.
##
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
## network address is already in use).
##
## c: The connection record describing the underlying UDP flow.
##
## msg: The parsed type-independent part of the DHCP message.
##
## host_name: Optional host name value.
##
## .. bro:see:: dhcp_discover dhcp_offer dhcp_request dhcp_ack dhcp_nak
## dhcp_release dhcp_inform
##
## .. note:: Bro does not support broadcast packets (as used by the DHCP
## protocol). It treats broadcast addresses just like any other and
## associates packets into transport-level flows in the same way as usual.
##
event dhcp_decline%(c: connection, msg: DHCP::Msg, host_name: string%);
## Generated for DHCP messages of type *DHCPACK* (Server to client with configuration
## parameters, including committed network address).
##
## c: The connection record describing the underlying UDP flow.
##
## msg: The parsed type-independent part of the DHCP message.
##
## mask: The subnet mask specified by the message.
##
## router: The list of routers specified by the message.
##
## lease: The least interval specified by the message.
##
## serv_addr: The server address specified by the message.
##
## host_name: Optional host name value. May differ from the host name requested
## from the client.
##
## reb_time: A 32-bit unsigned integer indicating the number of seconds before
## the cilent enters the rebinding state if it has not renewed its
## current address lease with the DHCP server.
##
## ren_time: A 32-bit unsigned integer indicating the number of seconds before
## the client begins to renew its address lease with the DHCP server.
##
## sub_opt: DHCP relay agent information option list of suboption values
## (see http://slaptijack.com/networking/what-is-dhcp-option-82/ or
## http://www.juniper.net/documentation/en_US/junose14.3/topics/concept/dhcp-relay-option-82-suboptions-overview.html)
##
## .. bro:see:: dhcp_discover dhcp_offer dhcp_request dhcp_decline dhcp_nak
## dhcp_release dhcp_inform
##
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
## notion of network address is incorrect (e.g., client has moved to new subnet) or
## client's lease has expired).
##
## c: The connection record describing the underlying UDP flow.
##
## msg: The parsed type-independent part of the DHCP message.
##
## host_name: Optional host name value.
##
## .. bro:see:: dhcp_discover dhcp_offer dhcp_request dhcp_decline dhcp_ack dhcp_release
## dhcp_inform
##
## .. note:: Bro does not support broadcast packets (as used by the DHCP
## protocol). It treats broadcast addresses just like any other and
## associates packets into transport-level flows in the same way as usual.
##
event dhcp_nak%(c: connection, msg: DHCP::Msg, host_name: string%);
## Generated for DHCP messages of type *DHCPRELEASE* (Client to server relinquishing
## network address and cancelling remaining lease).
##
## c: The connection record describing the underlying UDP flow.
##
## msg: The parsed type-independent part of the DHCP message.
##
## host_name: The value of the host name option, if specified by the client.
##
## .. bro:see:: dhcp_discover dhcp_offer dhcp_request dhcp_decline dhcp_ack dhcp_nak
## dhcp_inform
##
event dhcp_release%(c: connection, msg: DHCP::Msg, host_name: string%);
## Generated for DHCP messages of type *DHCPINFORM* (Client to server, asking only for
## local configuration parameters; client already has externally configured network
## address).
##
## c: The connection record describing the underlying UDP flow.
##
## msg: The parsed type-independent part of the DHCP message.
##
## host_name: The value of the host name option, if specified by the client.
##
## req_parms: The Parameters Request List.
##
## .. bro:see:: dhcp_discover dhcp_offer dhcp_request dhcp_decline dhcp_ack dhcp_nak
## dhcp_release
##
## .. note:: Bro does not support broadcast packets (as used by the DHCP
## protocol). It treats broadcast addresses just like any other and
## associates packets into transport-level flows in the same way as usual.
##
event dhcp_inform%(c: connection, msg: DHCP::Msg, host_name: string%);

View file

@ -1,9 +1,9 @@
module DHCP; module DHCP;
type Msg: record; type Msg: record;
type RouterList: table; type Addrs: vector;
type ParamsList: table;
type SubOptList: table;
type SubOpt: record; type SubOpt: record;
type SubOpts: vector;
type ClientFQDN: record;
type ClientID: record; type ClientID: record;
type Options: record; type Options: record;

View file

@ -17,6 +17,7 @@
1 3306 1 3306
1 3389 1 3389
1 3544 1 3544
1 4011
2 443 2 443
1 502 1 502
1 5060 1 5060
@ -51,8 +52,8 @@
1 992 1 992
1 993 1 993
1 995 1 995
58 and 59 and
57 or 58 or
58 port 59 port
40 tcp 40 tcp
18 udp 19 udp

View file

@ -3,7 +3,7 @@
#empty_field (empty) #empty_field (empty)
#unset_field - #unset_field -
#path loaded_scripts #path loaded_scripts
#open 2017-05-02-20-38-47 #open 2018-03-01-16-07-03
#fields name #fields name
#types string #types string
scripts/base/init-bare.bro scripts/base/init-bare.bro
@ -66,6 +66,7 @@ scripts/base/init-bare.bro
build/scripts/base/bif/plugins/Bro_DCE_RPC.types.bif.bro build/scripts/base/bif/plugins/Bro_DCE_RPC.types.bif.bro
build/scripts/base/bif/plugins/Bro_DCE_RPC.events.bif.bro build/scripts/base/bif/plugins/Bro_DCE_RPC.events.bif.bro
build/scripts/base/bif/plugins/Bro_DHCP.events.bif.bro build/scripts/base/bif/plugins/Bro_DHCP.events.bif.bro
build/scripts/base/bif/plugins/Bro_DHCP.types.bif.bro
build/scripts/base/bif/plugins/Bro_DNP3.events.bif.bro build/scripts/base/bif/plugins/Bro_DNP3.events.bif.bro
build/scripts/base/bif/plugins/Bro_DNS.events.bif.bro build/scripts/base/bif/plugins/Bro_DNS.events.bif.bro
build/scripts/base/bif/plugins/Bro_File.events.bif.bro build/scripts/base/bif/plugins/Bro_File.events.bif.bro
@ -168,4 +169,4 @@ scripts/base/init-bare.bro
build/scripts/base/bif/plugins/Bro_SQLiteWriter.sqlite.bif.bro build/scripts/base/bif/plugins/Bro_SQLiteWriter.sqlite.bif.bro
scripts/policy/misc/loaded-scripts.bro scripts/policy/misc/loaded-scripts.bro
scripts/base/utils/paths.bro scripts/base/utils/paths.bro
#close 2017-05-02-20-38-47 #close 2018-03-01-16-07-03

View file

@ -3,7 +3,7 @@
#empty_field (empty) #empty_field (empty)
#unset_field - #unset_field -
#path loaded_scripts #path loaded_scripts
#open 2017-05-02-20-39-05 #open 2018-03-01-16-09-46
#fields name #fields name
#types string #types string
scripts/base/init-bare.bro scripts/base/init-bare.bro
@ -66,6 +66,7 @@ scripts/base/init-bare.bro
build/scripts/base/bif/plugins/Bro_DCE_RPC.types.bif.bro build/scripts/base/bif/plugins/Bro_DCE_RPC.types.bif.bro
build/scripts/base/bif/plugins/Bro_DCE_RPC.events.bif.bro build/scripts/base/bif/plugins/Bro_DCE_RPC.events.bif.bro
build/scripts/base/bif/plugins/Bro_DHCP.events.bif.bro build/scripts/base/bif/plugins/Bro_DHCP.events.bif.bro
build/scripts/base/bif/plugins/Bro_DHCP.types.bif.bro
build/scripts/base/bif/plugins/Bro_DNP3.events.bif.bro build/scripts/base/bif/plugins/Bro_DNP3.events.bif.bro
build/scripts/base/bif/plugins/Bro_DNS.events.bif.bro build/scripts/base/bif/plugins/Bro_DNS.events.bif.bro
build/scripts/base/bif/plugins/Bro_File.events.bif.bro build/scripts/base/bif/plugins/Bro_File.events.bif.bro
@ -267,7 +268,6 @@ scripts/base/init-default.bro
scripts/base/protocols/dhcp/__load__.bro scripts/base/protocols/dhcp/__load__.bro
scripts/base/protocols/dhcp/consts.bro scripts/base/protocols/dhcp/consts.bro
scripts/base/protocols/dhcp/main.bro scripts/base/protocols/dhcp/main.bro
scripts/base/protocols/dhcp/utils.bro
scripts/base/protocols/dnp3/__load__.bro scripts/base/protocols/dnp3/__load__.bro
scripts/base/protocols/dnp3/main.bro scripts/base/protocols/dnp3/main.bro
scripts/base/protocols/dnp3/consts.bro scripts/base/protocols/dnp3/consts.bro
@ -357,4 +357,4 @@ scripts/base/init-default.bro
scripts/base/misc/find-filtered-trace.bro scripts/base/misc/find-filtered-trace.bro
scripts/base/misc/version.bro scripts/base/misc/version.bro
scripts/policy/misc/loaded-scripts.bro scripts/policy/misc/loaded-scripts.bro
#close 2017-05-02-20-39-05 #close 2018-03-01-16-09-46

View file

@ -4,6 +4,7 @@
0.000000 MetaHookPost CallFunction(Analyzer::__disable_analyzer, <frame>, (Analyzer::ANALYZER_TCPSTATS)) -> <no result> 0.000000 MetaHookPost CallFunction(Analyzer::__disable_analyzer, <frame>, (Analyzer::ANALYZER_TCPSTATS)) -> <no result>
0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, <frame>, (Analyzer::ANALYZER_AYIYA, 5072/udp)) -> <no result> 0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, <frame>, (Analyzer::ANALYZER_AYIYA, 5072/udp)) -> <no result>
0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, <frame>, (Analyzer::ANALYZER_DCE_RPC, 135/tcp)) -> <no result> 0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, <frame>, (Analyzer::ANALYZER_DCE_RPC, 135/tcp)) -> <no result>
0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, <frame>, (Analyzer::ANALYZER_DHCP, 4011/udp)) -> <no result>
0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, <frame>, (Analyzer::ANALYZER_DHCP, 67/udp)) -> <no result> 0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, <frame>, (Analyzer::ANALYZER_DHCP, 67/udp)) -> <no result>
0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, <frame>, (Analyzer::ANALYZER_DHCP, 68/udp)) -> <no result> 0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, <frame>, (Analyzer::ANALYZER_DHCP, 68/udp)) -> <no result>
0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, <frame>, (Analyzer::ANALYZER_DNP3_TCP, 20000/tcp)) -> <no result> 0.000000 MetaHookPost CallFunction(Analyzer::__register_for_port, <frame>, (Analyzer::ANALYZER_DNP3_TCP, 20000/tcp)) -> <no result>
@ -66,6 +67,7 @@
0.000000 MetaHookPost CallFunction(Analyzer::disable_analyzer, <frame>, (Analyzer::ANALYZER_TCPSTATS)) -> <no result> 0.000000 MetaHookPost CallFunction(Analyzer::disable_analyzer, <frame>, (Analyzer::ANALYZER_TCPSTATS)) -> <no result>
0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, <frame>, (Analyzer::ANALYZER_AYIYA, 5072/udp)) -> <no result> 0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, <frame>, (Analyzer::ANALYZER_AYIYA, 5072/udp)) -> <no result>
0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, <frame>, (Analyzer::ANALYZER_DCE_RPC, 135/tcp)) -> <no result> 0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, <frame>, (Analyzer::ANALYZER_DCE_RPC, 135/tcp)) -> <no result>
0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, <frame>, (Analyzer::ANALYZER_DHCP, 4011/udp)) -> <no result>
0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, <frame>, (Analyzer::ANALYZER_DHCP, 67/udp)) -> <no result> 0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, <frame>, (Analyzer::ANALYZER_DHCP, 67/udp)) -> <no result>
0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, <frame>, (Analyzer::ANALYZER_DHCP, 68/udp)) -> <no result> 0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, <frame>, (Analyzer::ANALYZER_DHCP, 68/udp)) -> <no result>
0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, <frame>, (Analyzer::ANALYZER_DNP3_TCP, 20000/tcp)) -> <no result> 0.000000 MetaHookPost CallFunction(Analyzer::register_for_port, <frame>, (Analyzer::ANALYZER_DNP3_TCP, 20000/tcp)) -> <no result>
@ -256,7 +258,7 @@
0.000000 MetaHookPost CallFunction(Log::__create_stream, <frame>, (Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird])) -> <no result> 0.000000 MetaHookPost CallFunction(Log::__create_stream, <frame>, (Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird])) -> <no result>
0.000000 MetaHookPost CallFunction(Log::__create_stream, <frame>, (X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509])) -> <no result> 0.000000 MetaHookPost CallFunction(Log::__create_stream, <frame>, (X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509])) -> <no result>
0.000000 MetaHookPost CallFunction(Log::__create_stream, <frame>, (mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql])) -> <no result> 0.000000 MetaHookPost CallFunction(Log::__create_stream, <frame>, (mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql])) -> <no result>
0.000000 MetaHookPost CallFunction(Log::__write, <frame>, (PacketFilter::LOG, [ts=1516211213.330468, node=bro, filter=ip or not ip, init=T, success=T])) -> <no result> 0.000000 MetaHookPost CallFunction(Log::__write, <frame>, (PacketFilter::LOG, [ts=1519920860.516463, node=bro, filter=ip or not ip, init=T, success=T])) -> <no result>
0.000000 MetaHookPost CallFunction(Log::add_default_filter, <frame>, (Cluster::LOG)) -> <no result> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, <frame>, (Cluster::LOG)) -> <no result>
0.000000 MetaHookPost CallFunction(Log::add_default_filter, <frame>, (Communication::LOG)) -> <no result> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, <frame>, (Communication::LOG)) -> <no result>
0.000000 MetaHookPost CallFunction(Log::add_default_filter, <frame>, (Conn::LOG)) -> <no result> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, <frame>, (Conn::LOG)) -> <no result>
@ -429,7 +431,7 @@
0.000000 MetaHookPost CallFunction(Log::create_stream, <frame>, (Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird])) -> <no result> 0.000000 MetaHookPost CallFunction(Log::create_stream, <frame>, (Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird])) -> <no result>
0.000000 MetaHookPost CallFunction(Log::create_stream, <frame>, (X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509])) -> <no result> 0.000000 MetaHookPost CallFunction(Log::create_stream, <frame>, (X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509])) -> <no result>
0.000000 MetaHookPost CallFunction(Log::create_stream, <frame>, (mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql])) -> <no result> 0.000000 MetaHookPost CallFunction(Log::create_stream, <frame>, (mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql])) -> <no result>
0.000000 MetaHookPost CallFunction(Log::write, <frame>, (PacketFilter::LOG, [ts=1516211213.330468, node=bro, filter=ip or not ip, init=T, success=T])) -> <no result> 0.000000 MetaHookPost CallFunction(Log::write, <frame>, (PacketFilter::LOG, [ts=1519920860.516463, node=bro, filter=ip or not ip, init=T, success=T])) -> <no result>
0.000000 MetaHookPost CallFunction(NetControl::check_plugins, <frame>, ()) -> <no result> 0.000000 MetaHookPost CallFunction(NetControl::check_plugins, <frame>, ()) -> <no result>
0.000000 MetaHookPost CallFunction(NetControl::init, <null>, ()) -> <no result> 0.000000 MetaHookPost CallFunction(NetControl::init, <null>, ()) -> <no result>
0.000000 MetaHookPost CallFunction(Notice::want_pp, <frame>, ()) -> <no result> 0.000000 MetaHookPost CallFunction(Notice::want_pp, <frame>, ()) -> <no result>
@ -480,6 +482,7 @@
0.000000 MetaHookPost LoadFile(0, .<...>/Bro_DCE_RPC.events.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(0, .<...>/Bro_DCE_RPC.events.bif.bro) -> -1
0.000000 MetaHookPost LoadFile(0, .<...>/Bro_DCE_RPC.types.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(0, .<...>/Bro_DCE_RPC.types.bif.bro) -> -1
0.000000 MetaHookPost LoadFile(0, .<...>/Bro_DHCP.events.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(0, .<...>/Bro_DHCP.events.bif.bro) -> -1
0.000000 MetaHookPost LoadFile(0, .<...>/Bro_DHCP.types.bif.bro) -> -1
0.000000 MetaHookPost LoadFile(0, .<...>/Bro_DNP3.events.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(0, .<...>/Bro_DNP3.events.bif.bro) -> -1
0.000000 MetaHookPost LoadFile(0, .<...>/Bro_DNS.events.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(0, .<...>/Bro_DNS.events.bif.bro) -> -1
0.000000 MetaHookPost LoadFile(0, .<...>/Bro_FTP.events.bif.bro) -> -1 0.000000 MetaHookPost LoadFile(0, .<...>/Bro_FTP.events.bif.bro) -> -1
@ -782,6 +785,7 @@
0.000000 MetaHookPre CallFunction(Analyzer::__disable_analyzer, <frame>, (Analyzer::ANALYZER_TCPSTATS)) 0.000000 MetaHookPre CallFunction(Analyzer::__disable_analyzer, <frame>, (Analyzer::ANALYZER_TCPSTATS))
0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, <frame>, (Analyzer::ANALYZER_AYIYA, 5072/udp)) 0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, <frame>, (Analyzer::ANALYZER_AYIYA, 5072/udp))
0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, <frame>, (Analyzer::ANALYZER_DCE_RPC, 135/tcp)) 0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, <frame>, (Analyzer::ANALYZER_DCE_RPC, 135/tcp))
0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, <frame>, (Analyzer::ANALYZER_DHCP, 4011/udp))
0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, <frame>, (Analyzer::ANALYZER_DHCP, 67/udp)) 0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, <frame>, (Analyzer::ANALYZER_DHCP, 67/udp))
0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, <frame>, (Analyzer::ANALYZER_DHCP, 68/udp)) 0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, <frame>, (Analyzer::ANALYZER_DHCP, 68/udp))
0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, <frame>, (Analyzer::ANALYZER_DNP3_TCP, 20000/tcp)) 0.000000 MetaHookPre CallFunction(Analyzer::__register_for_port, <frame>, (Analyzer::ANALYZER_DNP3_TCP, 20000/tcp))
@ -844,6 +848,7 @@
0.000000 MetaHookPre CallFunction(Analyzer::disable_analyzer, <frame>, (Analyzer::ANALYZER_TCPSTATS)) 0.000000 MetaHookPre CallFunction(Analyzer::disable_analyzer, <frame>, (Analyzer::ANALYZER_TCPSTATS))
0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, <frame>, (Analyzer::ANALYZER_AYIYA, 5072/udp)) 0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, <frame>, (Analyzer::ANALYZER_AYIYA, 5072/udp))
0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, <frame>, (Analyzer::ANALYZER_DCE_RPC, 135/tcp)) 0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, <frame>, (Analyzer::ANALYZER_DCE_RPC, 135/tcp))
0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, <frame>, (Analyzer::ANALYZER_DHCP, 4011/udp))
0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, <frame>, (Analyzer::ANALYZER_DHCP, 67/udp)) 0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, <frame>, (Analyzer::ANALYZER_DHCP, 67/udp))
0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, <frame>, (Analyzer::ANALYZER_DHCP, 68/udp)) 0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, <frame>, (Analyzer::ANALYZER_DHCP, 68/udp))
0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, <frame>, (Analyzer::ANALYZER_DNP3_TCP, 20000/tcp)) 0.000000 MetaHookPre CallFunction(Analyzer::register_for_port, <frame>, (Analyzer::ANALYZER_DNP3_TCP, 20000/tcp))
@ -1034,7 +1039,7 @@
0.000000 MetaHookPre CallFunction(Log::__create_stream, <frame>, (Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, <frame>, (Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird]))
0.000000 MetaHookPre CallFunction(Log::__create_stream, <frame>, (X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, <frame>, (X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509]))
0.000000 MetaHookPre CallFunction(Log::__create_stream, <frame>, (mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql])) 0.000000 MetaHookPre CallFunction(Log::__create_stream, <frame>, (mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql]))
0.000000 MetaHookPre CallFunction(Log::__write, <frame>, (PacketFilter::LOG, [ts=1516211213.330468, node=bro, filter=ip or not ip, init=T, success=T])) 0.000000 MetaHookPre CallFunction(Log::__write, <frame>, (PacketFilter::LOG, [ts=1519920860.516463, node=bro, filter=ip or not ip, init=T, success=T]))
0.000000 MetaHookPre CallFunction(Log::add_default_filter, <frame>, (Cluster::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, <frame>, (Cluster::LOG))
0.000000 MetaHookPre CallFunction(Log::add_default_filter, <frame>, (Communication::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, <frame>, (Communication::LOG))
0.000000 MetaHookPre CallFunction(Log::add_default_filter, <frame>, (Conn::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, <frame>, (Conn::LOG))
@ -1207,7 +1212,7 @@
0.000000 MetaHookPre CallFunction(Log::create_stream, <frame>, (Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird])) 0.000000 MetaHookPre CallFunction(Log::create_stream, <frame>, (Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird]))
0.000000 MetaHookPre CallFunction(Log::create_stream, <frame>, (X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509])) 0.000000 MetaHookPre CallFunction(Log::create_stream, <frame>, (X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509]))
0.000000 MetaHookPre CallFunction(Log::create_stream, <frame>, (mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql])) 0.000000 MetaHookPre CallFunction(Log::create_stream, <frame>, (mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql]))
0.000000 MetaHookPre CallFunction(Log::write, <frame>, (PacketFilter::LOG, [ts=1516211213.330468, node=bro, filter=ip or not ip, init=T, success=T])) 0.000000 MetaHookPre CallFunction(Log::write, <frame>, (PacketFilter::LOG, [ts=1519920860.516463, node=bro, filter=ip or not ip, init=T, success=T]))
0.000000 MetaHookPre CallFunction(NetControl::check_plugins, <frame>, ()) 0.000000 MetaHookPre CallFunction(NetControl::check_plugins, <frame>, ())
0.000000 MetaHookPre CallFunction(NetControl::init, <null>, ()) 0.000000 MetaHookPre CallFunction(NetControl::init, <null>, ())
0.000000 MetaHookPre CallFunction(Notice::want_pp, <frame>, ()) 0.000000 MetaHookPre CallFunction(Notice::want_pp, <frame>, ())
@ -1258,6 +1263,7 @@
0.000000 MetaHookPre LoadFile(0, .<...>/Bro_DCE_RPC.events.bif.bro) 0.000000 MetaHookPre LoadFile(0, .<...>/Bro_DCE_RPC.events.bif.bro)
0.000000 MetaHookPre LoadFile(0, .<...>/Bro_DCE_RPC.types.bif.bro) 0.000000 MetaHookPre LoadFile(0, .<...>/Bro_DCE_RPC.types.bif.bro)
0.000000 MetaHookPre LoadFile(0, .<...>/Bro_DHCP.events.bif.bro) 0.000000 MetaHookPre LoadFile(0, .<...>/Bro_DHCP.events.bif.bro)
0.000000 MetaHookPre LoadFile(0, .<...>/Bro_DHCP.types.bif.bro)
0.000000 MetaHookPre LoadFile(0, .<...>/Bro_DNP3.events.bif.bro) 0.000000 MetaHookPre LoadFile(0, .<...>/Bro_DNP3.events.bif.bro)
0.000000 MetaHookPre LoadFile(0, .<...>/Bro_DNS.events.bif.bro) 0.000000 MetaHookPre LoadFile(0, .<...>/Bro_DNS.events.bif.bro)
0.000000 MetaHookPre LoadFile(0, .<...>/Bro_FTP.events.bif.bro) 0.000000 MetaHookPre LoadFile(0, .<...>/Bro_FTP.events.bif.bro)
@ -1560,6 +1566,7 @@
0.000000 | HookCallFunction Analyzer::__disable_analyzer(Analyzer::ANALYZER_TCPSTATS) 0.000000 | HookCallFunction Analyzer::__disable_analyzer(Analyzer::ANALYZER_TCPSTATS)
0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_AYIYA, 5072/udp) 0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_AYIYA, 5072/udp)
0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_DCE_RPC, 135/tcp) 0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_DCE_RPC, 135/tcp)
0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_DHCP, 4011/udp)
0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_DHCP, 67/udp) 0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_DHCP, 67/udp)
0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_DHCP, 68/udp) 0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_DHCP, 68/udp)
0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_DNP3_TCP, 20000/tcp) 0.000000 | HookCallFunction Analyzer::__register_for_port(Analyzer::ANALYZER_DNP3_TCP, 20000/tcp)
@ -1622,6 +1629,7 @@
0.000000 | HookCallFunction Analyzer::disable_analyzer(Analyzer::ANALYZER_TCPSTATS) 0.000000 | HookCallFunction Analyzer::disable_analyzer(Analyzer::ANALYZER_TCPSTATS)
0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_AYIYA, 5072/udp) 0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_AYIYA, 5072/udp)
0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_DCE_RPC, 135/tcp) 0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_DCE_RPC, 135/tcp)
0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_DHCP, 4011/udp)
0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_DHCP, 67/udp) 0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_DHCP, 67/udp)
0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_DHCP, 68/udp) 0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_DHCP, 68/udp)
0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_DNP3_TCP, 20000/tcp) 0.000000 | HookCallFunction Analyzer::register_for_port(Analyzer::ANALYZER_DNP3_TCP, 20000/tcp)
@ -1811,7 +1819,7 @@
0.000000 | HookCallFunction Log::__create_stream(Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird]) 0.000000 | HookCallFunction Log::__create_stream(Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird])
0.000000 | HookCallFunction Log::__create_stream(X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509]) 0.000000 | HookCallFunction Log::__create_stream(X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509])
0.000000 | HookCallFunction Log::__create_stream(mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql]) 0.000000 | HookCallFunction Log::__create_stream(mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql])
0.000000 | HookCallFunction Log::__write(PacketFilter::LOG, [ts=1516211213.330468, node=bro, filter=ip or not ip, init=T, success=T]) 0.000000 | HookCallFunction Log::__write(PacketFilter::LOG, [ts=1519920860.516463, node=bro, filter=ip or not ip, init=T, success=T])
0.000000 | HookCallFunction Log::add_default_filter(Cluster::LOG) 0.000000 | HookCallFunction Log::add_default_filter(Cluster::LOG)
0.000000 | HookCallFunction Log::add_default_filter(Communication::LOG) 0.000000 | HookCallFunction Log::add_default_filter(Communication::LOG)
0.000000 | HookCallFunction Log::add_default_filter(Conn::LOG) 0.000000 | HookCallFunction Log::add_default_filter(Conn::LOG)
@ -1984,7 +1992,7 @@
0.000000 | HookCallFunction Log::create_stream(Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird]) 0.000000 | HookCallFunction Log::create_stream(Weird::LOG, [columns=<no value description>, ev=Weird::log_weird, path=weird])
0.000000 | HookCallFunction Log::create_stream(X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509]) 0.000000 | HookCallFunction Log::create_stream(X509::LOG, [columns=<no value description>, ev=X509::log_x509, path=x509])
0.000000 | HookCallFunction Log::create_stream(mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql]) 0.000000 | HookCallFunction Log::create_stream(mysql::LOG, [columns=<no value description>, ev=MySQL::log_mysql, path=mysql])
0.000000 | HookCallFunction Log::write(PacketFilter::LOG, [ts=1516211213.330468, node=bro, filter=ip or not ip, init=T, success=T]) 0.000000 | HookCallFunction Log::write(PacketFilter::LOG, [ts=1519920860.516463, node=bro, filter=ip or not ip, init=T, success=T])
0.000000 | HookCallFunction NetControl::check_plugins() 0.000000 | HookCallFunction NetControl::check_plugins()
0.000000 | HookCallFunction NetControl::init() 0.000000 | HookCallFunction NetControl::init()
0.000000 | HookCallFunction Notice::want_pp() 0.000000 | HookCallFunction Notice::want_pp()
@ -2035,6 +2043,7 @@
0.000000 | HookLoadFile .<...>/Bro_DCE_RPC.events.bif.bro 0.000000 | HookLoadFile .<...>/Bro_DCE_RPC.events.bif.bro
0.000000 | HookLoadFile .<...>/Bro_DCE_RPC.types.bif.bro 0.000000 | HookLoadFile .<...>/Bro_DCE_RPC.types.bif.bro
0.000000 | HookLoadFile .<...>/Bro_DHCP.events.bif.bro 0.000000 | HookLoadFile .<...>/Bro_DHCP.events.bif.bro
0.000000 | HookLoadFile .<...>/Bro_DHCP.types.bif.bro
0.000000 | HookLoadFile .<...>/Bro_DNP3.events.bif.bro 0.000000 | HookLoadFile .<...>/Bro_DNP3.events.bif.bro
0.000000 | HookLoadFile .<...>/Bro_DNS.events.bif.bro 0.000000 | HookLoadFile .<...>/Bro_DNS.events.bif.bro
0.000000 | HookLoadFile .<...>/Bro_FTP.events.bif.bro 0.000000 | HookLoadFile .<...>/Bro_FTP.events.bif.bro
@ -2327,7 +2336,7 @@
0.000000 | HookLoadFile base<...>/x509 0.000000 | HookLoadFile base<...>/x509
0.000000 | HookLoadFile base<...>/xmpp 0.000000 | HookLoadFile base<...>/xmpp
0.000000 | HookLogInit packet_filter 1/1 {ts (time), node (string), filter (string), init (bool), success (bool)} 0.000000 | HookLogInit packet_filter 1/1 {ts (time), node (string), filter (string), init (bool), success (bool)}
0.000000 | HookLogWrite packet_filter [ts=1516211213.330468, node=bro, filter=ip or not ip, init=T, success=T] 0.000000 | HookLogWrite packet_filter [ts=1519920860.516463, node=bro, filter=ip or not ip, init=T, success=T]
0.000000 | HookQueueEvent NetControl::init() 0.000000 | HookQueueEvent NetControl::init()
0.000000 | HookQueueEvent bro_init() 0.000000 | HookQueueEvent bro_init()
0.000000 | HookQueueEvent filter_change_tracking() 0.000000 | HookQueueEvent filter_change_tracking()

View file

@ -3,8 +3,8 @@
#empty_field (empty) #empty_field (empty)
#unset_field - #unset_field -
#path dhcp #path dhcp
#open 2018-01-08-17-58-31 #open 2018-03-01-15-18-30
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p mac assigned_ip lease_time trans_id msg_type client_id server_id host_name subscriber_id agent_remote_id #fields ts uids client_addr server_addr mac host_name client_fqdn domain requested_addr assigned_addr lease_time client_message server_message msg_types duration
#types time string addr port addr port string addr interval count string string addr string string string #types time set[string] addr addr string string string string addr addr interval string string vector[string] interval
1102274184.387798 CHhAvVGS1DHFjwGM9 10.10.0.10 68 10.10.0.1 67 00:0a:28:00:fa:42 192.168.0.10 3600.000000 15633 DHCP_ACK - 10.10.0.1 (empty) -subID- 13 1102274184.387798 CHhAvVGS1DHFjwGM9 192.168.0.10 10.10.0.1 00:0a:28:00:fa:42 - - - - 192.168.0.10 3600.000000 - - ACK 0.000000
#close 2018-01-08-17-58-31 #close 2018-03-01-15-18-30

View file

@ -3,8 +3,10 @@
#empty_field (empty) #empty_field (empty)
#unset_field - #unset_field -
#path dhcp #path dhcp
#open 2016-07-13-16-15-58 #open 2018-03-01-15-19-24
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p mac assigned_ip lease_time trans_id #fields ts uids client_addr server_addr mac host_name client_fqdn domain requested_addr assigned_addr lease_time client_message server_message msg_types duration
#types time string addr port addr port string addr interval count #types time set[string] addr addr string string string string addr addr interval string string vector[string] interval
1370200444.371332 CtPZjS20MLrsMUOJi2 128.2.6.189 68 128.2.6.152 67 90:b1:1c:99:49:29 128.2.6.189 900.000000 1984 1370200447.422207 CHhAvVGS1DHFjwGM9 - - - btest.is.cool - - 128.2.6.189 - - - - INFORM 0.000000
#close 2016-07-13-16-15-58 1370200442.323173 CtPZjS20MLrsMUOJi2,CHhAvVGS1DHFjwGM9,C4J4Th3PJpwUYZZ6gc,ClEkJM2Vm5giqnMf4h 128.2.6.97 128.2.6.152 90:b1:1c:99:49:29 btest.is.cool - cmu.edu 128.2.6.189 128.2.6.189 900.000000 - requested address not available DISCOVER,OFFER,REQUEST,NAK,REQUEST,ACK,DECLINE 3.058797
1370200446.402928 CHhAvVGS1DHFjwGM9 - - - - - - - - - - - RELEASE 0.000000
#close 2018-03-01-15-19-24

View file

@ -3,8 +3,8 @@
#empty_field (empty) #empty_field (empty)
#unset_field - #unset_field -
#path dhcp #path dhcp
#open 2018-01-08-17-58-41 #open 2018-03-01-15-30-31
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p mac assigned_ip lease_time trans_id msg_type client_id server_id host_name subscriber_id agent_remote_id #fields ts uids client_addr server_addr mac host_name client_fqdn domain requested_addr assigned_addr lease_time client_message server_message msg_types duration
#types time string addr port addr port string addr interval count string string addr string string string #types time set[string] addr addr string string string string addr addr interval string string vector[string] interval
1102274184.317453 CHhAvVGS1DHFjwGM9 0.0.0.0 68 255.255.255.255 67 - - - 15633 DHCP_DISCOVER 00:0b:82:01:fc:42 - test0000 - - 1102274184.317453 CHhAvVGS1DHFjwGM9 - - 00:0b:82:01:fc:42 test0000 - - 208.67.222.222 - - - - DISCOVER 0.000000
#close 2018-01-08-17-58-41 #close 2018-03-01-15-30-31

View file

@ -0,0 +1,10 @@
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path dhcp
#open 2018-03-01-15-30-58
#fields ts uids client_addr server_addr mac host_name client_fqdn domain requested_addr assigned_addr lease_time client_message server_message msg_types duration circuit_id agent_remote_id subscriber_id
#types time set[string] addr addr string string string string addr addr interval string string vector[string] interval string string string
1102274184.387798 CHhAvVGS1DHFjwGM9 192.168.0.10 10.10.0.1 00:0a:28:00:fa:42 - - - - 192.168.0.10 3600.000000 - - ACK 0.000000 this is only a test... \x13 -subID-
#close 2018-03-01-15-30-58

View file

@ -3,8 +3,8 @@
#empty_field (empty) #empty_field (empty)
#unset_field - #unset_field -
#path dhcp #path dhcp
#open 2016-07-13-16-15-59 #open 2018-03-01-15-32-52
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p mac assigned_ip lease_time trans_id #fields ts uids client_addr server_addr mac host_name client_fqdn domain requested_addr assigned_addr lease_time client_message server_message msg_types duration
#types time string addr port addr port string addr interval count #types time set[string] addr addr string string string string addr addr interval string string vector[string] interval
1374432420.191205 CHhAvVGS1DHFjwGM9 128.2.6.122 68 128.2.6.152 67 90:b1:1c:99:49:29 128.2.6.122 0.000000 2754407505 1374432420.186878 CHhAvVGS1DHFjwGM9 128.2.6.122 - 90:b1:1c:99:49:29 - - - - - - - - INFORM,ACK 0.004327
#close 2016-07-13-16-15-59 #close 2018-03-01-15-32-52

View file

@ -1,11 +0,0 @@
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path known_devices
#open 2013-07-31-21-27-41
#fields ts mac dhcp_host_name
#types time string string
1370200443.344965 90:b1:1c:99:49:29 btest.is.cool
1374432420.186878 90:b1:1c:99:49:29 (empty)
#close 2013-07-31-21-27-41

View file

@ -0,0 +1,2 @@
# @TEST-EXEC: bro -r $TRACES/dhcp/dhcp_ack_subscriber_id_and_agent_remote_id.trace %INPUT protocols/dhcp/sub-opts
# @TEST-EXEC: btest-diff dhcp.log

View file

@ -1,8 +0,0 @@
# This tests that the known_devices log is created,
# that devices are logged by MAC address, and that
# the DHCP hostname is added, if available.
# @TEST-EXEC: bro -r $TRACES/dhcp/dhcp.trace -r $TRACES/dhcp/dhcp_inform.trace %INPUT
# @TEST-EXEC: btest-diff known_devices.log
@load policy/protocols/dhcp/known-devices-and-hostnames