A capture holds six Echo requests and three replies, and somebody writes 50 percent packet loss in the ticket. That number may be true for the capture and false for the tunnel. The six requests might belong to two different conversations with two different delivery contracts. Group them before you divide, and the ratio stops being the interesting part of the report.

Step 1: separate the streams by source and destination

An Echo request carries a source and a destination, and those two fields define which conversation it belongs to. A probe generated by the gateway uses the gateway's tunnel address, while a probe forwarded on behalf of a LAN host keeps that host's address. The far side can have a return route for one and not the other, which makes the two groups behave differently for reasons that have nothing to do with the tunnel.

Split the capture on those fields before counting anything, and keep the destination as part of the key. Two streams to different peers are not comparable even when they share a source.

Write the groups down with their counts, because the next step decides which replies belong to which group. A group with three requests and no matching reply is a finding. A group with three requests and three replies is a baseline.

Step 2: match on the identifier and the sequence

The Echo format in RFC 792 carries an identifier and a sequence number, and it treats them as the fields that pair a reply with its request. Both are needed for that job. A sequence number alone is not unique, since different senders or processes can reuse the same value inside one capture window. The identifier narrows the sender and the sequence narrows the position, and the pair together is what makes a match defensible.

A reply reverses the address direction of its request, so a match is a request-reply pair rather than two identical tuples. Compare the request's source with the reply's destination and the request's destination with the reply's source, then confirm the identifier and sequence agree.

Keep the observation window as well, because a long capture can contain legitimate reuse of both fields. Trimming the window to one burst removes most of that ambiguity. It also makes the counts reproducible for whoever reads the ticket.

tshark -r capture.pcap -Y 'icmp.type == 8' -T fields -e frame.time -e ip.src -e ip.dst -e icmp.ident -e icmp.seq
tshark -r capture.pcap -Y 'icmp.type == 0' -T fields -e frame.time -e ip.src -e ip.dst -e icmp.ident -e icmp.seq

Step 3: compare tuples at the same boundary

If network address translation sits between the capture point and the peer, the addresses in the request and the reply will differ by design. Compare the tuples at one boundary, or carry the mapping explicitly so the difference is accounted for. Mixing pre-translation requests with post-translation replies invents mismatches that never existed on the wire.

Decide the boundary before you start counting, and state it in the report so the next person can reproduce the grouping. One capture on the client side and another on the server side are two different boundaries. Each one answers a different question about where the reply disappeared.

A translated probe group also inherits the translation device's own state, which can be the actual reason a reply never arrives. Check that state before blaming the path beyond it.

tcpdump -ni any icmp and host 10.90.0.1 -c 20
tshark -r capture.pcap -Y 'icmp' -T fields -e ip.src -e ip.dst -e ip.ttl | head -20

Step 4: state what the capture can and cannot prove

An observed gap does not establish that the far host stayed silent. The capture point may see only one direction, a filter may drop the reply, or the buffer may have overflowed during the window. Each of those produces the same absence and a different conclusion.

Record the capture location, the filter expression and the drop counters alongside the counts, because a ratio without them cannot be audited. Those three lines are what make the number defensible later.

Then separate what the observation establishes from what it suggests, in two sentences rather than one. The first sentence states the counts and the boundary. The second states the hypothesis and what would confirm it.

Where the question is whether a specific path drops packets, a controlled probe with an explicit source address is stronger evidence than a passive count of mixed traffic. Send it from the same machine, at the same time, to the same peer. Change one variable and the comparison holds.

Report the groups and the next boundary

The report has three lines: the group definition, the matched counts inside each group, and the boundary at which the comparison was made. A reader can then see that one group answered completely and another did not, which points at a route or a permission rather than at random loss.

Attach the capture file and the filter expressions so the grouping can be reproduced. A summary without the file is an assertion rather than a result.

ping -c 5 -I 10.80.0.6 10.90.0.1
ping -c 5 -I 10.30.0.25 10.90.0.1
tshark -r capture.pcap -Y 'icmp.type == 8 || icmp.type == 0' -T fields -e ip.src -e ip.dst -e icmp.ident -e icmp.seq | sort | uniq -c | head

When one group shows five replies and the other shows none, the finding is that one source has a working return path and the other does not. That is a much better ticket than a blended percentage, and it points the next check at the return route instead of at an unrelated VPN instance.

Nsɛm a ɛfa ho