Skip to content

"chicken and egg" problem for PCAPNG files: 'PCAPNG' object has no attribute '_info' #289

@9yte

Description

@9yte

When loading a pcapng file, using the code below,

import pcapkit

with open('sample.pcap', 'rb') as file:
    pcapkit.extract(fin=file, nofile=True, verbose=True)

I see this error:

File ~/Desktop/REDACTED/meta.git/.venv/lib/python3.13/site-packages/pcapkit/interface/core.py:122, in extract(fin, fout, format, auto, extension, store, files, nofile, verbose, engine, layer, protocol, reassembly, reasm_strict, reasm_store, trace, trace_fout, trace_format, trace_byteorder, trace_nanosecond, ip, ipv4, ipv6, tcp, buffer_size, buffer_save, buffer_path, no_eof)
    119 if isinstance(layer, type) and issubclass(layer, Protocol):
    120     layer = (layer.__layer__ or 'none').lower()  # type: ignore[assignment]
--> 122 return Extractor(fin=fin, fout=fout, format=format,
    123                  store=store, files=files, nofile=nofile,
    124                  auto=auto, verbose=verbose, extension=extension,
    125                  engine=engine, layer=layer, protocol=protocol,  # type: ignore[arg-type]
    126                  ip=ip, ipv4=ipv4, ipv6=ipv6, tcp=tcp,
    127                  reassembly=reassembly, reasm_store=reasm_store, reasm_strict=reasm_strict,
    128                  trace=trace, trace_fout=trace_fout, trace_format=trace_format,
    129                  trace_byteorder=trace_byteorder, trace_nanosecond=trace_nanosecond,
    130                  buffer_size=buffer_size, buffer_path=buffer_path, buffer_save=buffer_save,
    131                  no_eof=no_eof)

File ~/Desktop/REDACTED/meta.git/.venv/lib/python3.13/site-packages/pcapkit/foundation/extraction.py:825, in Extractor.__init__(self, fin, fout, format, auto, extension, store, files, nofile, verbose, engine, layer, protocol, reassembly, reasm_strict, reasm_store, trace, trace_fout, trace_format, trace_byteorder, trace_nanosecond, ip, ipv4, ipv6, tcp, buffer_size, buffer_save, buffer_path, no_eof)
    821 self._magic = self._ifile.peek(4)[:4]
    822 #self._magic = self._ifile.read(4)  # magic number
    823 #self._ifile.seek(0, os.SEEK_SET)
--> 825 self.run()

File ~/Desktop/REDACTED/meta.git/.venv/lib/python3.13/site-packages/pcapkit/foundation/extraction.py:456, in Extractor.run(self)
    453     raise FormatError(f'unknown file format: {self._magic!r}')
    455 # start engine
--> 456 self._exeng.run()
    458 # start iteration
    459 self.record_frames()

File ~/Desktop/REDACTED/meta.git/.venv/lib/python3.13/site-packages/pcapkit/foundation/engines/pcapng.py:135, in PCAPNG.run(self)
    125 """Start extraction.
    126 
    127 This method is the entry point for PCAP-NG file extraction. It will
   (...)    131 
    132 """
    133 ext = self._extractor
--> 135 shb = P_PCAPNG(ext._ifile, num=0, sct=1, ctx=None)
    136 if shb.info.type != Enum_BlockType.Section_Header_Block:
    137     raise FormatError(f'PCAP-NG: [SHB] invalid block type: {shb.info.type!r}')

File ~/Desktop/REDACTED/meta.git/.venv/lib/python3.13/site-packages/pcapkit/protocols/protocol.py:521, in ProtocolBase.__init__(self, file, length, **kwargs)
    518 self._sigterm = self._check_term_threshold()
    520 # post-init customisations
--> 521 self.__post_init__(file, length, **kwargs)  # type: ignore[arg-type]
    523 # inject packet payload to the info dict
    524 self._info.__update__(packet=self.packet.payload)

File ~/Desktop/REDACTED/meta.git/.venv/lib/python3.13/site-packages/pcapkit/protocols/misc/pcapng.py:1046, in PCAPNG.__post_init__(self, file, length, num, sct, ctx, **kwargs)
   1043 _seek_set = self._file.tell()
   1045 #: pcapkit.corekit.infoclass.Info: Parsed packet data.
-> 1046 self._info = self.unpack(length, _read=_read, _seek_set=_seek_set, **kwargs)

File ~/Desktop/REDACTED/meta.git/.venv/lib/python3.13/site-packages/pcapkit/protocols/misc/pcapng.py:867, in PCAPNG.unpack(self, length, **kwargs)
    864     self.__header__ = cast('Schema_PCAPNG', self.__schema__.unpack(self._file, length, packet))  # type: ignore[call-arg,misc]
    866 data = self.read(length, **kwargs)
--> 867 data.__update__(packet=self.packet.payload)
    868 return data

File /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/functools.py:1042, in cached_property.__get__(self, instance, owner)
   1040 val = cache.get(self.attrname, _NOT_FOUND)
   1041 if val is _NOT_FOUND:
-> 1042     val = self.func(instance)
   1043     try:
   1044         cache[self.attrname] = val

File ~/Desktop/REDACTED/meta.git/.venv/lib/python3.13/site-packages/pcapkit/protocols/protocol.py:187, in ProtocolBase.packet(self)
    185 """Data_Packet data of the protocol."""
    186 try:
--> 187     return self._read_packet(header=self.length)
    188 except UnsupportedCall:
    189     return Data_Packet(
    190         header=b'',
    191         payload=self._read_packet(),
    192     )

File ~/Desktop/REDACTED/meta.git/.venv/lib/python3.13/site-packages/pcapkit/protocols/misc/pcapng.py:651, in PCAPNG.length(self)
    648 @property
    649 def length(self) -> 'int':
    650     """Header length of corresponding protocol."""
--> 651     return self._info.length

AttributeError: 'PCAPNG' object has no attribute '_info'

The AttributeError: 'PCAPNG' object has no attribute '_info' is caused by a bug in the pcapkit library (specifically pypcapkit).
The traceback reveals a circular dependency in the library's internal logic for handling PCAPNG files:
PCAPNG initialization calls self.unpack().
unpack attempts to access self.packet.payload.
Accessing self.packet triggers a read that requires self.length.
self.length tries to read from self._info.length.
Critically, self._info has not been created yet—it is exactly what unpack() is supposed to return and assign.
This is a "chicken and egg" problem.

System information
A clear and concise description of your system information.

  • OS Version: macOS Sequoia 15.6
  • Python Version: 3.12

You can reproduce this by simply running your test: https://github.com/JarryShaw/PyPCAPKit/blob/main/test/test_pcapng.py

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions