File Extractor¶
pcapkit.foundation.extraction contains
Extractor only,
which synthesises file I/O and protocol analysis,
coordinates information exchange in all network layers,
extracts parametres from a PCAP file.
See also
Engine support for pypcap, pcap-ct and pypcapfile has since landed,
as pcapkit.foundation.engines.pypcap.PyPCAP (engine='pypcap'),
pcapkit.foundation.engines.pcap_ct.PCAP_CT (engine='pcap_ct')
and pcapkit.foundation.engines.pypcapfile.PyPCAPFile
(engine='pypcapfile'). All three support less than the default
engine does; Engine Support tabulates the gaps, and PyPCAPKit - Comprehensive Network Packet Analysis Library
documents the installation prerequisites each of the three carries.
- class pcapkit.foundation.extraction.Extractor(fin=None, fout=None, format=None, auto=True, extension=True, store=True, files=False, nofile=False, verbose=False, engine=None, layer=None, protocol=None, reassembly=False, reasm_strict=True, reasm_store=True, reasm_timeout=None, trace=False, trace_fout=None, trace_format=None, trace_byteorder='little', trace_nanosecond=False, trace_bidirectional=True, trace_analyse=False, ip=False, ipv4=False, ipv6=False, tcp=False, buffer_size=131072, buffer_save=False, buffer_path=None, no_eof=False, context=None)[source]¶
-
Extractor for PCAP files.
Notes
For supported engines, please refer to
run().- __init__(fin=None, fout=None, format=None, auto=True, extension=True, store=True, files=False, nofile=False, verbose=False, engine=None, layer=None, protocol=None, reassembly=False, reasm_strict=True, reasm_store=True, reasm_timeout=None, trace=False, trace_fout=None, trace_format=None, trace_byteorder='little', trace_nanosecond=False, trace_bidirectional=True, trace_analyse=False, ip=False, ipv4=False, ipv6=False, tcp=False, buffer_size=131072, buffer_save=False, buffer_path=None, no_eof=False, context=None)[source]¶
Initialise PCAP Reader.
- Parameters:
fin (
str|IO[bytes] |None) – file name to be read or a binary IO object; if file not exist, raiseFileNotFoundformat (
Literal['pcap','cap','json','tree','text','txt','plist','xml'] |None) – file format of outputauto (
bool) – if automatically run till EOFextension (
bool) – if check and append extensions to output filestore (
bool) – if store extracted packet infofiles (
bool) – if split each frame into different filesnofile (
bool) – if no output file is to be dumpedverbose (
bool|Callable[[Extractor,Frame|PCAPNG|Packet|Packet|Packet|pcap_packet|tuple[float,bytes]],Any]) – aboolvalue or a function takes theExtractorinstance and current parsed frame (depends on engine selected) as parameters to print verbose output informationengine (
Literal['default','pcapkit','dpkt','scapy','pyshark','pypcap','pcap_ct','pypcapfile'] |None) – extraction engine to be usedlayer (
Literal['link','internet','transport','application','none'] |None) – extract til which layerprotocol (
str|ProtocolBase|Type[ProtocolBase] |None) – extract til which protocolreassembly (
bool) – if perform reassemblyreasm_strict (
bool) – if set strict flag for reassemblyreasm_store (
bool) – if store reassembled datagramsreasm_timeout (
float|None) – reassembly timeout in seconds, measured on the capture’s own clock rather than the host’s, since an offline parser has no other notion of time passing;Noneselects each protocol’s own default – 60 seconds for IPv4 (RFC 1122 Section 3.3.2) and IPv6 (RFC 8200 Section 4.5), disabled for TCP, which no specification gives a deadline. Passmath.infto disable it everywheretrace (
bool) – if trace TCP traffic flowstrace_fout (
str|None) – path name for flow tracer if necessarytrace_format (
Literal['pcap','cap','json','tree','text','txt','plist','xml'] |None) – output file format of flow tracertrace_byteorder (
Literal['big','little']) – output file byte ordertrace_nanosecond (
bool) – output nanosecond-resolution file flagtrace_bidirectional (
bool) – whether both halves of a conversation are traced as one flow, which is the default;Falserestores the older behaviour of a flow per directiontrace_analyse (
bool) – whether each traced flow reassembles its application layer, so that itspacketcan be read. Off by default, because it buffers every traced payload – a cost tracing does not otherwise pay. Unavailable on thepysharkengine, which reports dissected fields rather than the octets behind themip (
bool) – if record data for IPv4 & IPv6 reassembly (must be used withreassembly=True)ipv4 (
bool) – if perform IPv4 reassembly (must be used withreassembly=True)ipv6 (
bool) – if perform IPv6 reassembly (must be used withreassembly=True)tcp (
bool) – if perform TCP reassembly and/or flow tracing (must be used withreassembly=Trueortrace=True)buffer_size (
int) – buffer size for reading input file (forSeekableReaderonly)buffer_save (
bool) – if save buffer to file (forSeekableReaderonly)buffer_path (
str|None) – path name for buffer file if necessary (forSeekableReaderonly)no_eof (
bool) – if not raiseEOFErrorwhen reach EOF – retry instead, which is what a live capture on a pipe or on standard input wants, since a read there blocks until the writer produces more or closes. Retrying stops as soon as one retry finds nothing new, so an exhausted input finishes rather than spinning; on a seekable input, where nothing blocks, that means a file still being appended to ends at the data present when the extraction reached itcontext (
ContextRegistry|ProtocolContext|Mapping[str,ProtocolContext] |Iterable[ProtocolContext] |None) – caller supplied parsing context for protocols that need information not carried on the wire, keyed by protocol index ID – c.f.pcapkit.corekit.context. Accepts aContextRegistry, a singleProtocolContext, a mapping, or any iterable of contexts. The channel is honoured by thedefault,pcapandpcapngengines, which parse withpcapkit’s own protocol implementations; the third party engines ignore it.
- Warns:
pcapkit.utilities.warnings.FormatWarning – Warns under following circumstances:
If using PCAP output for TCP flow tracing while the extraction engine is PyShark.
If output file format is not supported.
- property format: Literal['pcap', 'cap', 'json', 'tree', 'text', 'txt', 'plist', 'xml']¶
Format of output file.
- Raises:
UnsupportedCall – If
self._flag_qis set asTrue, as output is disabled by initialisation parameter.
- property output: str¶
Name of output file.
- Raises:
UnsupportedCall – If
self._flag_qis set asTrue, as output is disabled by initialisation parameter.
- property frame: tuple[Frame | PCAPNG | Packet | Packet | Packet | pcapfile.structs.pcap_packet | tuple[float, bytes], ...]¶
Extracted frames.
- Raises:
UnsupportedCall – If
self._flag_disFalse, as storing frame data is disabled.
- property reassembly: ReassemblyData¶
Frame record for reassembly.
ipv4– tuple of IPv4 payload fragment (reasm.ipv4.datagram)ipv6– tuple of IPv6 payload fragment (reasm.ipv6.datagram)tcp– tuple of TCP payload fragment (reasm.tcp.datagram)
- Raises:
UnsupportedCall – If
self._flag_risFalse, as reassembly is disabled.
- property trace: TraceFlowData¶
Index table for traced flow.
tcp– tuple of TCP flows (trace.tcp.index)
- Raises:
UnsupportedCall – If
self._flag_tisFalse, as flow tracing is disabled.
- classmethod register_dumper(format, dumper, ext)[source]¶
Register a new dumper class.
Notes
The full qualified class name of the new dumper class should be as
{dumper.module}.{dumper.name}.The overwrite guard fires only when the incumbent dumper differs from the replacement, so re-registering the exact same object is a silent no-op rather than a warning about nothing displaced – the identity guard GitHub issue #718 gave the code-keyed registrars, extended here by GitHub issue #739.
__output__maps each format to a(dumper, ext)pair, so the identity check compares the incumbent dumper (index0), not the pair – a re-registration that only changesextis still identity-equal on the dumper and stays silent, since the dumper is what “the same object” means here, not the pair as a whole.__output__is also acollections.defaultdict, unlike the other three registrars this issue touches;dict.get()does not invoke the default factory the waycls.__output__[format]would, so it stays non-inserting here as well.- Parameters:
format (
str) – format namedumper (
ModuleDescriptor[Dumper] |Type[Dumper]) – module descriptor or adictdumper.dumper.Dumpersubclassext (
str) – file extension
- classmethod register_engine(name, engine)[source]¶
Register a new extraction engine.
Notes
The full qualified class name of the new extraction engine should be as
{engine.module}.{engine.name}.The overwrite guard fires only when the incumbent differs from the replacement, so re-registering the exact same object is a silent no-op rather than a warning about nothing displaced – the identity guard GitHub issue #718 gave the code-keyed registrars, extended here by GitHub issue #739.
- classmethod register_reassembly(protocol, reassembly)[source]¶
Register a new reassembly engine.
Notes
The full qualified class name of the new reassembly engine should be as
{reassembly.module}.{reassembly.name}.The overwrite guard fires only when the incumbent differs from the replacement, so re-registering the exact same object is a silent no-op rather than a warning about nothing displaced – the identity guard GitHub issue #718 gave the code-keyed registrars, extended here by GitHub issue #739.
- Parameters:
protocol (
str) – protocol namereassembly (
ModuleDescriptor[Reassembly] |Type[Reassembly]) – module descriptor or aReassemblysubclass
- classmethod register_traceflow(protocol, traceflow)[source]¶
Register a new flow tracing engine.
Notes
The full qualified class name of the new flow tracing engine should be as
{traceflow.module}.{traceflow.name}.The overwrite guard fires only when the incumbent differs from the replacement, so re-registering the exact same object is a silent no-op rather than a warning about nothing displaced – the identity guard GitHub issue #718 gave the code-keyed registrars, extended here by GitHub issue #739.
- run()[source]¶
Start extraction.
We uses
import_test()to check if a certain engine is available or not. For supported engines, each engine has different driver method:Default drivers:
PCAP Format:
pcapkit.foundation.engines.pcap.PCAPPCAP-NG Format:
pcapkit.foundation.engines.pcapng.PCAPNG
DPKT driver:
pcapkit.foundation.engines.dpkt.DPKTScapy driver:
pcapkit.foundation.engines.scapy.ScapyPyShark driver:
pcapkit.foundation.engines.pyshark.PySharkPyPCAP driver:
pcapkit.foundation.engines.pypcap.PyPCAPpcap-ct driver:
pcapkit.foundation.engines.pcap_ct.PCAP_CTPyPCAPFile driver:
pcapkit.foundation.engines.pypcapfile.PyPCAPFile
- Warns:
pcapkit.utilities.warnings.EngineWarning – If the extraction engine is not available. This is either due to dependency not installed, or supplied engine unknown.
- Return type:
None
- classmethod make_name(fin='in.pcap', fout='out', fmt='tree', extension=True, *, files=False, nofile=False)[source]¶
Generate input and output filenames.
The method will perform following processing:
sanitise
finas the input PCAP filename;in.pcapas default value and append.pcapextension if needed andextensionisTrue; as well as test if the file exists;if
nofileisTrue, skips following processing;if
fmtprovided, then it presumes corresponding output file extension;if
foutnot provided, it presumes the output file name based on the presumptive file extension; the stem of the output file name is set asout; should the file extension is not available, then it raisesFormatError;if
foutprovided, it presumes corresponding output format if needed; should the presumption cannot be made, then it raisesFormatError;it will also append corresponding file extension to the output file name if needed and
extensionisTrue.
And the method returns the generated input and output filenames as follows:
input filename
output filename / directory name
output format
output file extension, bare, i.e. without the leading
., so that a caller composing a per-frame filename writesf'{name}.{ext}'if split each frame into different files
- Parameters:
fin (
str|IO[bytes]) – Input filename or a binary IO object.fout (
str) – Output filename.fmt (
Literal['pcap','cap','json','tree','text','txt','plist','xml']) – Output file format.extension (
bool) – If append.pcapfile extension to the input filename iffindoes not have such file extension; if check and append extensions to output file.files (
bool) – If split each frame into different files.nofile (
bool) – If no output file is to be dumped.
- Return type:
tuple[str,str|None,Literal['pcap','cap','json','tree','text','txt','plist','xml'],str|None,bool]- Returns:
Generated input and output filenames.
- Raises:
FileNotFound – If input file does not exists.
FormatError – If output format not provided and cannot be presumpted.
- record_header()[source]¶
Read global header.
The method will parse the PCAP global header and save the parsed result to its extraction context. Information such as PCAP version, data link layer protocol type, nanosecond flag and byteorder will also be save the current
Engineinstance as well.If TCP flow tracing is enabled, the nanosecond flag and byteorder will be used for the output PCAP file of the traced TCP flows.
For output, the method will dump the parsed PCAP global header under the name of
Global Header.- Return type:
- record_frames()[source]¶
Read packet frames.
The method calls
self._exeng.read_frameto parse each frame from the input PCAP file; and performs cleanup by callingself._exeng.closeupon completion of the parsing process.Notes
Under non-auto mode, i.e.
self._flag_aisFalse, the method performs no action.
- __output__: DefaultDict[str, tuple[ModuleDescriptor[Dumper] | Type[Dumper], str | None]]¶
Format dumper mapping for writing output files. The values should be a tuple representing the module name and class name, or a
dictdumper.dumper.Dumpersubclass, and corresponding file extension.
- __engine__: dict[str, ModuleDescriptor[Engine] | Type[Engine]]¶
Engine mapping for extracting frames. The values should be a tuple representing the module name and class name, or an
Enginesubclass.
- __reassembly__: dict[str, ModuleDescriptor[Reassembly] | Type[Reassembly]]¶
Reassembly support mapping for extracting frames. The values should be a tuple representing the module name and class name, or a
Reassemblysubclass.
- __traceflow__: dict[str, ModuleDescriptor[TraceFlow] | Type[TraceFlow]]¶
Flow tracing support mapping for extracting frames. The values should be a tuple representing the module name and class name, or a
TraceFlowsubclass.
- _cleanup()[source]¶
Cleanup after extraction & analysis.
The method calls
self._exeng.close, setsself._flag_easTrueand closes the input file if this class opened it.That proviso is the whole of it: a handle opened here –
fingiven as a path, i.e.self._flag_sset – is closed, and a stream the caller supplied is left alone for the caller to close when it is done with it.It also tells the flow tracer the capture has ended, via
TraceFlow.finish. That is the point at which a traced flow nothing has superseded can be said to be over, so it is where such a flow is finalised and its callbacks run. This method can be reached twice for one extraction – the EOF path in_read_frame()and again fromrun()– sofinishis required to be idempotent rather than guarded here.
- _flag_a: bool¶
Auto extract flag. It indicates if the extraction process should continue automatically until the EOF is reached.
- _flag_r: bool¶
Reassembly flag. It indicates if datagram reassembly is enabled. Every engine reads it to decide whether to feed
_reasm, and the engines that cannot reassemble clear it on startup.
- _flag_v: bool¶
Verbose flag. This is used to determine if the verbose callback function should be called at each frame.
- _flag_n: bool¶
No EOF flag. It is useful when the input is a live capture on a pipe or on standard input, where reaching the end of what has arrived so far does not mean the capture is over: the extraction retries instead of stopping. It retries only while the input is still producing, though – see
_note_eof_progress()for the rule and for what it narrows, without which an exhausted stream spins forever (#620).
- _flag_s: bool¶
Input filename flag. It indicates if the input file is a file name or a binary IO object. For the latter, we should not close the file object after extraction.
- _ifile: BufferedReader¶
Input file object.
- _fext: str | None¶
Output file extension, bare, i.e. without the leading
.–'json', not'.json'. Normalised bymake_name(), whose docstring is the contract; the engines compose a per-frame filename asf'{name}.{ext._fext}'and supply the dot themselves.
- _frame: list[Frame | PCAPNG | Packet | Packet | Packet | pcapfile.structs.pcap_packet | tuple[float, bytes]]¶
Frame records.
- _reasm: ReassemblyManager¶
Frame record for reassembly.
- _trace: TraceFlowManager¶
Frame record for flow tracing.
- _eof_mark: int | None¶
Position of the input stream at the previous end of stream, or
Nonebefore the first one. Comparing it against the position at the next end of stream is what tells a live capture that has paused – retry, more may arrive – from one that is finished, which is the termination conditionno_eofwas missing (#620).
- _vfunc¶
- _exnam: Literal['default', 'pcapkit', 'dpkt', 'scapy', 'pyshark', 'pypcap', 'pcap_ct', 'pypcapfile']¶
Extraction engine name.
- _exptl: str | ProtocolBase | Type[ProtocolBase]¶
Extract til protocol.
- _exctx: ContextRegistry¶
Caller supplied parsing context, c.f.
pcapkit.corekit.context.
- __iter__()[source]¶
Iterate and parse PCAP frame.
- Raises:
IterableError – If
self._flag_aisTrue, as such operation is not applicable.- Return type:
- __next__()[source]¶
Iterate and parse next PCAP frame.
It will call
self._exeng.read_frameto parse next PCAP frame internally, until the EOF reached; then it callsself._cleanupfor the aftermath.- Return type:
TypeVar(_P)
- __call__()[source]¶
Works as a simple wrapper for the iteration protocol.
- Raises:
CallableError – If
self._flag_aisTrue, as such operation is not applicable.- Return type:
TypeVar(_P)