Deeper Than tcpdump: NIC Diagnostics with ethtool and Protocol Analysis with tshark

tcpdump answers “what packets are crossing this interface.” It does not answer “is this NIC actually negotiated at the speed and duplex it should be,” “are ring buffer overruns silently dropping packets before tcpdump ever sees them,” or “what does every single field in this TLS ClientHello actually contain.” Those require two different tools: ethtool for the hardware layer below the packet capture point, and tshark for protocol decode beyond what tcpdump’s default output gives you.

This post covers both, and where they fit relative to tcpdump in a diagnostic workflow.

ethtool: The Hardware Layer

ethtool eth0
Settings for eth0:
        Supported ports: [ TP ]
        Supported link modes:   1000baseT/Full
                                10000baseT/Full
        Speed: 10000Mb/s
        Duplex: Full
        Auto-negotiation: on
        Link detected: yes

This is the first thing to check when a connection “feels slow” — a NIC stuck negotiating at 100Mb/s instead of 10Gb/s due to a bad cable or a misconfigured switch port produces symptoms that look exactly like a software problem.

Forcing speed and duplex (diagnostic only — rarely correct for production)

ethtool -s eth0 speed 1000 duplex full autoneg off

Useful for proving a negotiation problem by forcing both ends to a known-good state and observing whether the symptom disappears. Leave auto-negotiation on for any link you are not actively debugging.

Driver and firmware info

ethtool -i eth0
driver: ixgbe
version: 5.1.0-k
firmware-version: 0x800007b8
bus-info: 0000:01:00.0

Critical when chasing a known driver bug — cross-reference firmware-version against vendor advisories before assuming the problem is configuration.

Ring buffer sizes

ethtool -g eth0
Ring parameters for eth0:
Pre-set maximums:
RX:             4096
TX:             4096
Current hardware settings:
RX:             512
TX:             512

Small ring buffers under high packet rates or bursty traffic cause silent drops before the kernel networking stack — and therefore before tcpdump — ever sees the packet. If ethtool -S (below) shows rx_dropped incrementing while tcpdump shows nothing, this is usually why.

# Increase RX ring to the hardware maximum
ethtool -G eth0 rx 4096

Hardware statistics and error counters

ethtool -S eth0 | grep -E 'drop|error|discard'
rx_dropped: 1402
rx_errors: 0
rx_missed_errors: 1402
rx_crc_errors: 0
tx_dropped: 0

rx_missed_errors incrementing means the NIC’s hardware ring filled up faster than the kernel could drain it — a capacity problem, not a cabling problem. Compare against ethtool -g ring sizes and consider increasing them, or check for CPU starvation on the interrupt-handling core (mpstat -P ALL 1 during the symptom window).

Offload features

ethtool -k eth0
rx-checksumming: on
tx-checksumming: on
tcp-segmentation-offload: on
generic-segmentation-offload: on
large-receive-offload: off

Offload features matter enormously when packet captures look “wrong.” With TSO (TCP Segmentation Offload) enabled, tcpdump on the local host can show TCP segments far larger than the path MTU — the NIC does the segmentation in hardware after the kernel hands off one large buffer, so the capture point (which sits before the NIC) sees the pre-segmentation size.

# Disable TSO to see what the wire actually carries (diagnostic only)
ethtool -K eth0 tso off gso off

Always re-enable afterward — TSO/GSO meaningfully reduces CPU load on high-throughput interfaces.

Wake-on-LAN, pause frames, and other settings

# Flow control / pause frame status — relevant when a switch and NIC disagree on flow control
ethtool -a eth0
Pause parameters for eth0:
Autonegotiate: on
RX:            on
TX:            on

Mismatched pause frame settings between a NIC and its switch port can cause one side to silently throttle or drop traffic under load — worth checking when a link “works fine at low traffic, falls over under load.”

tshark: Protocol Decode Beyond tcpdump

tshark is Wireshark’s command-line interface — same dissectors, same protocol decode depth, no GUI. Where tcpdump’s default output gives you headers, tshark gives you everything Wireshark’s GUI would show, including TLS handshake details, HTTP/2 frame contents, and DNS record fields, fully decoded.

Basic capture

tshark -i eth0

Capture filters use the same BPF syntax as tcpdump:

tshark -i eth0 -f "tcp port 443"

Display filters (the real power)

This is where tshark diverges sharply from tcpdump. Display filters operate on decoded fields, not raw bytes:

# Only TLS handshake packets
tshark -i eth0 -Y "tls.handshake"

# Only TLS ClientHello messages
tshark -i eth0 -Y "tls.handshake.type == 1"

# HTTP requests with a specific host header
tshark -i eth0 -Y 'http.host == "api.example.com"'

# DNS queries only (not responses)
tshark -i eth0 -Y "dns.flags.response == 0"

You can apply a capture filter (-f, BPF syntax, applied before capture) and a display filter (-Y, Wireshark syntax, applied after decode) simultaneously — capture broadly, filter precisely:

tshark -i eth0 -f "port 443" -Y "tls.handshake.extensions_server_name"

Extracting specific fields

tshark -i eth0 -Y "tls.handshake.type == 1" \
  -T fields -e ip.src -e tls.handshake.extensions_server_name
192.168.1.10    api.example.com
192.168.1.10    cdn.example.net

-T fields -e <field> is the single most useful tshark flag for scripting — it turns a packet capture directly into structured columnar output, no further parsing required.

Reading from a pcap file

tshark -r capture.pcap -Y "tcp.analysis.retransmission"

tcp.analysis.retransmission is a Wireshark-computed field — Wireshark/tshark tracks TCP sequence numbers across the whole capture and flags retransmissions automatically, something raw tcpdump output cannot do without manual sequence number tracking.

Statistics

# Conversation summary — who talked to whom, how much
tshark -r capture.pcap -q -z conv,ip

# Protocol hierarchy — breakdown of what's actually in the capture
tshark -r capture.pcap -q -z io,phs

# IO graph data — packets per second over time
tshark -r capture.pcap -q -z io,stat,1

Following a TCP stream

tshark -r capture.pcap -q -z follow,tcp,ascii,0

Reconstructs the full application-layer conversation for TCP stream index 0 — the command-line equivalent of Wireshark’s “Follow TCP Stream” feature.

A Combined Workflow

A realistic diagnostic sequence when a customer reports “intermittent slowness” on a specific link:

  1. ethtool eth0 — confirm link speed/duplex is correct, not negotiated down.
  2. ethtool -S eth0 | grep -E 'drop|error' — check for hardware-level drops before assuming it’s a software/application issue.
  3. ethtool -g eth0 — if drops are present, check whether ring buffers are undersized for the traffic burst pattern.
  4. tcpdump -i eth0 -w capture.pcap — capture once hardware is ruled out, to see what is actually on the wire.
  5. tshark -r capture.pcap -Y "tcp.analysis.retransmission or tcp.analysis.duplicate_ack" — check whether retransmissions correlate with the reported slowness windows.
  6. tshark -r capture.pcap -q -z io,stat,1 — plot packets-per-second over time to visually correlate against the reported timing of the issue.

This mirrors the same fingerprinting approach behind rst-forensics — work from coarse hardware-layer signals down to fine packet-layer evidence, rather than guessing at the application layer first.

When PMTUD Is the Real Culprit

If tshark analysis shows the TCP handshake completing but the connection stalling shortly after on larger payloads, suspect a Path MTU Discovery black hole — an intermediate hop dropping ICMP “Fragmentation Needed” messages that would otherwise tell the sender to reduce its segment size. pmtud-sweeper automates exactly this investigation, binary-searching the largest DF-set packet each hop will pass and naming the constraining router.

  • Linux tcpdump — capture filter syntax shared with tshark; the lighter-weight option when you only need raw packet headers rather than full protocol decode
  • Linux tc — controls the shaping and queuing that happens after the NIC receives packets; ethtool ring buffers and tc qdiscs operate on adjacent layers
  • pmtud-sweeper — automates the ICMP type 3 / fragmentation-needed investigation that tshark surfaces manually