DHCP Stream
The DHCP Stream page shows a real-time feed of DHCP packets as they are processed, with filtering, protocol badges, and expandable event details.
The stream connects to the server via WebSocket (wss://<host>/api/ws/dhcp-events) and displays each DHCP event as a row in a live-updating table. It is the primary tool for real-time packet inspection and troubleshooting.
Connecting to the Stream
Section titled “Connecting to the Stream”The stream opens a WebSocket connection automatically when you navigate to the page.
Authentication uses your current session token, passed as a query parameter on the WebSocket URL. The connection is subject to the server’s maximum WebSocket connection limit (configured in config.yaml under api.websocket.max_connections).
If the connection drops, the stream pauses and shows a reconnection indicator. The page attempts automatic reconnection at a fixed 5-second interval; there is no exponential backoff.
Stream Controls
Section titled “Stream Controls”The toolbar at the top of the stream provides play/pause, clear, and filter controls.
Play / Pause
Section titled “Play / Pause”Click the play/pause button to temporarily stop new events from appearing. Events continue to arrive over the WebSocket but are buffered. When you resume, buffered events appear in order. Use pause when you need to examine a specific event without the table scrolling.
Click clear to remove all events from the current display. This does not affect the WebSocket connection or ClickHouse storage — it only clears the in-browser buffer.
Event Counter
Section titled “Event Counter”The toolbar shows the running event count and how many events have been dropped from the local buffer (Events: <n> / Dropped: <n>). There is no per-second rate indicator; high sustained event volumes (above ~500/s) may cause the browser to use more memory.
Note: Devices with an active Deny action do not appear in the stream. Denied devices have their event generation suppressed entirely — no WebSocket events are broadcast and no ClickHouse records are written. If you expect to see a device but it is missing, check whether it has been denied on the Firewall Decisions or Actions Log page.
Stream Columns
Section titled “Stream Columns”Each row in the stream table represents a single DHCP packet with the following columns.
| Column | Description | Example |
|---|---|---|
| Time | When the packet was processed (server time) | 2026-03-07T14:23:01Z |
| Type | DHCP message type | DISCOVER, OFFER, REQUEST, ACK, SOLICIT, ADVERTISE |
| Proto | DHCPv4 or DHCPv6 badge | v4 or v6 |
| XID | Transaction ID | 0xa1b2c3d4 |
| Client MAC | Client hardware address | aa:bb:cc:dd:ee:ff |
| Source IP | IP address the packet came from | 192.168.1.100 |
| Hostname | Client-provided hostname (Option 12) | laptop-jsmith |
| Vendor | Client vendor class (Option 60) | MSFT 5.0 |
| Requested IP | The IP the client asked for (DHCPv4 Option 50 / DHCPv6 IA address) | 192.168.1.100 |
| Server IP | Server identifier (siaddr / Option 54) | 192.168.1.1 |
| Lease | Lease time / valid lifetime | 3600s |
| Mark | NFTables mark assigned to this packet | 0x0a1b2c3d |
| Rule | Description of the rule that matched (defaults to unknown when no rule matched) | Default printer pool |
| Opts | Compact summary of additional DHCP options | t82, t82.1 |
These columns are fixed; the GUI does not currently provide a column-visibility toggle.
Protocol Badges
Section titled “Protocol Badges”Each event displays a protocol badge indicating whether it is a DHCPv4 or DHCPv6 packet.
- v4 (blue badge): Standard DHCPv4 packet using the DORA (Discover-Offer-Request-Ack) flow
- v6 (purple badge): DHCPv6 packet using Solicit-Advertise-Request-Reply or other v6 message types
DHCPv6 events include additional fields visible in the expanded detail view: Client DUID, Server DUID, DUID Type, IA Type, IA Addresses, Delegated Prefix, and Preferred/Valid Lifetimes.
Filtering the Stream
Section titled “Filtering the Stream”Filters control which events appear in the stream. They are evaluated SERVER-side — the GUI sends an update_filters message to the WebSocket, the server validates the filter set, and only matching events are pushed to your stream.
Filter Structure
Section titled “Filter Structure”Filters use a rule-based system with AND/OR logic. Each rule specifies a field, an operator, and a value:
{ "logic": "AND", "rules": [ { "field": "message_type", "operator": "eq", "value": "DISCOVER" }, { "field": "vendor_class", "operator": "contains", "value": "MSFT" } ]}Available Filter Fields
Section titled “Available Filter Fields”| Field | Type | Description |
|---|---|---|
client_mac | string | Client hardware address |
source_mac | string | Source MAC from Ethernet frame |
source_ip | string | Source IP address |
dest_ip | string | Destination IP address |
dest_mac | string | Destination MAC address |
message_type | string | DHCP message type name |
hostname | string | Client hostname (Option 12) |
vendor_class | string | Vendor class identifier (Option 60) |
client_identifier | string | Client identifier (Option 61) |
xid | string | Transaction ID |
server_ip | string | DHCP server IP |
relay_ip | string | Relay agent IP (giaddr) |
gateway_ip | string | Gateway IP |
client_ip | string | Client IP (ciaddr) |
your_ip | string | Your IP (yiaddr — assigned IP) |
requested_ip | string | Requested IP (Option 50) |
matched_rule | string | Name of the matched config rule |
lease_time | numeric | Lease time in seconds |
renewal_time | numeric | Renewal time (T1) in seconds |
rebinding_time | numeric | Rebinding time (T2) in seconds |
mark | numeric | NFTables mark value |
processing_time_ms | numeric | Processing time in milliseconds |
option_count | numeric | Number of DHCP options present |
op_code | string | DHCP opcode (BOOTREQUEST/BOOTREPLY) |
hw_type | string | Hardware type |
source_port | numeric | UDP source port |
dest_port | numeric | UDP destination port |
dhcp_options.<CODE> | string | Any DHCP option by code number (e.g., dhcp_options.82) |
Filter Operators
Section titled “Filter Operators”| Operator | Code | Works With | Example |
|---|---|---|---|
| Equals | eq | All types | message_type eq DISCOVER |
| Not equals | ne | All types | vendor_class ne "" |
| Contains | contains | Strings | hostname contains laptop |
| Starts with | startswith | Strings | client_mac startswith aa:bb |
| Ends with | endswith | Strings | client_mac endswith ee:ff |
| Regex | regex | Strings | hostname regex ^srv-\d+ |
| Greater than | gt | Numerics | lease_time gt 3600 |
| Greater or equal | gte | Numerics | mark gte 256 |
| Less than | lt | Numerics | processing_time_ms lt 1.0 |
| Less or equal | lte | Numerics | option_count lte 10 |
| In | in | All types | message_type in [DISCOVER, REQUEST] |
| Not in | not_in | All types | message_type not_in [OFFER, ACK] |
Combining Filters
Section titled “Combining Filters”Use AND logic to require all rules to match. Use OR logic to match any rule. You can nest groups for complex conditions:
AND: - message_type eq DISCOVER - OR: - vendor_class contains MSFT - vendor_class contains dhcpcdSaving and Loading Filters
Section titled “Saving and Loading Filters”Filters are saved per-user in the dhcp_stream_filters table. You can name and save your current filter set, then load it later from the filter dropdown. Saved filters persist across sessions.
To manage saved filters, use the filter menu in the toolbar. You can create, rename, and delete saved filters from there.
Event Details
Section titled “Event Details”Click any row to expand it and see the full packet details.
The expanded view shows all DHCP fields including options that are not displayed in the table columns. Key sections in the detail view:
- Packet Header: OpCode, hardware type, hop count, transaction ID, seconds elapsed, flags
- Addresses: Client IP, Your IP, Server IP, Gateway IP, Client MAC
- DHCP Options: Full list of options with code number, name, and decoded value
- Network Layer: Source/destination IP, source/destination port, source/destination MAC
- Processing: Mark assigned, matched rule, processing time
- DHCPv6 Fields (v6 only): Client DUID, Server DUID, DUID type, IA type, IAID, IA addresses, prefixes, lifetimes, T1/T2 timers, FQDN flags
Performance in High-Traffic Environments
Section titled “Performance in High-Traffic Environments”The stream is designed for real-time monitoring but browser performance degrades at very high event rates.
At sustained rates above 1000 events/second, consider these practices:
- Apply filters to reduce the number of displayed events. Filter to a specific MAC, message type, or relay IP
- Pause the stream when investigating a specific event to prevent the table from scrolling
- Clear periodically to release browser memory if running the stream for extended periods
- Use the events API (
GET /api/events) for historical analysis instead of streaming large time windows
The WebSocket connection applies server-side rate limiting (configured as events_per_second with a burst multiplier in config.yaml). Events exceeding the rate limit are dropped from the stream but are still stored in ClickHouse.
Stream shows no events? Verify the processor is running, NFQueue is active (
sudo nft list table inet dhcp_inspection | grep queue), and there is DHCP traffic on the network. Check the WebSocket connection status indicator in the toolbar.