mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 22:58:20 +00:00
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:
commit
81133f3116
42 changed files with 1688 additions and 722 deletions
18
CHANGES
18
CHANGES
|
@ -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
28
NEWS
|
@ -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".
|
||||||
|
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
2.5-535
|
2.5-544
|
||||||
|
|
|
@ -3285,24 +3285,151 @@ export {
|
||||||
|
|
||||||
module GLOBAL;
|
module GLOBAL;
|
||||||
|
|
||||||
## A list of router addresses offered by a DHCP server.
|
module DHCP;
|
||||||
##
|
|
||||||
## .. bro:see:: dhcp_ack dhcp_offer
|
|
||||||
type dhcp_router_list: table[count] of addr;
|
|
||||||
|
|
||||||
## A DHCP message.
|
export {
|
||||||
##
|
## A list of addresses offered by a DHCP server. Could be routers,
|
||||||
## .. bro:see:: dhcp_ack dhcp_decline dhcp_discover dhcp_inform dhcp_nak
|
## DNS servers, or other.
|
||||||
## dhcp_offer dhcp_release dhcp_request
|
##
|
||||||
type dhcp_msg: record {
|
## .. bro:see:: dhcp_message
|
||||||
|
type DHCP::Addrs: vector of addr;
|
||||||
|
|
||||||
|
## A DHCP message.
|
||||||
|
## .. bro:see:: dhcp_message
|
||||||
|
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
|
||||||
|
|
|
@ -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); };
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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]));
|
|
||||||
}
|
|
||||||
|
|
|
@ -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"]);
|
|
||||||
}
|
|
|
@ -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]);
|
|
||||||
}
|
|
||||||
}
|
|
21
scripts/policy/protocols/dhcp/msg-orig.bro
Normal file
21
scripts/policy/protocols/dhcp/msg-orig.bro
Normal 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;
|
||||||
|
}
|
63
scripts/policy/protocols/dhcp/software.bro
Normal file
63
scripts/policy/protocols/dhcp/software.bro
Normal 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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
45
scripts/policy/protocols/dhcp/sub-opts.bro
Normal file
45
scripts/policy/protocols/dhcp/sub-opts.bro
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
711
src/analyzer/protocol/dhcp/dhcp-options.pac
Normal file
711
src/analyzer/protocol/dhcp/dhcp-options.pac
Normal 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);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
@ -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 DHCP_Option = record {
|
type OptionValueWrapper(code: uint8) = record {
|
||||||
|
length : uint8;
|
||||||
|
value : OptionValue(code, length);
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
%}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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%);
|
|
||||||
|
|
||||||
|
|
9
src/analyzer/protocol/dhcp/types.bif
Normal file
9
src/analyzer/protocol/dhcp/types.bif
Normal 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;
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
Binary file not shown.
Binary file not shown.
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
Loading…
Add table
Add a link
Reference in a new issue