PCAP Integration
Relevant source files
The following files were used as context for generating this wiki page:
Purpose and Scope
This document describes eCapture's PCAP-NG file generation capabilities, which enable network packet capture and storage in a format compatible with Wireshark and other network analysis tools. The PCAP integration captures both encrypted network traffic and the TLS/SSL decryption keys required to decrypt it, storing them together in a single PCAP-NG file with Decryption Secrets Blocks (DSB).
For information about other output formats, see Text Output Mode and TLS Key Logging. For details on the underlying packet capture mechanism, see Network Connection Tracking.
Overview
eCapture's PCAP integration operates in pcap or pcapng mode, which differs fundamentally from text mode by capturing complete network packets rather than just plaintext content. This mode combines three data sources into a unified PCAP-NG file:
- Network packets captured via TC (Traffic Control) eBPF classifiers on ingress/egress
- TLS master secrets extracted via uprobe hooks on SSL/TLS functions
- Connection metadata including process information (PID, UID, command name)
The resulting PCAP-NG file can be opened in Wireshark with automatic decryption of TLS traffic using the embedded master secrets.
PCAP Integration Architecture
Sources: user/module/probe_openssl.go:137-148, user/module/probe_openssl.go:287-296, README.md:173-187
Activation and Configuration
Command Line Usage
PCAP mode is activated using the -m pcap or -m pcapng flag with the tls or gotls modules. Required parameters include:
| Parameter | Description | Default Value |
|---|---|---|
-m pcap or -m pcapng | Activates PCAP mode | N/A (required) |
--pcapfile | Output file path | ecapture_openssl.pcapng |
-i | Network interface to capture | N/A (required) |
| PCAP filter expression | Optional BPF filter | None |
Example command:
sudo ecapture tls -m pcap -i eth0 --pcapfile=capture.pcapng tcp port 443Mode Selection Implementation
Sources: user/module/probe_openssl.go:127-154, user/config/iconfig.go:73-79, cli/cmd/root.go:249-296
Configuration Structure
The PCAP mode is configured through OpensslConfig:
OpensslConfig.Model = "pcap" or "pcapng"
OpensslConfig.PcapFile = output file path
OpensslConfig.Ifname = network interface name
OpensslConfig.PcapFilter = optional BPF filter expressionThis configuration triggers initialization of:
tcPacketsChan: Buffered channel (capacity 2048) for packet queueingtcPackets: Slice buffer (capacity 256) for batch writingpcapngFilename: Absolute path to output file
Sources: user/module/probe_openssl.go:137-148
PCAP-NG File Format
File Structure
eCapture generates PCAP-NG (Next Generation) files, which extend the classic PCAP format with richer metadata. The file structure consists of:
- Section Header Block (SHB): File identification and byte order
- Interface Description Block (IDB): Network interface metadata
- Decryption Secrets Block (DSB): TLS master secrets for decryption
- Enhanced Packet Block (EPB): Individual packet data with timestamps
PCAP-NG Block Structure
Sources: user/module/probe_openssl.go:558-565, user/module/probe_openssl.go:625-632
Enhanced Packet Block (EPB) Content
Each captured packet is stored as an EPB with:
- Interface ID: Links to the IDB (typically 0)
- Timestamp: Nanosecond precision (boot time + monotonic clock)
- Captured packet length: Actual bytes captured
- Original packet length: Length on wire (may exceed captured if truncated)
- Packet data: Raw Ethernet frame including:
- Ethernet header (14 bytes)
- IP header (IPv4 or IPv6)
- Transport header (TCP/UDP)
- Application payload (encrypted or decrypted)
The packet data comes from TC eBPF programs that capture the complete network frame at ingress/egress points.
Sources: user/module/probe_openssl.go:747-750
Decryption Secrets Block (DSB)
Purpose and Format
The DSB is a PCAP-NG block type that stores TLS decryption keys, enabling Wireshark to automatically decrypt captured TLS traffic. eCapture embeds DSB blocks containing master secrets in the SSLKEYLOGFILE format used by browsers and other TLS tools.
DSB Data Format
DSB blocks contain TLS secrets in the standard key log format:
CLIENT_RANDOM <client_random_hex> <master_secret_hex>
CLIENT_HANDSHAKE_TRAFFIC_SECRET <client_random_hex> <secret_hex>
SERVER_HANDSHAKE_TRAFFIC_SECRET <client_random_hex> <secret_hex>
CLIENT_TRAFFIC_SECRET_0 <client_random_hex> <secret_hex>
SERVER_TRAFFIC_SECRET_0 <client_random_hex> <secret_hex>
EXPORTER_SECRET <client_random_hex> <secret_hex>For TLS 1.2, only CLIENT_RANDOM is written. For TLS 1.3, multiple traffic secrets are derived and written.
Master Secret Extraction and DSB Writing
Sources: user/module/probe_openssl.go:482-575, user/module/probe_openssl.go:577-642
Implementation Details
TLS 1.2 Master Secret
For TLS 1.2, the master secret is captured directly from the SSL structure:
- Uprobe on
SSL_do_handshakecaptures the SSL context - Navigate to
s3->tmp.new_cipherto get cipher suite - Read
session->master_key(48 bytes) - Read
session->client_random(32 bytes) - Format:
CLIENT_RANDOM <32 hex bytes> <48 hex bytes>
TLS 1.3 Traffic Secrets
For TLS 1.3, multiple secrets are extracted and derived:
- Capture
handshake_secret,handshake_traffic_hashfrom SSL structure - Use HKDF to derive:
client_handshake_traffic_secret= HKDF-Expand-Label(handshake_secret, "c hs traffic", handshake_traffic_hash, hash_len)server_handshake_traffic_secret= HKDF-Expand-Label(handshake_secret, "s hs traffic", handshake_traffic_hash, hash_len)
- Capture
client_app_traffic_secret,server_app_traffic_secret,exporter_master_secretdirectly - Write all six secret types to DSB
The HKDF expansion is performed in user space using the captured hash algorithm (SHA256 or SHA384 based on cipher suite).
Sources: user/module/probe_openssl.go:502-551, pkg/util/hkdf/hkdf.go
Null Secret Detection
eCapture validates that captured secrets are not null (all zeros) before writing to DSB. This prevents corruption of the keylog:
- For TLS 1.2: Check if all 48 bytes of
master_keyare zero - For TLS 1.3: Check if all traffic secrets are zero (5 different secrets)
- If all secrets are null, the event is dropped
Sources: user/module/probe_openssl.go:644-731
Deduplication
Master secrets are deduplicated using a map[string]bool keyed by the hex-encoded ClientRandom:
ClientRandom (32 bytes) -> hex string (64 characters) -> map keyIf a ClientRandom already exists in the map, the duplicate secret is not written. This prevents the same TLS session from writing multiple identical DSB blocks.
Sources: user/module/probe_openssl.go:483-489, user/module/probe_openssl.go:578-584
TC Packet Capture Integration
Traffic Control (TC) eBPF Programs
PCAP mode relies on TC eBPF classifiers attached to network interfaces for packet capture. Unlike uprobes that capture plaintext at the application layer, TC programs capture complete network packets including encrypted payloads.
TC Classifier Attachment Points
Sources: user/module/probe_openssl.go:303-307
TcSkbEvent Structure
Each captured packet generates a TcSkbEvent containing:
| Field | Type | Description |
|---|---|---|
Pid | uint32 | Process ID that sent/received packet |
Tid | uint32 | Thread ID |
Uid | uint32 | User ID |
Gid | uint32 | Group ID |
Comm | [16]byte | Command name (process) |
SAddr | [16]byte | Source IP address (IPv4/IPv6) |
DAddr | [16]byte | Destination IP address |
Sport | uint16 | Source port |
Dport | uint16 | Destination port |
PacketLen | uint32 | Total packet length |
Payload | []byte | Packet data (Ethernet frame) |
Direction | uint8 | 0=egress, 1=ingress |
The complete Ethernet frame is captured, including headers and encrypted payload.
Sources: user/event/event_tc.go
BPF Filter Integration
When a PCAP filter expression is provided (e.g., tcp port 443), it is compiled into eBPF instructions and patched into the TC classifier programs at load time:
- Parse filter expression using libpcap syntax
- Compile to classic BPF instructions
- Convert to eBPF instructions
- Patch into TC programs using
InstructionPatchers
This filtering occurs in kernel space, reducing the volume of events sent to user space.
Sources: user/module/probe_openssl.go:303-307
Packet Processing Pipeline
Event Flow from TC to File
Packet Capture Pipeline
Sources: user/module/probe_openssl.go:747-750, user/module/probe_tc.go
TcPacket Construction
The dumpTcSkb method converts TcSkbEvent into TcPacket structures:
- Timestamp conversion: Convert kernel monotonic time to wall clock time
timestamp_ns = boot_time + skb_event.timestamp_ns
- Packet data extraction: Copy Ethernet frame from event payload
- Metadata attachment: Include PID, command, tuple information
- Enqueue: Send to
tcPacketsChanfor buffered processing
The TcPacket structure holds:
- Timestamp (nanosecond precision)
- Packet data (Ethernet frame bytes)
- Connection information (for correlation with uprobes)
Sources: user/module/probe_tc.go
Batch Writing
Packets are written to the PCAP-NG file in batches for performance:
- Consumer goroutine reads from
tcPacketsChan - Accumulates packets in
tcPacketsslice (up to 256) - When slice is full or timeout occurs, calls
savePcapng savePcapngacquires lock and writes all packets as EPB blocks- Flushes writer to disk every 2 seconds
This batching reduces system call overhead and improves throughput.
Sources: user/module/probe_tc.go
File Writer Implementation
PcapNG Writer Initialization
eCapture uses the gopacket/pcapgo library for PCAP-NG file generation:
Writer: *pcapgo.NgWriter
File: *os.File opened with O_CREATE | O_WRONLY | O_TRUNC
Interface: pcapgo.NgInterface with LinkType, SnapLen, Name, DescriptionInitialization sequence:
- Create/truncate output file
- Create
NgWriterwith file handle - Write Section Header Block (SHB)
- Write Interface Description Block (IDB)
- Set up periodic flush timer (2 seconds)
Sources: user/module/probe_tc.go
DSB Writing
Decryption secrets are written via savePcapngSslKeyLog:
- Format master secrets as TLS Key Log lines in
masterKeyBuffer - Call
NgWriter.WriteDecryptionSecretsBlock:- SecretsType:
pcapgo.DSB_SECRETS_TYPE_TLS(0x544c534b) - SecretsData: Key log formatted bytes
- SecretsType:
- Clear
masterKeyBufferfor next batch
DSB blocks can appear anywhere in the file, interleaved with EPB blocks. Wireshark processes all DSB blocks to build its decryption key table.
Sources: user/module/probe_openssl.go:558-565
EPB Writing
Each packet is written as an Enhanced Packet Block:
CaptureInfo: gopacket.CaptureInfo {
Timestamp: time.Unix(0, timestamp_ns)
CaptureLength: len(packet_data)
Length: len(packet_data)
InterfaceIndex: 0
}The NgWriter.WritePacket method handles EPB block formatting, including:
- Block type and length fields
- Interface ID
- Timestamp (high/low 32-bit split)
- Captured and original lengths
- Packet data
- Padding to 32-bit boundary
- Block total length trailer
Sources: user/module/probe_tc.go
Periodic Flushing
To ensure data is written to disk even with infrequent packets:
- Start ticker goroutine with 2-second interval
- On each tick, acquire lock and flush writer
- Log packet count statistics
- Continue until context cancellation
This prevents data loss if the program is terminated.
Sources: user/module/probe_tc.go
Process and Connection Correlation
PID/FD to Socket Mapping
To correlate network packets (captured at TC layer) with TLS plaintext (captured at SSL layer), eCapture maintains bidirectional mappings:
Connection Tracking Architecture
Sources: user/module/probe_openssl.go:398-480
Connection Lifecycle
Creation: When a connection is established (detected via kprobe on
tcp_connectorsys_connect):- Generate 4-tuple:
SrcIP:SrcPort-DstIP:DstPort - Map PID+FD ->
- Map sock ->
- Generate 4-tuple:
Usage: When SSL data is captured (via uprobe on
SSL_read/SSL_write):- Lookup tuple and sock by PID+FD
- Attach tuple to
SSLDataEvent - Event processor uses tuple to correlate with TC packets
Destruction: When socket is closed (detected via kprobe on
tcp_destroy_sock):- Remove PID+FD -> ConnInfo mapping
- Remove sock -> PID+FD mapping
- Delayed deletion (3 seconds) to allow in-flight events to complete
This correlation enables Wireshark to display:
- Which process generated each packet
- Which user owns the process
- Command name for the process
Sources: user/module/probe_openssl.go:398-462
Wireshark Integration
Opening PCAP-NG Files
To view captured traffic in Wireshark:
Direct open:
wireshark ecapture.pcapng- TLS traffic is automatically decrypted using embedded DSB blocks
- No additional configuration needed
Manual keylog: If DSB is not embedded, use
Edit -> Preferences -> Protocols -> TLS -> (Pre)-Master-Secret log filenameLive capture: While eCapture is running, Wireshark can open the file for live viewing (file is flushed every 2 seconds)
Display Filters
Useful Wireshark filters for eCapture PCAP-NG files:
| Filter | Purpose |
|---|---|
http | HTTP/1.x decrypted requests/responses |
http2 | HTTP/2 decrypted frames |
http3 | HTTP/3 QUIC decrypted streams |
tls.handshake.type == 1 | TLS ClientHello messages |
frame.comment | Packets with comments (PID/Comm) |
Sources: README.md:189-230
Protocol Hierarchy
The PCAP-NG file contains complete protocol stacks:
Ethernet II
└─ IPv4 or IPv6
└─ TCP or UDP
└─ TLS 1.2/1.3
└─ HTTP/1.1, HTTP/2, or HTTP/3 (QUIC)Wireshark automatically dissects all layers and displays decrypted application data when DSB blocks are present.
Performance Considerations
Buffer Sizing
| Buffer | Size | Purpose |
|---|---|---|
tcPacketsChan | 2048 packets | Asynchronous producer/consumer buffering |
tcPackets slice | 256 packets | Batch writing to reduce system calls |
| Per-CPU map | Configurable (default 1024 * PAGE_SIZE) | eBPF event buffer size |
Larger buffers reduce packet loss under high traffic but increase memory usage.
Sources: user/module/probe_openssl.go:137-148, cli/cmd/root.go:143
Packet Loss Scenarios
- eBPF map overflow: If per-CPU map fills, events are dropped in kernel
- Channel overflow: If
tcPacketsChanfills (2048 packets), blocking may occur - Processing latency: If user space cannot keep up with kernel event rate
The system logs warnings when packets are lost, including lost sample counts from perf buffers.
Sources: user/module/imodule.go:336-338
Optimization Strategies
- Increase map size: Use
--mapsizeflag to allocate more memory for eBPF maps - Filter aggressively: Use PCAP filter expressions to reduce captured packet volume
- Target specific processes: Use
-pflag to capture only specific PIDs - SSD storage: Write PCAP-NG files to fast storage (SSD) to reduce I/O bottlenecks
Implementation Class Diagram
Key Classes and Their Relationships
Sources: user/module/probe_openssl.go:83-106, user/event/event_tc.go, user/event/event_ssl.go
Error Handling
Common Issues
| Issue | Cause | Solution |
|---|---|---|
| Empty PCAP file | No packets matched filter | Check interface and filter expression |
| Missing DSB blocks | TLS handshake not captured | Ensure capture starts before connections |
| Wireshark cannot decrypt | Wrong cipher suite / version | Check TLS version compatibility |
| File not flushed | Program killed without cleanup | Wait for graceful shutdown or use longer captures |
Logging
PCAP mode logs include:
- Packet save counts (every 2 seconds):
INF packets saved into pcapng file. count=123 - Master secret saves:
INF CLIENT_RANDOM save success CLientRandom=... TlsVersion=... - DSB write failures:
WRN save sslKeylog failed - File path on initialization:
INF packets saved into pcapng file. pcapng path=...
Sources: README.md:189-230
Comparison with Other Modes
| Feature | PCAP Mode | Text Mode | Keylog Mode |
|---|---|---|---|
| Output format | PCAP-NG file | Text logs | SSLKEYLOGFILE |
| Network packets | Full capture | Not captured | Not captured |
| Plaintext content | Via DSB decryption | Direct output | Not included |
| Wireshark compatible | Yes (native) | No | Yes (manual import) |
| Performance impact | Highest (full packets) | Lowest | Low |
| Use case | Network analysis | Quick inspection | tcpdump integration |
For details on other modes, see Text Output Mode and TLS Key Logging.
Related Components
This PCAP integration relies on several other eCapture subsystems:
- TC Programs: See Network Connection Tracking for TC eBPF classifier details
- Master Secret Extraction: See Master Secret Extraction for TLS key capture
- Event Processing: See Event Processing Pipeline for event routing
- Module System: See Module System and Lifecycle for
IModuleinterface
The PCAP mode is one of three output formats supported by TLS modules, each optimized for different use cases and workflows.