Wireshark on FreeBSD: Network Protocol Analyzer Review
Wireshark is the standard network protocol analyzer. It captures packets, decodes protocols, and presents network traffic in a way that makes debugging and analysis practical. On FreeBSD, Wireshark works through BPF (Berkeley Packet Filter), the packet capture mechanism that originated on BSD. This review covers installation, the GUI and CLI tools, capture and display filters, protocol analysis workflows, tshark for headless systems, and integration with tcpdump.
Why Wireshark on FreeBSD
FreeBSD is commonly deployed as a firewall, router, or network gateway. When network problems occur -- dropped connections, performance degradation, protocol errors -- you need packet-level visibility. Wireshark provides that.
The relationship between FreeBSD and Wireshark is historically close. BPF, the kernel mechanism that makes packet capture possible, was developed on BSD. libpcap, the capture library that Wireshark (and tcpdump, and most packet capture tools) uses, was also a BSD project. Running Wireshark on FreeBSD is running it on native ground.
Installation
GUI Version
shpkg install wireshark
This installs the Qt-based GUI, tshark (CLI), and supporting tools. It pulls in Qt6 and other GUI dependencies, which is a significant dependency footprint on a headless server.
CLI Only (tshark)
If you do not need the GUI:
shpkg install tshark
This installs tshark, editcap, mergecap, capinfos, and other CLI tools without the Qt dependency. This is the right choice for servers.
Ports
shcd /usr/ports/net/wireshark make config # Select or deselect Qt GUI make install clean
BPF Permissions
By default, only root can access BPF devices (/dev/bpf*). To allow non-root capture:
sh# Create a network capture group pw groupmod network -m youruser # Set BPF device permissions (persists across reboots via devfs.rules) # /etc/devfs.rules [localrules=10] add path 'bpf*' mode 0660 group network
Enable the devfs ruleset:
shsysrc devfs_system_ruleset="localrules" service devfs restart
Alternatively, use dumpcap with setuid (Wireshark recommends this approach):
shchgrp network /usr/local/bin/dumpcap chmod 4750 /usr/local/bin/dumpcap
Capture Filters vs Display Filters
Wireshark uses two distinct filter systems. Understanding the difference is essential.
Capture Filters (BPF Syntax)
Applied before packets are stored. They reduce the volume of captured data. Use the same syntax as tcpdump.
sh# Capture only HTTP traffic tshark -i em0 -f "tcp port 80" # Capture traffic to/from a specific host tshark -i em0 -f "host 192.168.1.100" # Capture DNS traffic tshark -i em0 -f "udp port 53" # Capture SYN packets only tshark -i em0 -f "tcp[tcpflags] & tcp-syn != 0" # Capture traffic on a subnet, excluding SSH tshark -i em0 -f "net 10.0.0.0/24 and not port 22"
Capture filters are processed by BPF in the kernel. They are fast and efficient. Use them to limit capture to traffic you care about.
Display Filters (Wireshark Syntax)
Applied after capture. They filter what you see, not what is captured. More powerful and protocol-aware.
sh# Display only HTTP GET requests tshark -r capture.pcap -Y "http.request.method == GET" # Display TCP retransmissions tshark -r capture.pcap -Y "tcp.analysis.retransmission" # Display DNS queries for a specific domain tshark -r capture.pcap -Y "dns.qry.name contains example.com" # Display TLS handshake failures tshark -r capture.pcap -Y "tls.alert_message" # Display packets with specific TCP flags tshark -r capture.pcap -Y "tcp.flags.reset == 1" # Display slow HTTP responses (>1 second) tshark -r capture.pcap -Y "http.time > 1"
Common Display Filter Patterns for Sysadmins
sh# Find TCP connection resets tcp.flags.reset == 1 # Find retransmissions (indicates packet loss) tcp.analysis.retransmission # Find zero-window conditions (receiver buffer full) tcp.analysis.zero_window # Find duplicate ACKs (precursor to retransmission) tcp.analysis.duplicate_ack # Find TLS version negotiation tls.handshake.type == 1 # Find failed TLS handshakes tls.alert_message.level == 2 # Find ICMP errors icmp.type == 3 || icmp.type == 11
tshark: CLI Protocol Analysis
tshark is Wireshark's command-line interface. It is the tool you will use most on FreeBSD servers.
Live Capture
sh# Basic capture with protocol summary tshark -i em0 # Capture with verbose output tshark -i em0 -V # Capture N packets then stop tshark -i em0 -c 1000 # Capture for N seconds tshark -i em0 -a duration:60 # Capture to file tshark -i em0 -w /tmp/capture.pcap
Ring Buffer Capture
For long-running captures that should not fill the disk:
sh# Capture in ring buffer: 10 files, 100 MB each tshark -i em0 -b filesize:102400 -b files:10 -w /var/captures/trace.pcap
This creates trace_00001_TIMESTAMP.pcap through trace_00010_TIMESTAMP.pcap, then wraps around.
Reading and Filtering Captures
sh# Read a capture file tshark -r capture.pcap # Apply a display filter tshark -r capture.pcap -Y "http" # Extract specific fields tshark -r capture.pcap -T fields -e ip.src -e ip.dst -e tcp.port -e http.host # Statistics: protocol hierarchy tshark -r capture.pcap -q -z io,phs # Statistics: conversations tshark -r capture.pcap -q -z conv,tcp # Statistics: HTTP requests tshark -r capture.pcap -q -z http,tree # Statistics: DNS response times tshark -r capture.pcap -q -z dns,tree
JSON Output
shtshark -r capture.pcap -T json -Y "http.request" > http_requests.json
JSON output integrates with jq, Elasticsearch, and custom analysis scripts.
Integration with tcpdump
tcpdump is installed by default on FreeBSD. A common workflow is to capture with tcpdump (lightweight, always available) and analyze with Wireshark/tshark (powerful dissection).
Capture with tcpdump
sh# Capture on the firewall tcpdump -i em0 -w /tmp/firewall_capture.pcap -c 100000 # Capture with rotation tcpdump -i em0 -w /tmp/trace.pcap -C 100 -W 10
Analyze with tshark
sh# Transfer the file scp firewall:/tmp/firewall_capture.pcap . # Analyze tshark -r firewall_capture.pcap -Y "tcp.analysis.retransmission" -T fields -e ip.src -e ip.dst -e tcp.srcport -e tcp.dstport # Protocol breakdown tshark -r firewall_capture.pcap -q -z io,phs
Format Conversion
sh# Convert pcap to pcapng (Wireshark's native format) editcap -F pcapng input.pcap output.pcapng # Merge multiple captures mergecap -w merged.pcap trace1.pcap trace2.pcap trace3.pcap # Trim a capture to a time range editcap -A "2026-04-09 10:00:00" -B "2026-04-09 10:05:00" input.pcap trimmed.pcap # Extract specific packets editcap -r input.pcap output.pcap 1-1000 # First 1000 packets
Practical Analysis Workflows
Diagnosing Slow Connections
sh# Capture traffic for the affected connection tshark -i em0 -f "host 10.0.0.50 and port 443" -w /tmp/slow.pcap -a duration:120 # Check for retransmissions tshark -r /tmp/slow.pcap -q -z io,stat,1,"tcp.analysis.retransmission" # Check TCP window sizes tshark -r /tmp/slow.pcap -T fields -e frame.time_relative -e tcp.window_size -Y "ip.src == 10.0.0.50" # Check round-trip times tshark -r /tmp/slow.pcap -q -z rtt,tree
DNS Troubleshooting
sh# Capture DNS traffic tshark -i em0 -f "udp port 53" -w /tmp/dns.pcap -a duration:300 # Show all queries and responses tshark -r /tmp/dns.pcap -T fields -e frame.time -e ip.src -e dns.qry.name -e dns.resp.addr -e dns.time # Find slow DNS responses (>500ms) tshark -r /tmp/dns.pcap -Y "dns.time > 0.5" -T fields -e dns.qry.name -e dns.time # Find NXDOMAIN responses tshark -r /tmp/dns.pcap -Y "dns.flags.rcode == 3" -T fields -e dns.qry.name
TLS Troubleshooting
sh# Capture TLS handshakes tshark -i em0 -f "tcp port 443" -w /tmp/tls.pcap -a duration:60 # Show TLS versions negotiated tshark -r /tmp/tls.pcap -Y "tls.handshake.type == 2" -T fields -e ip.dst -e tls.handshake.version # Show cipher suites offered by clients tshark -r /tmp/tls.pcap -Y "tls.handshake.type == 1" -T fields -e ip.src -e tls.handshake.ciphersuite # Find certificate errors tshark -r /tmp/tls.pcap -Y "tls.alert_message" -T fields -e ip.src -e ip.dst -e tls.alert_message.desc
Firewall Rule Debugging
When PF or IPFW drops packets unexpectedly:
sh# Capture on the internal interface tshark -i em1 -f "host 10.0.0.100" -w /tmp/internal.pcap & # Capture on the external interface simultaneously tshark -i em0 -f "host 10.0.0.100" -w /tmp/external.pcap & # Wait, then compare # If packets appear on em1 but not em0, the firewall is dropping them
FreeBSD-Specific Notes
Interface Names
FreeBSD uses driver-based interface names (em0, igb0, ix0, etc.). List available interfaces:
shtshark -D
VLAN Traffic
To capture on a VLAN interface:
shtshark -i vlan100
Or capture on the parent interface and filter:
shtshark -i em0 -Y "vlan.id == 100"
Capturing on Bridge Interfaces
If running a bridge (e.g., for bhyve or VNET jails):
shtshark -i bridge0
PF Logged Packets
PF can log packets to the pflog interface:
shtshark -i pflog0
This captures only packets matching PF rules with the log keyword, providing a filtered view of firewall decisions.
Performance Considerations
Capture Performance
On high-throughput links (10 Gbps+), packet capture becomes a challenge. Recommendations:
- Use capture filters to limit traffic volume
- Write to ramdisk or fast SSD
- Increase BPF buffer size:
shsysctl net.bpf.bufsize=4194304 sysctl net.bpf.maxbufsize=16777216
- Use ring buffer captures to prevent disk fill
Analysis Performance
Wireshark's GUI slows down with large capture files (>1 GB). For large captures:
- Use tshark for initial filtering
- Split captures with editcap:
editcap -c 100000 large.pcap split.pcap - Use display filters to narrow scope before loading in the GUI
Verdict
Wireshark and tshark are indispensable tools for any FreeBSD sysadmin doing network work. The protocol dissection is unmatched, BPF integration is native and efficient, and the combination of tcpdump for capture with tshark for analysis is a powerful workflow.
The GUI (Wireshark) is excellent for interactive analysis but requires a desktop environment. For server work, tshark handles everything. The learning curve for display filters is moderate, but investing time in learning them pays dividends immediately.
Rating: 9/10 -- The definitive network analysis tool. Docked one point for the GUI dependency footprint, which is irrelevant if you use tshark.
Frequently Asked Questions
Can I capture traffic inside a FreeBSD jail?
Not directly. BPF devices are not available inside jails by default. Capture on the host and filter by the jail's IP address. For VNET jails, capture on the epair interface from the host side.
How do I decrypt TLS traffic with Wireshark?
If you have the server's private key (RSA only, not ECDHE), configure it in Wireshark's TLS preferences. For modern ECDHE-based connections, use the SSLKEYLOGFILE environment variable on the client to export session keys:
shexport SSLKEYLOGFILE=/tmp/sslkeys.log curl https://example.com
Then load /tmp/sslkeys.log in Wireshark under Edit > Preferences > Protocols > TLS > Pre-Master-Secret log filename.
How much disk space do captures use?
A fully saturated 1 Gbps link generates ~125 MB/s of capture data. At 10 Gbps, that is 1.25 GB/s. Always use capture filters to reduce volume, and ring buffer captures to limit disk usage.
What is the difference between pcap and pcapng?
pcapng (next generation) supports multiple interfaces in a single file, packet annotations, name resolution records, and per-packet comments. Wireshark uses pcapng by default. tcpdump uses pcap. Both tools can read both formats.
Can I automate tshark analysis?
Yes. tshark's -T fields output is designed for scripting:
sh# Extract HTTP hosts and count occurrences tshark -r capture.pcap -T fields -e http.host -Y "http.request" | sort | uniq -c | sort -rn
Combine with cron for scheduled analysis of ongoing captures.
How do I capture on all interfaces at once?
shtshark -i any -w /tmp/all_interfaces.pcap
The any pseudo-interface captures on all interfaces. Note that on FreeBSD, this may not capture VLAN tags correctly on all interface types.