Skip to content

Frame.len and Frame.cap_len are populated from opposite wire fields by the PCAP and PCAP-NG readers #618

Description

@JarryShaw

Frame.len and Frame.cap_len are populated from opposite wire fields depending on which container format was read. A caller reading frame.len gets the captured length from a PCAP file and the original on-wire length from a PCAP-NG file.

The two sites

PCAP — pcapkit/protocols/misc/pcap/frame.py:224-225 then :261-262:

_ilen = schema.incl_len      # captured octets
_olen = schema.orig_len      # original on-wire octets
...
len=_ilen,                   # len   <- CAPTURED
cap_len=_olen,               # cap_len <- ORIGINAL

PCAP-NG — pcapkit/toolkit/pcapng.py:270-271:

len=block.original_len,      # len   <- ORIGINAL
cap_len=block.captured_len,  # cap_len <- CAPTURED

Exactly inverted. Read against the field names, the PCAP-NG path is the intuitive one — cap_len holding the captured length — and the PCAP path is the surprising one.

Why it went unnoticed until now

The two lengths differ only for a truncated frame, where the snapshot length cut the capture short. Until #614 there was no fixture in this repository with incl_len != orig_len, so every existing test compared a value against itself and could not distinguish the two assignments. #614 adds one deliberately: a frame with 1200 octets on the wire and 96 captured, which is the first case that can show the inversion at all.

That is the same shape as three other defects found in this repository today — a suite that looks thorough while every fixture sits at the one point where two possibilities coincide.

Why it is not a one-line rename

On the PCAP path, len is load-bearing as the captured length. frame.py:289 reads self._read_fileng(self.length + _ilen) and :283 computes seek_cur = _seek_set + self.length + _ilen, and the value is handed to _decode_next_layer as the octets actually available to parse. Swapping the names without tracing those consumers would hand the parser the on-wire length for a truncated frame, which is precisely the over-long-declared-length class that #554, #573 and #594 are about.

So the fix requires deciding which reader is wrong, and it changes caller-visible behaviour either way:

  • if len should mean captured, the PCAP-NG path is wrong and any caller relying on it changes meaning;
  • if len should mean original, the PCAP path's internal uses must be rewired to cap_len first.

That is an owner decision rather than a mechanical fix, which is why #614 left it and its new tests deliberately assert on frame_info.* rather than on len/cap_len, so they pin neither answer.

Notes

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions