PCAP Dumper

pcapkit.dumpkit.pcap is the dumper for the PCAP format, like those in dictdumper.

class pcapkit.dumpkit.pcap.PCAPIO(fname, *, protocol, byteorder=sys.byteorder, nanosecond=False, **kwargs)[source]

Bases: DumperBase

PCAP file dumper.

Parameters:
  • fname (str) – output file name

  • protocol (LinkType | IntEnum | aenum.IntEnum | str | int) – data link type

  • byteorder (Literal['big', 'little']) – header byte order

  • nanosecond (bool) – nanosecond-resolution file flag

  • **kwargs (Any) – further global header fields, i.e. version, thiszone, sigfigs and snaplen, and arbitrary keyword arguments

Changed in version 1.5.0: The global header takes version, thiszone, sigfigs and snaplen from **kwargs, so format='pcap' output keeps the input’s values; 1.4.x wrote the defaults (#1165, #1255).

property kind: Literal['pcap']

File format of current dumper.

__init__(fname, *, protocol, byteorder=sys.byteorder, nanosecond=False, **kwargs)[source]

Initialise dumper.

Parameters:
  • fname (str) – output file name

  • protocol (LinkType | IntEnum | aenum.IntEnum | str | int) – data link type

  • byteorder (Literal['big', 'little']) – header byte order

  • nanosecond (bool) – nanosecond-resolution file flag

  • **kwargs (Any) – further global header fields, i.e. version, thiszone, sigfigs and snaplen, and arbitrary keyword arguments

_append_value(value, file, name)[source]

Call this function to write contents.

Parameters:
  • value (Frame) – content to be dumped

  • file (IO[bytes]) – output file

  • name (str) – name of current content block

Notes

A PCAP record is a 16-octet header, from value.frame_info with the fraction in this file’s resolution (see self._make_timestamp), followed by value.packet. Both are written directly rather than through Frame, whose constructor dissects the record again through the whole protocol stack. That round trip measured about 82% of the cost of a flow-traced extraction (http.pcap, 1117 frames, best of 7: 2319 ms with it, 1263 ms without, over a 1030 ms untraced baseline), and re-emits every parse warning the frame raised, such as SchemaWarning: packet length < 0: -3 for a 3-octet payload.

incl_len is written as len(value.packet), not as value.frame_info.incl_len. They differ only for a record kept as captured whose declared length runs past the end of its file, or past its PCAP-NG block (#1405); copying that length would claim octets the trace does not hold, and a reader would run off the end of the file (#1541).

_make_timestamp(frame_info, time_epoch)[source]

Record header seconds and fraction, in this file’s resolution.

Parameters:
  • frame_info (FrameInfo) – the frame’s record header fields

  • time_epoch (Decimal | float | int) – the frame’s UNIX timestamp

Return type:

tuple[int, int]

Returns:

The ts_sec and ts_usec fields to write.

Notes

frame_info does not say which resolution its ts_usec is in. A PCAP frame carries its file’s, and one converted from PCAP-NG carries its interface’s (cf. block2frame()), either of which may differ from this file’s (#1500). time_epoch settles it: the fraction is in whichever resolution truncates the frame’s offset into its second to exactly that value.

The fraction is written as is when that is this file’s resolution, so a record traced at its own resolution keeps its octets, and also when neither resolution fits, as for a frame built by hand. When it is the other resolution, the fraction is recomputed from time_epoch at this file’s – microseconds times 1000, or nanoseconds divided by 1000 and truncated rather than rounded. That is how block2frame() and Frame.make reduce a timestamp to a fraction, and how libpcap scales a nanosecond file down (sf-pcap.c). It also keeps the second: 999,999,999 ns truncates to 999,999 us, where rounding would reach a whole second. A recomputed fraction of a second or more is carried into ts_sec, so that multiplying by 1000 cannot overflow the field.