Merge remote-tracking branch 'origin/topic/seth/dhcp-update'

* origin/topic/seth/dhcp-update:
  Rework to the DHCP analyzer.
  First step of DHCP analyzer rearchitecture.
  Add .btest scripts for dhck_ack and dhcp_discover messages verifying that new options are correctly reported in dhcp.log records.
  Extend DHCP protocol analyzer with new options.

BIT-1924 #merged

Additional changes:

* Removed known-hosts.bro as the only thing populating its table was
  the already-removed known-hosts-and-devices.bro.  So a
  known_devices.log will no longer be generated.

* In dhcp-options.pac, the process_relay_agent_inf_option had a memleak
  and also process_auto_proxy_config_option looked like it accessed one
  byte past the end of the available bytestring, so fixed those.
This commit is contained in:
Jon Siwek 2018-05-01 17:57:15 -05:00
commit 81133f3116
42 changed files with 1688 additions and 722 deletions

18
CHANGES
View file

@ -1,4 +1,22 @@
2.5-544 | 2018-05-01 17:57:15 -0500
* Rewrite the DHCP analyzer and accompanying script-layer API.
(Valerio G, Corelight)
* 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.bro and known-devices.bro
scripts since it's generally less relevant now with the updated log.
* Change include directory search order to better support --with-openssl.
(Johanna Amann)
2.5-535 | 2018-04-30 16:22:30 -0500 2.5-535 | 2018-04-30 16:22:30 -0500
* Improve how coverage unit tests handle name of build dir (Corelight) * Improve how coverage unit tests handle name of build dir (Corelight)

28
NEWS
View file

@ -149,6 +149,34 @@ New Functionality
Changed Functionality Changed Functionality
--------------------- ---------------------
- The DHCP analyzer and its script-layer interface have been rewritten.
- Supports more DHCP options than before.
- The DHCP log now represents DHCP sessions based on transaction ID
and works on Bro cluster deployments.
- Removed the policy/protocols/dhcp/known-devices-and-hostnames.bro
script since it's generally less relevant now with the updated log.
- Removed policy/misc/known-devices.bro script and thus
known_devices.log will no longer be created.
- Removed the base/protocols/dhcp/utils.bro script and thus the
'reverse_ip' function.
- Replaced all DHCP events with the single 'dhcp_message' event.
The list of removed events includes:
- dhcp_discover
- dhcp_offer
- dhcp_request
- dhcp_decline
- dhcp_ack
- dhcp_nak
- dhcp_release
- dhcp_inform
- The --with-binpac= configure option has changed to mean "path - The --with-binpac= configure option has changed to mean "path
to the binpac executable" instead of "path to binpac installation root". to the binpac executable" instead of "path to binpac installation root".

View file

@ -1 +1 @@
2.5-535 2.5-544

View file

@ -3285,24 +3285,151 @@ export {
module GLOBAL; module GLOBAL;
## A list of router addresses offered by a DHCP server. module DHCP;
export {
## 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_message
type dhcp_router_list: table[count] of addr; type DHCP::Addrs: vector of addr;
## A DHCP message. ## A DHCP message.
## ## .. bro:see:: dhcp_message
## .. bro:see:: dhcp_ack dhcp_decline dhcp_discover dhcp_inform dhcp_nak type DHCP::Msg: record {
## dhcp_offer dhcp_release dhcp_request
type dhcp_msg: record {
op: count; ##< Message OP code. 1 = BOOTREQUEST, 2 = BOOTREPLY op: count; ##< Message OP code. 1 = BOOTREQUEST, 2 = BOOTREPLY
m_type: count; ##< The type of DHCP message. m_type: count; ##< The type of DHCP message.
xid: count; ##< Transaction ID of a DHCP session. xid: count; ##< Transaction ID of a DHCP session.
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.
chaddr: string; ##< Client hardware address.
sname: string &default=""; ##< Server host name.
file_n: string &default=""; ##< Boot file name.
}; };
## DHCP Client Identifier (Option 61)
## .. bro:see:: dhcp_message
type DHCP::ClientID: record {
hwtype: count;
hwaddr: string;
};
## 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_message
type DHCP::SubOpt: record {
code: count;
value: string;
};
type DHCP::SubOpts: vector of DHCP::SubOpt;
type DHCP::Options: record {
## The ordered list of all DHCP option numbers.
options: index_vec &optional;
## Subnet Mask Value (option 1)
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;
## The DNS domain name of the client (option 15)
domain_name: string &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;
## Server address to allow clients to distinguish
## between lease offers. (option 54)
serv_addr: addr &optional;
## DHCP Parameter Request list (option 55)
param_list: index_vec &optional;
## Textual error message (option 56)
message: string &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)
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)
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;
## A DNS message. ## A DNS message.
## ##
## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl ## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl

View file

@ -4,17 +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] = "FORCERENEW", # RFC3203
[10] = "LEASEQUERY", # RFC4388
[11] = "LEASEUNASSIGNED", # RFC4388
[12] = "LEASEUNKNOWN", # RFC4388
[13] = "LEASEACTIVE", # RFC4388
[14] = "BULKLEASEQUERY", # RFC6926
[15] = "LEASEQUERYDONE", # RFC6926
[16] = "ACTIVELEASEQUERY", # RFC7724
[17] = "LEASEQUERYSTATUS", # RFC7724
[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 messages 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,21 +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
## so the client can tell the server why it rejected
## an address.
client_message: string &log &optional;
## Message typically accompanied with a DHCP_NAK to let
## the client know why it rejected the request.
server_message: string &log &optional;
## The DHCP message types seen by this DHCP transaction
msg_types: vector of string &log &default=string_vec();
## Duration of the DHCP "session" representing the
## 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);
@ -43,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
@ -53,27 +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_ack(c: connection, msg: dhcp_msg, mask: addr, router: dhcp_router_list, lease: interval, serv_addr: addr, host_name: string) &priority=5 # Setup the clusterized config that is needed to tie messages together on a cluster.
redef Cluster::worker2manager_events += /DHCP::aggregate_msgs/;
function join_data_expiration(t: table[count] of Info, idx: count): interval
{ {
local info: Info; local info = t[idx];
info$ts = network_time();
info$id = c$id;
info$uid = c$uid;
info$lease_time = lease;
info$trans_id = msg$xid;
if ( msg$h_addr != "" ) local now = network_time();
info$mac = msg$h_addr; # 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);
if ( reverse_ip(msg$yiaddr) != 0.0.0.0 ) # Go ahead and expire the data now that the log
info$assigned_ip = reverse_ip(msg$yiaddr); # entry has been written.
return 0secs;
}
else else
info$assigned_ip = c$id$orig_h;
c$dhcp = info;
}
event dhcp_ack(c: connection, msg: dhcp_msg, mask: addr, router: dhcp_router_list, lease: interval, serv_addr: addr, host_name: string) &priority=-5
{ {
Log::write(DHCP::LOG, c$dhcp); 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 )
log_info$lease_time = options$lease;
}
}
@endif
# Aggregate DHCP messages to the manager.
event dhcp_message(c: connection, is_orig: bool, msg: DHCP::Msg, options: DHCP::Options) &priority=-5
{
event DHCP::aggregate_msgs(network_time(), c$id, c$uid, is_orig, msg, options);
}
event bro_done() &priority=-5
{
# 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

@ -1,42 +0,0 @@
##! This script provides infrastructure for logging devices for which Bro has
##! 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
##! 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;
export {
## The known-hosts logging stream identifier.
redef enum Log::ID += { DEVICES_LOG };
## The record type which contains the column fields of the known-devices
## log.
type DevicesInfo: record {
## The timestamp at which the host was detected.
ts: time &log;
## The MAC address that was detected.
mac: string &log;
};
## The set of all known MAC addresses. It can accessed from other
## scripts to add, and check for, addresses seen in use.
##
## We maintain each entry for 24 hours by default so that the existence
## of individual addresses is logged each day.
global known_devices: set[string] &create_expire=1day &synchronized &redef;
## An event that can be handled to access the :bro:type:`Known::DevicesInfo`
## record as it is sent on to the logging framework.
global log_known_devices: event(rec: DevicesInfo);
}
event bro_init()
{
Log::create_stream(Known::DEVICES_LOG, [$columns=DevicesInfo, $ev=log_known_devices, $path="known_devices"]);
}

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_msg, req_addr: addr, serv_addr: addr, host_name: string)
{
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_msg, host_name: string)
{
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;
else if ( sub_opt$code == 2 )
DHCP::log_info$agent_remote_id = sub_opt$value;
else if ( sub_opt$code == 6 )
DHCP::log_info$subscriber_id = sub_opt$value;
}
}
}

View file

@ -48,7 +48,6 @@
@load misc/detect-traceroute/__load__.bro @load misc/detect-traceroute/__load__.bro
@load misc/detect-traceroute/main.bro @load misc/detect-traceroute/main.bro
# @load misc/dump-events.bro # @load misc/dump-events.bro
@load misc/known-devices.bro
@load misc/load-balancing.bro @load misc/load-balancing.bro
@load misc/loaded-scripts.bro @load misc/loaded-scripts.bro
@load misc/profiling.bro @load misc/profiling.bro
@ -60,7 +59,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

@ -110,9 +110,6 @@ RecordType* geo_location;
RecordType* entropy_test_result; RecordType* entropy_test_result;
TableType* dhcp_router_list;
RecordType* dhcp_msg;
RecordType* dns_msg; RecordType* dns_msg;
RecordType* dns_answer; RecordType* dns_answer;
RecordType* dns_soa; RecordType* dns_soa;
@ -426,9 +423,6 @@ void init_net_var()
entropy_test_result = internal_type("entropy_test_result")->AsRecordType(); entropy_test_result = internal_type("entropy_test_result")->AsRecordType();
dhcp_router_list = internal_type("dhcp_router_list")->AsTableType();
dhcp_msg = internal_type("dhcp_msg")->AsRecordType();
dns_msg = internal_type("dns_msg")->AsRecordType(); dns_msg = internal_type("dns_msg")->AsRecordType();
dns_answer = internal_type("dns_answer")->AsRecordType(); dns_answer = internal_type("dns_answer")->AsRecordType();
dns_soa = internal_type("dns_soa")->AsRecordType(); dns_soa = internal_type("dns_soa")->AsRecordType();

View file

@ -113,9 +113,6 @@ extern RecordType* geo_location;
extern RecordType* entropy_test_result; extern RecordType* entropy_test_result;
extern TableType* dhcp_router_list;
extern RecordType* dhcp_msg;
extern RecordType* dns_msg; extern RecordType* dns_msg;
extern RecordType* dns_answer; extern RecordType* dns_answer;
extern RecordType* dns_soa; extern RecordType* dns_soa;

View file

@ -6,5 +6,6 @@ include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DI
bro_plugin_begin(Bro DHCP) bro_plugin_begin(Bro DHCP)
bro_plugin_cc(DHCP.cc Plugin.cc) bro_plugin_cc(DHCP.cc Plugin.cc)
bro_plugin_bif(events.bif) bro_plugin_bif(events.bif)
bro_plugin_pac(dhcp.pac dhcp-protocol.pac dhcp-analyzer.pac) bro_plugin_bif(types.bif)
bro_plugin_pac(dhcp.pac dhcp-protocol.pac dhcp-analyzer.pac dhcp-options.pac)
bro_plugin_end() bro_plugin_end()

View file

@ -1,6 +1,7 @@
#include "DHCP.h" #include "DHCP.h"
#include "events.bif.h" #include "events.bif.h"
#include "types.bif.h"
using namespace analyzer::dhcp; using namespace analyzer::dhcp;
@ -24,5 +25,14 @@ void DHCP_Analyzer::DeliverPacket(int len, const u_char* data,
bool orig, uint64 seq, const IP_Hdr* ip, int caplen) bool orig, uint64 seq, const IP_Hdr* ip, int caplen)
{ {
Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen);
try
{
interp->NewData(orig, data, data + len); interp->NewData(orig, data, data + len);
} }
catch ( const binpac::Exception& e )
{
ProtocolViolation(fmt("Binpac exception: %s", e.c_msg()));
}
}

View file

@ -1,227 +1,44 @@
connection DHCP_Conn(bro_analyzer: BroAnalyzer) {
upflow = DHCP_Flow(true);
downflow = DHCP_Flow(false);
};
flow DHCP_Flow(is_orig: bool) {
datagram = DHCP_Message withcontext(connection, this);
refine flow DHCP_Flow += {
%member{ %member{
BroVal dhcp_msg_val_; RecordVal* options;
VectorVal* all_options;
%} %}
%init{ %init{
dhcp_msg_val_ = 0; options = nullptr;
all_options = nullptr;
%} %}
%cleanup{ %cleanup{
Unref(dhcp_msg_val_); Unref(options);
dhcp_msg_val_ = 0; options = nullptr;
Unref(all_options);
all_options = nullptr;
%} %}
function get_dhcp_msgtype(options: DHCP_Option[]): uint8 function init_options(): bool
%{ %{
vector<DHCP_Option*>::const_iterator ptr; if ( ! options )
uint8 type = 0;
// Leave the for loop if the message type is found.
bool parsed = false;
for ( ptr = options->begin();
ptr != options->end() && ! (*ptr)->last(); ++ptr )
{ {
// We use a switch for future expandability. options = new RecordVal(BifType::Record::DHCP::Options);
switch ( (*ptr)->code() ) { all_options = new VectorVal(index_vec);
case MSG_TYPE_OPTION: options->Assign(0, all_options->Ref());
type = (*ptr)->info()->msg_type();
parsed = true;
break;
}
if ( parsed )
break;
}
if ( type == 0 )
connection()->bro_analyzer()->ProtocolViolation("no DHCP message type option");
return type;
%}
function parse_request(options: DHCP_Option[], type: uint8): bool
%{
vector<DHCP_Option*>::const_iterator ptr;
// Requested IP address to the server.
::uint32 req_addr = 0, serv_addr = 0;
StringVal* host_name = 0;
for ( ptr = options->begin(); ptr != options->end() && ! (*ptr)->last(); ++ptr )
{
switch ( (*ptr)->code() )
{
case REQ_IP_OPTION:
req_addr = htonl((*ptr)->info()->req_addr());
break;
case SERV_ID_OPTION:
serv_addr = htonl((*ptr)->info()->serv_addr());
break;
case HOST_NAME_OPTION:
Unref(host_name);
host_name = new StringVal((*ptr)->info()->host_name().length(),
(const char*) (*ptr)->info()->host_name().begin());
break;
}
}
if ( host_name == 0 )
host_name = 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);
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);
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);
break;
default:
Unref(host_name);
break;
} }
return true; return true;
%} %}
function parse_reply(options: DHCP_Option[], type: uint8): bool function create_options(code: uint8): bool
%{ %{
vector<DHCP_Option*>::const_iterator ptr; init_options();
// RFC 1533 allows a list of router addresses. if ( code != 255 )
TableVal* router_list = 0; all_options->Assign(all_options->Size(),
new Val(code, TYPE_COUNT));
::uint32 subnet_mask = 0, serv_addr = 0;
uint32 lease = 0;
StringVal* host_name = 0;
for ( ptr = options->begin();
ptr != options->end() && ! (*ptr)->last(); ++ptr )
{
switch ( (*ptr)->code() )
{
case SUBNET_OPTION:
subnet_mask = htonl((*ptr)->info()->mask());
break;
case ROUTER_OPTION:
// Let's hope there aren't multiple
// such options.
Unref(router_list);
router_list = new TableVal(dhcp_router_list);
{
int num_routers = (*ptr)->info()->router_list()->size();
for ( int i = 0; i < num_routers; ++i )
{
vector<uint32>* rlist = (*ptr)->info()->router_list();
uint32 raddr = (*rlist)[i];
::uint32 tmp_addr;
tmp_addr = htonl(raddr);
// index starting from 1
Val* index = new Val(i + 1, TYPE_COUNT);
router_list->Assign(index, new AddrVal(tmp_addr));
Unref(index);
}
}
break;
case LEASE_OPTION:
lease = (*ptr)->info()->lease();
break;
case SERV_ID_OPTION:
serv_addr = htonl((*ptr)->info()->serv_addr());
break;
case HOST_NAME_OPTION:
Unref(host_name);
host_name = new StringVal((*ptr)->info()->host_name().length(),
(const char*) (*ptr)->info()->host_name().begin());
break;
}
}
if ( host_name == 0 )
host_name = new StringVal("");
switch ( type )
{
case DHCPOFFER:
if ( ! router_list )
router_list = new TableVal(dhcp_router_list);
BifEvent::generate_dhcp_offer(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
dhcp_msg_val_->Ref(), new AddrVal(subnet_mask),
router_list, lease, new AddrVal(serv_addr), host_name);
break;
case DHCPACK:
if ( ! router_list )
router_list = new TableVal(dhcp_router_list);
BifEvent::generate_dhcp_ack(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
dhcp_msg_val_->Ref(), new AddrVal(subnet_mask),
router_list, lease, new AddrVal(serv_addr), host_name);
break;
case DHCPNAK:
Unref(router_list);
BifEvent::generate_dhcp_nak(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
dhcp_msg_val_->Ref(), host_name);
break;
default:
Unref(router_list);
Unref(host_name);
break;
}
return true; return true;
%} %}
function process_dhcp_message(msg: DHCP_Message): bool function process_dhcp_message(msg: DHCP_Message): bool
@ -235,52 +52,67 @@ flow DHCP_Flow(is_orig: bool) {
return false; return false;
} }
Unref(dhcp_msg_val_); if ( dhcp_message )
std::string mac_str = fmt_mac(${msg.chaddr}.data(), ${msg.chaddr}.length());
RecordVal* r = new RecordVal(dhcp_msg);
r->Assign(0, new Val(${msg.op}, TYPE_COUNT));
r->Assign(1, new Val(${msg.type}, TYPE_COUNT));
r->Assign(2, new Val(${msg.xid}, TYPE_COUNT));
r->Assign(3, new StringVal(mac_str));
r->Assign(4, new AddrVal(${msg.ciaddr}));
r->Assign(5, new AddrVal(${msg.yiaddr}));
dhcp_msg_val_ = r;
switch ( ${msg.op} )
{ {
case BOOTREQUEST: // presumably from client to server std::string mac_str = fmt_mac(${msg.chaddr}.data(), ${msg.chaddr}.length());
if ( ${msg.type} == DHCPDISCOVER || double secs = static_cast<double>(${msg.secs});
${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 auto dhcp_msg_val = new RecordVal(BifType::Record::DHCP::Msg);
if ( ${msg.type} == DHCPOFFER || dhcp_msg_val->Assign(0, new Val(${msg.op}, TYPE_COUNT));
${msg.type} == DHCPACK || dhcp_msg_val->Assign(1, new Val(${msg.type}, TYPE_COUNT));
${msg.type} == DHCPNAK ) dhcp_msg_val->Assign(2, new Val(${msg.xid}, TYPE_COUNT));
parse_reply(${msg.options}, ${msg.type}); dhcp_msg_val->Assign(3, new Val(secs, TYPE_INTERVAL));
else dhcp_msg_val->Assign(4, new Val(${msg.flags}, TYPE_COUNT));
connection()->bro_analyzer()->ProtocolViolation(fmt("unknown DHCP message type option for BOOTREPLY (%d)", dhcp_msg_val->Assign(5, new AddrVal(htonl(${msg.ciaddr})));
${msg.type})); 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));
break; int last_non_null = 0;
default: for ( int i = 0; i < ${msg.sname}.length(); ++i )
connection()->bro_analyzer()->ProtocolViolation(fmt("unknown DHCP message op code (%d). Known codes: 1=BOOTREQUEST, 2=BOOTREPLY", {
${msg.op})); if ( *(${msg.sname}.begin() + i) != 0 )
break; 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())));
init_options();
BifEvent::generate_dhcp_message(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
${msg.is_orig},
dhcp_msg_val,
options);
options = nullptr;
Unref(all_options);
all_options = nullptr;
}
// A single message reaching this point is enough to confirm the protocol
// because it's not uncommon to see a single DHCP message
// on a "connection".
// The binpac analyzer would have thrown an error before this point
// if there was a problem too (and subsequently called ProtocolViolation).
connection()->bro_analyzer()->ProtocolConfirmation(); connection()->bro_analyzer()->ProtocolConfirmation();
return true; return true;
%} %}
}; };
@ -288,3 +120,8 @@ flow DHCP_Flow(is_orig: bool) {
refine typeattr DHCP_Message += &let { refine typeattr DHCP_Message += &let {
proc_dhcp_message = $context.flow.process_dhcp_message(this); proc_dhcp_message = $context.flow.process_dhcp_message(this);
}; };
refine typeattr Option += &let {
proc_create_options = $context.flow.create_options(code);
};

View file

@ -0,0 +1,711 @@
##############################
# SUBNET OPTION
##############################
let SUBNET_OPTION = 1;
# Parse the option
refine casetype OptionValue += {
SUBNET_OPTION -> subnet : uint32;
};
refine flow DHCP_Flow += {
function process_subnet_option(v: OptionValue): bool
%{
${context.flow}->options->Assign(1, new AddrVal(htonl(${v.subnet})));
return true;
%}
};
refine typeattr Option += &let {
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);
};
##############################
# HOST NAME OPTION
##############################
let HOST_NAME_OPTION = 12;
# Parse the option
refine casetype OptionValue += {
HOST_NAME_OPTION -> host_name : bytestring &length=length;
};
refine flow DHCP_Flow += {
function process_host_name_option(v: OptionValue): bool
%{
${context.flow}->options->Assign(4, new StringVal(${v.host_name}.length(),
reinterpret_cast<const char*>(${v.host_name}.begin())));
return true;
%}
};
refine typeattr Option += &let {
proc_host_name_option = $context.flow.process_host_name_option(info.value) &if(code==HOST_NAME_OPTION);
};
##############################
# DOMAIN NAME OPTION
##############################
let DOMAIN_NAME_OPTION = 15;
# Parse the option
refine casetype OptionValue += {
DOMAIN_NAME_OPTION -> domain_name : bytestring &length=length;
};
refine flow DHCP_Flow += {
function process_domain_name_option(v: OptionValue): bool
%{
int last_non_null = 0;
for ( int i = 0; i < ${v.domain_name}.length(); ++i )
{
if ( *(${v.domain_name}.begin() + i ) != 0 )
last_non_null = i;
}
${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;
%}
};
refine typeattr Option += &let {
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);
};
##############################
# LEASE_OPTION OPTION
##############################
let LEASE_OPTION = 51;
# Parse the option
refine casetype OptionValue += {
LEASE_OPTION -> lease : uint32;
};
refine flow DHCP_Flow += {
function process_lease_option(v: OptionValue): bool
%{
double lease = static_cast<double>(${v.lease});
${context.flow}->options->Assign(11, new Val(lease, TYPE_INTERVAL));
return true;
%}
};
refine typeattr Option += &let {
proc_lease_option = $context.flow.process_lease_option(info.value) &if(code==LEASE_OPTION);
};
##############################
# SERV_ID_OPTION OPTION
##############################
let SERV_ID_OPTION = 54;
# Parse the option
refine casetype OptionValue += {
SERV_ID_OPTION -> serv_addr : uint32;
};
refine flow DHCP_Flow += {
function process_serv_id_option(v: OptionValue): bool
%{
${context.flow}->options->Assign(12, new AddrVal(htonl(${v.serv_addr})));
return true;
%}
};
refine typeattr Option += &let {
proc_serv_id_option = $context.flow.process_serv_id_option(info.value) &if(code==SERV_ID_OPTION);
};
##############################
# PAR_REQ_LIST OPTION
##############################
let PAR_REQ_LIST_OPTION = 55;
# Parse the option
refine casetype OptionValue += {
PAR_REQ_LIST_OPTION -> par_req_list : uint8[length];
};
refine flow DHCP_Flow += {
function process_par_req_list_option(v: OptionValue): bool
%{
VectorVal* params = new VectorVal(index_vec);
int num_parms = ${v.par_req_list}->size();
vector<uint8>* plist = ${v.par_req_list};
for ( int i = 0; i < num_parms; ++i )
{
uint8 param = (*plist)[i];
params->Assign(i, new Val(param, TYPE_COUNT));
}
${context.flow}->options->Assign(13, params);
return true;
%}
};
refine typeattr Option += &let {
proc_par_req_list_option = $context.flow.process_par_req_list_option(info.value) &if(code==PAR_REQ_LIST_OPTION);
};
##############################
# MESSAGE OPTION
##############################
let MESSAGE_OPTION = 56;
# Parse the option
refine casetype OptionValue += {
MESSAGE_OPTION -> message : bytestring &length=length;
};
refine flow DHCP_Flow += {
function process_message_option(v: OptionValue): bool
%{
${context.flow}->options->Assign(14, new StringVal(${v.message}.length(),
reinterpret_cast<const char*>(${v.message}.begin())));
return true;
%}
};
refine typeattr Option += &let {
proc_message_option = $context.flow.process_message_option(info.value) &if(code==MESSAGE_OPTION);
};
##############################
# MAX MESSAGE SIZE OPTION
##############################
let MAX_MESSAGE_SIZE_OPTION = 57;
# Parse the option
refine casetype OptionValue += {
MAX_MESSAGE_SIZE_OPTION -> max_msg_size : uint16;
};
refine flow DHCP_Flow += {
function process_max_message_size_option(v: OptionValue): bool
%{
${context.flow}->options->Assign(15, new Val(${v.max_msg_size}, TYPE_COUNT));
return true;
%}
};
refine typeattr Option += &let {
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);
};
##############################
# CLIENT_ID_OPTION OPTION
##############################
let CLIENT_ID_OPTION = 61;
type Client_Identifier(length: uint8) = record {
hwtype : uint8;
hwaddr : bytestring &length = length - 1;
};
# Parse the option
refine casetype OptionValue += {
CLIENT_ID_OPTION -> client_id : Client_Identifier(length);
};
refine flow DHCP_Flow += {
function process_client_id_option(v: OptionValue): bool
%{
RecordVal* client_id = new RecordVal(BifType::Record::DHCP::ClientID);
client_id->Assign(0, new Val(${v.client_id.hwtype}, TYPE_COUNT));
client_id->Assign(1, new StringVal(fmt_mac(${v.client_id.hwaddr}.begin(), ${v.client_id.hwaddr}.length())));
${context.flow}->options->Assign(19, client_id);
return true;
%}
};
refine typeattr Option += &let {
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
##############################
let RELAY_AGENT_INF_OPTION = 82;
type Relay_Agent_SubOption(tot_len: uint8) = record {
code : uint8;
length : uint8;
value : bytestring &length = length;
} &let {
sum_len: uint8 = $context.flow.get_dhcp_sumlen(length + 2);
last: bool = (sum_len == tot_len);
};
# Parse the option
refine casetype OptionValue += {
RELAY_AGENT_INF_OPTION -> relay_agent_inf : Relay_Agent_SubOption(length)[] &until($element.last);
};
refine flow DHCP_Flow += {
%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
%{
VectorVal* relay_agent_sub_opt = new VectorVal(BifType::Vector::DHCP::SubOpts);
uint16 i = 0;
for ( auto ptrsubopt = ${v.relay_agent_inf}->begin();
ptrsubopt != ${v.relay_agent_inf}->end(); ++ptrsubopt )
{
auto r = new RecordVal(BifType::Record::DHCP::SubOpt);
r->Assign(0, new Val((*ptrsubopt)->code(), TYPE_COUNT));
r->Assign(1, bytestring_to_val((*ptrsubopt)->value()));
relay_agent_sub_opt->Assign(i, r);
++i;
}
${context.flow}->options->Assign(22, relay_agent_sub_opt);
return true;
%}
};
refine typeattr Option += &let {
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();
if ( string_len == 0 )
{
${context.flow}->options->Assign(24, new StringVal(0, ""));
return true;
}
const char* last_char = reinterpret_cast<const char*>(${v.auto_proxy_config}.begin() + string_len - 1);
bool has_newline = *last_char == '\x0a';
if ( has_newline )
--string_len;
${context.flow}->options->Assign(24, new StringVal(string_len,
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

@ -3,96 +3,33 @@
# Refer to RFC 2131 for op types. # Refer to RFC 2131 for op types.
enum OP_type { enum OP_type {
BOOTREQUEST = 1, BOOTREQUEST = 1,
BOOTREPLY = 2, BOOTREPLY = 2
}; };
# Refer to RFC 1533 for option types. let MSG_TYPE_OPTION = 53;
# The option types are by no means complete.
# Anyone can add a new option type in RFC 1533 to be parsed here.
enum OPTION_type {
SUBNET_OPTION = 1,
ROUTER_OPTION = 3,
HOST_NAME_OPTION = 12,
REQ_IP_OPTION = 50,
LEASE_OPTION = 51,
MSG_TYPE_OPTION = 53,
SERV_ID_OPTION = 54, # Server address, actually :)
END_OPTION = 255,
};
# Refer to RFC 1533 for message types (with option = 53). type OptionValue(code: uint8, length: uint8) = case code of {
enum DHCP_message_type { # This is extended in dhcp-options.pac
DHCPDISCOVER = 1,
DHCPOFFER = 2,
DHCPREQUEST = 3,
DHCPDECLINE = 4,
DHCPACK = 5,
DHCPNAK = 6,
DHCPRELEASE = 7,
DHCPINFORM = 8,
};
type Option_Info(code: uint8) = record {
length : uint8;
value : case code of {
SUBNET_OPTION -> mask : uint32;
ROUTER_OPTION -> router_list : uint32[length/4];
REQ_IP_OPTION -> req_addr : uint32;
LEASE_OPTION -> lease : uint32;
MSG_TYPE_OPTION -> msg_type : uint8; MSG_TYPE_OPTION -> msg_type : uint8;
SERV_ID_OPTION -> serv_addr : uint32;
HOST_NAME_OPTION-> host_name : bytestring &length = length;
default -> other : bytestring &length = length; default -> other : bytestring &length = length;
}; };
type OptionValueWrapper(code: uint8) = record {
length : uint8;
value : OptionValue(code, length);
}; };
type DHCP_Option = record { type Option = record {
code : uint8; code : uint8;
data : case code of { data : case code of {
0, 255 -> none : empty; 0, 255 -> none : empty;
default -> info : Option_Info(code); default -> info : OptionValueWrapper(code);
}; };
} &let { } &let {
last: bool = (code == 255); # Mark the end of a list of options last = (code == 255); # Mark the end of a list of options
}; };
# Message format according to RFC 2131 type DHCP_Message(is_orig: bool) = record {
#
# 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3
# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | op (1) | htype (1) | hlen (1) | hops (1) |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | xid (4) |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | secs (2) | flags (2) |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | ciaddr (4) |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | yiaddr (4) |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | siaddr (4) |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | giaddr (4) |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | |
# | chaddr (16) |
# / /
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | |
# | sname (64) |
# / /
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | |
# | file (128) |
# / /
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | |
# | options (variable) |
# / /
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
type DHCP_Message = record {
op : uint8; op : uint8;
htype : uint8; htype : uint8;
hlen : uint8; hlen : uint8;
@ -106,13 +43,33 @@ type DHCP_Message = 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;
options : Option[] &until($element.last);
options : DHCP_Option[] &until($element.last);
} &let { } &let {
type : uint8 = $context.flow.get_dhcp_msgtype(options); type = $context.flow.get_dhcp_msgtype(options);
} &byteorder = bigendian; } &byteorder = bigendian;
refine flow DHCP_Flow += {
function get_dhcp_msgtype(options: Option[]): uint8
%{
uint8 type = 0;
for ( auto ptr = options->begin();
ptr != options->end() && ! (*ptr)->last(); ++ptr )
{
if ( (*ptr)->code() == MSG_TYPE_OPTION )
{
type = (*ptr)->info()->value()->msg_type();
break;
}
}
if ( type == 0 )
connection()->bro_analyzer()->ProtocolViolation("no DHCP message type option");
return type;
%}
};

View file

@ -2,6 +2,7 @@
%include bro.pac %include bro.pac
%extern{ %extern{
#include "types.bif.h"
#include "events.bif.h" #include "events.bif.h"
%} %}
@ -10,5 +11,15 @@ analyzer DHCP withcontext {
flow: DHCP_Flow; flow: DHCP_Flow;
}; };
connection DHCP_Conn(bro_analyzer: BroAnalyzer) {
upflow = DHCP_Flow(true);
downflow = DHCP_Flow(false);
};
flow DHCP_Flow(is_orig: bool) {
datagram = DHCP_Message(is_orig) withcontext(connection, this);
};
%include dhcp-protocol.pac %include dhcp-protocol.pac
%include dhcp-analyzer.pac %include dhcp-analyzer.pac
%include dhcp-options.pac

View file

@ -1,164 +1,12 @@
## Generated for DHCP messages of type *DHCPDISCOVER* (client broadcast to locate ## Generated for all DHCP messages.
## available servers).
## ##
## c: The connection record describing the underlying UDP flow. ## c: The connection record describing the underlying UDP flow.
## ##
## msg: The parsed type-independent part of the DHCP message. ## is_orig: Indicate if the message came in a packet from the
## originator/client of the udp flow or the responder/server.
## ##
## req_addr: The specific address requested by the client. ## msg: The parsed type-independent part of the DHCP message. The message
## type is indicated in this record.
## ##
## host_name: The value of the host name option, if specified by the client. ## options: The full set of supported and parsed DHCP options.
## event dhcp_message%(c: connection, is_orig: bool, msg: DHCP::Msg, options: DHCP::Options%);
## .. 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%);
## 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_router_list, 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.
##
## .. 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%);
## 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.
##
## .. 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_router_list, 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.
##
## .. 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

@ -0,0 +1,9 @@
module DHCP;
type Msg: record;
type Addrs: vector;
type SubOpt: record;
type SubOpts: vector;
type ClientFQDN: record;
type ClientID: 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 2018-02-05-22-27-42 #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
@ -68,6 +68,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
@ -173,4 +174,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 2018-02-05-22-27-42 #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 2018-02-05-22-27-48 #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
@ -68,6 +68,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
@ -275,7 +276,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
@ -365,4 +365,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 2018-02-05-22-27-48 #close 2018-03-01-16-09-46

View file

@ -15,7 +15,6 @@ http
intel intel
irc irc
known_certs known_certs
known_devices
known_hosts known_hosts
known_modbus known_modbus
known_services known_services

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>
@ -258,7 +260,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=1517966765.39294, 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>, (Config::LOG)) -> <no result> 0.000000 MetaHookPost CallFunction(Log::add_default_filter, <frame>, (Config::LOG)) -> <no result>
@ -435,7 +437,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=1517966765.39294, 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>
@ -488,6 +490,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
@ -795,6 +798,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))
@ -857,6 +861,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))
@ -1049,7 +1054,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=1517966765.39294, 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>, (Config::LOG)) 0.000000 MetaHookPre CallFunction(Log::add_default_filter, <frame>, (Config::LOG))
@ -1226,7 +1231,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=1517966765.39294, 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>, ())
@ -1279,6 +1284,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)
@ -1586,6 +1592,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)
@ -1648,6 +1655,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)
@ -1839,7 +1847,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=1517966765.39294, 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(Config::LOG) 0.000000 | HookCallFunction Log::add_default_filter(Config::LOG)
@ -2016,7 +2024,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=1517966765.39294, 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()
@ -2069,6 +2077,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
@ -2366,7 +2375,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=1517966765.392940, 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

@ -0,0 +1,10 @@
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path dhcp
#open 2018-03-01-15-18-30
#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 set[string] addr addr string string string string addr addr interval string string vector[string] interval
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-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

@ -0,0 +1,10 @@
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path dhcp
#open 2018-03-01-15-30-31
#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 set[string] addr addr string string string string addr addr interval string string vector[string] interval
1102274184.317453 CHhAvVGS1DHFjwGM9 - - 00:0b:82:01:fc:42 test0000 - - 208.67.222.222 - - - - DISCOVER 0.000000
#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,6 @@
# This tests that DHCP leases are logged in dhcp.log
# The trace has a message of each DHCP message type,
# but only one lease should show up in the logs.
# @TEST-EXEC: bro -r $TRACES/dhcp/dhcp_ack_subscriber_id_and_agent_remote_id.trace %INPUT
# @TEST-EXEC: btest-diff dhcp.log

View file

@ -0,0 +1,6 @@
# This tests that DHCP leases are logged in dhcp.log
# The trace has a message of each DHCP message type,
# but only one lease should show up in the logs.
# @TEST-EXEC: bro -r $TRACES/dhcp/dhcp_discover_param_req_and_client_id.trace %INPUT
# @TEST-EXEC: btest-diff dhcp.log

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