mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Rework to the DHCP analyzer.
Highlights: - Reduced all DHCP events into a single dhcp_message event. (removed legacy events since they weren't widely used anyway) - Support many more DHCP options. - DHCP log is completely reworked and now represents DHCP sessions based on the transaction ID (and works on clusters). - Removed the known-devices-and-hostnames script since it's generally less relevant now with the updated log.
This commit is contained in:
parent
c2f35920fd
commit
e76b56ce53
28 changed files with 1234 additions and 732 deletions
|
@ -4,27 +4,186 @@
|
|||
module DHCP;
|
||||
|
||||
export {
|
||||
|
||||
## Types of DHCP messages. See :rfc:`1533`.
|
||||
## Types of DHCP messages. See :rfc:`1533`, :rfc:`3203`,
|
||||
## :rfc:`4388`, :rfc:`6926`, and :rfc:`7724`.
|
||||
const message_types = {
|
||||
[1] = "DHCP_DISCOVER",
|
||||
[2] = "DHCP_OFFER",
|
||||
[3] = "DHCP_REQUEST",
|
||||
[4] = "DHCP_DECLINE",
|
||||
[5] = "DHCP_ACK",
|
||||
[6] = "DHCP_NAK",
|
||||
[7] = "DHCP_RELEASE",
|
||||
[8] = "DHCP_INFORM",
|
||||
[9] = "DHCP_FORCERENEW",
|
||||
[10] = "DHCP_LEASEQUERY",
|
||||
[11] = "DHCP_LEASEUNASSIGNED",
|
||||
[12] = "DHCP_DHCPLEASEUNKNOWN",
|
||||
[13] = "DHCP_LEASEACTIVE",
|
||||
[14] = "DHCP_BULKLEASEQUERY",
|
||||
[15] = "DHCP_LEASEQUERYDONE",
|
||||
[16] = "DHCP_ACTIVELEASEQUERY",
|
||||
[17] = "DHCP_LEASEQUERYSTATUS",
|
||||
[18] = "DHCP_TLS",
|
||||
[1] = "DISCOVER",
|
||||
[2] = "OFFER",
|
||||
[3] = "REQUEST",
|
||||
[4] = "DECLINE",
|
||||
[5] = "ACK",
|
||||
[6] = "NAK",
|
||||
[7] = "RELEASE",
|
||||
[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); };
|
||||
|
||||
## 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); };
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
signature dhcp_cookie {
|
||||
ip-proto == udp
|
||||
payload /^.*\x63\x82\x53\x63/
|
||||
payload /^.{236}\x63\x82\x53\x63/
|
||||
enable "dhcp"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
##! Analyzes DHCP traffic in order to log DHCP leases given to clients.
|
||||
##! This script ignores large swaths of the protocol, since it is rather
|
||||
##! noisy on most networks, and focuses on the end-result: assigned leases.
|
||||
##!
|
||||
##! If you'd like to track known DHCP devices and to log the hostname
|
||||
##! supplied by the client, see
|
||||
##! :doc:`/scripts/policy/protocols/dhcp/known-devices-and-hostnames.bro`.
|
||||
##! Analyze DHCP traffic and provide a log that is organized around
|
||||
##! the idea of a DHCP "conversation" defined by messaes exchanged within
|
||||
##! a relatively short period of time using the same transaction ID.
|
||||
##! The log will have information from clients and servers to give a more
|
||||
##! complete picture of what happened.
|
||||
|
||||
@load ./utils.bro
|
||||
@load base/frameworks/cluster
|
||||
@load ./consts
|
||||
|
||||
module DHCP;
|
||||
|
||||
|
@ -17,34 +16,81 @@ export {
|
|||
type Info: record {
|
||||
## The earliest time at which a DHCP message over the
|
||||
## associated connection is observed.
|
||||
ts: time &log;
|
||||
## A unique identifier of the connection over which DHCP is
|
||||
## occurring.
|
||||
uid: string &log;
|
||||
## The connection's 4-tuple of endpoint addresses/ports.
|
||||
id: conn_id &log;
|
||||
ts: time &log;
|
||||
|
||||
## A series of unique identifiers of the connections over which
|
||||
## DHCP is occurring. This behavior with multiple connections is
|
||||
## unique to DHCP because of the way it uses broadcast packets
|
||||
## 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.
|
||||
mac: string &log &optional;
|
||||
## Client's actual assigned IP address.
|
||||
assigned_ip: addr &log &optional;
|
||||
mac: string &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.
|
||||
lease_time: interval &log &optional;
|
||||
## A random number chosen by the client for this transaction.
|
||||
trans_id: count &log;
|
||||
## the message type
|
||||
msg_type: string &log &optional;
|
||||
## client ID
|
||||
client_id: string &log &optional;
|
||||
## the server ID
|
||||
server_id: addr &log &optional;
|
||||
## the host name
|
||||
host_name: string &log &optional;
|
||||
## the subscriber id (if present)
|
||||
subscriber_id: string &log &optional;
|
||||
## the agent remote id (if present)
|
||||
agent_remote_id: string &log &optional;
|
||||
lease_time: interval &log &optional;
|
||||
|
||||
## 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
|
||||
## record as it is sent on to the logging framework.
|
||||
global log_dhcp: event(rec: Info);
|
||||
|
@ -55,8 +101,13 @@ redef record connection += {
|
|||
dhcp: Info &optional;
|
||||
};
|
||||
|
||||
redef record Info += {
|
||||
last_message_ts: time &optional;
|
||||
};
|
||||
|
||||
# 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 };
|
||||
|
||||
event bro_init() &priority=5
|
||||
|
@ -65,54 +116,144 @@ event bro_init() &priority=5
|
|||
Analyzer::register_for_ports(Analyzer::ANALYZER_DHCP, ports);
|
||||
}
|
||||
|
||||
event dhcp_message(c: connection, is_orig: bool, msg: DHCP::Msg, options: DHCP::Options) &priority=-5
|
||||
# Setup the clusterized config that is needed to tie messages together on a cluster.
|
||||
redef Cluster::worker2manager_events += /DHCP::aggregate_msgs/;
|
||||
|
||||
function join_data_expiration(t: table[count] of Info, idx: count): interval
|
||||
{
|
||||
if ( msg$m_type == 5 ) # DHCP_ACK
|
||||
local info = t[idx];
|
||||
|
||||
local now = network_time();
|
||||
# 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() )
|
||||
{
|
||||
local info = Info($ts = network_time(),
|
||||
$id = c$id,
|
||||
$uid = c$uid,
|
||||
$trans_id = msg$xid);
|
||||
Log::write(LOG, info);
|
||||
|
||||
if ( msg$h_addr != "" )
|
||||
info$mac = msg$h_addr;
|
||||
# Go ahead and expire the data now that the log
|
||||
# entry has been written.
|
||||
return 0secs;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 5secs;
|
||||
}
|
||||
}
|
||||
|
||||
if ( reverse_ip(msg$yiaddr) != 0.0.0.0 )
|
||||
info$assigned_ip = reverse_ip(msg$yiaddr);
|
||||
# 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
|
||||
info$assigned_ip = c$id$orig_h;
|
||||
log_info$server_message = options$message;
|
||||
}
|
||||
|
||||
if ( options?$lease )
|
||||
info$lease_time = options$lease;
|
||||
# Update the last message time so that we can do some data
|
||||
# expiration handling.
|
||||
log_info$last_message_ts = ts;
|
||||
|
||||
if ( options?$sub_opt )
|
||||
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 )
|
||||
{
|
||||
for ( param in options$sub_opt )
|
||||
{
|
||||
local sub_opt = options$sub_opt[param];
|
||||
|
||||
#if ( sub_opt$code == 1 )
|
||||
# {
|
||||
# print fmt("Relay Agent Information:");
|
||||
# print fmt( "sub option: code=%d circuit id=%s",sub_opt$code,sub_opt$value );
|
||||
# }
|
||||
|
||||
if ( sub_opt$code == 2 )
|
||||
info$agent_remote_id = bytestring_to_hexstr(sub_opt$value);
|
||||
|
||||
if ( sub_opt$code == 6 )
|
||||
info$subscriber_id = (sub_opt$value);
|
||||
}
|
||||
log_info$server_addr = id$resp_h;
|
||||
}
|
||||
|
||||
c$dhcp = info;
|
||||
# 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
|
||||
{
|
||||
if ( msg$m_type == 5 ) # DHCP_ACK
|
||||
{
|
||||
Log::write(DHCP::LOG, c$dhcp);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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]));
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue