Closed mcepl closed 2 years ago
@mcepl I've got a branch up with fixes for big endian, producing no test failures on a PowerPC emulator. I couldn't get the s390x emulator working fast enough. Feel free to give it a try! https://github.com/kbandla/dpkt/tree/fix-big-endian-2
UPD: thanks to @brifordwylie 's speedy review this has been merged to master
I am afraid that even with 1.9.7.2, we are still not there:
[ 261s] =================================== FAILURES ===================================
[ 261s] _____________________________ test_ethernet_unpack _____________________________
[ 261s]
[ 261s] def test_ethernet_unpack():
[ 261s] buf = b'\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x08\x00'
[ 261s] hdr = b'\x00\x02\x00\x02'
[ 261s]
[ 261s] lo = Loopback(hdr + buf)
[ 261s] > assert lo.family == 33554944
[ 261s] E assert 131074 == 33554944
[ 261s] E +131074
[ 261s] E -33554944
[ 261s]
[ 261s] dpkt/loopback.py:46: AssertionError
[ 261s] _______________________________ test_ip6_unpack ________________________________
[ 261s]
[ 261s] def test_ip6_unpack():
[ 261s] import struct
[ 261s] buf = (b'\x60\x00\x00\x00\x00\x14\x06\x38\x26\x07\xf8\xb0\x40\x0c\x0c\x03\x00\x00\x00\x00\x00\x00'
[ 261s] b'\x00\x1a\x20\x01\x04\x70\xe5\xbf\xde\xad\x49\x57\x21\x74\xe8\x2c\x48\x87')
[ 261s] hdr_suffix = b'\x00' * 3
[ 261s]
[ 261s] for family in (24, 28, 30):
[ 261s] hdr = struct.pack('B', family) + hdr_suffix
[ 261s]
[ 261s] lo = Loopback(hdr + buf)
[ 261s] > assert lo.family == family
[ 261s] E assert 402653184 == 24
[ 261s] E +402653184
[ 261s] E -24
[ 261s]
[ 261s] dpkt/loopback.py:73: AssertionError
[ 261s] _____________________________ test_writepkt_epb_ts _____________________________
[ 261s]
[ 261s] args = (), kwargs = {}, fobj = <_io.BytesIO object at 0x3ff9d6b4af0>
[ 261s]
[ 261s] def wrapper(*args, **kwargs):
[ 261s] fobj = BytesIO()
[ 261s] f.__globals__['fobj'] = fobj
[ 261s] > ret = f(*args, **kwargs)
[ 261s]
[ 261s] dpkt/pcapng.py:898:
[ 261s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
[ 261s] dpkt/pcapng.py:1194: in test_writepkt_epb_ts
[ 261s] writer = Writer(fobj, shb=shb, idb=idb) # noqa
[ 261s] dpkt/pcapng.py:371: in __init__
[ 261s] self._validate_block('shb', shb, SectionHeaderBlock)
[ 261s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
[ 261s]
[ 261s] self = <dpkt.pcapng.Writer object at 0x3ff9d8a0438>, arg_name = 'shb'
[ 261s] blk = SectionHeaderBlockLE(opts=[PcapngOptionLE(code=3, data=b'64-bit Windows 8.1, build 9600'), PcapngOptionLE(code=4, data=b'Dumpcap 1.12.7 (v1.12.7-0-g7fc8978 from master-1.12)'), PcapngOptionLE(opt_endofopt)])
[ 261s] expected_cls = <class 'dpkt.pcapng.SectionHeaderBlock'>
[ 261s]
[ 261s] def _validate_block(self, arg_name, blk, expected_cls):
[ 261s] """Check a user-defined block for correct type and endianness"""
[ 261s] if not isinstance(blk, expected_cls):
[ 261s] raise ValueError('{0}: expecting class {1}'.format(
[ 261s] arg_name, expected_cls.__name__))
[ 261s]
[ 261s] if self.__le and blk.__hdr_fmt__[0] == '>':
[ 261s] raise ValueError('{0}: expecting class {1}LE on a little-endian system'.format(
[ 261s] arg_name, expected_cls.__name__))
[ 261s]
[ 261s] if not self.__le and blk.__hdr_fmt__[0] == '<':
[ 261s] raise ValueError('{0}: expecting class {1} on a big-endian system'.format(
[ 261s] > arg_name, expected_cls.__name__.replace('LE', '')))
[ 261s] E ValueError: shb: expecting class SectionHeaderBlock on a big-endian system
[ 261s]
[ 261s] dpkt/pcapng.py:405: ValueError
[ 261s] ____________________________ test_custom_read_write ____________________________
[ 261s]
[ 261s] def test_custom_read_write():
[ 261s] """Test a full pcapng file with 1 ICMP packet"""
[ 261s] buf = define_testdata().valid_pcapng
[ 261s] fobj = BytesIO(buf)
[ 261s]
[ 261s] # test reading
[ 261s] reader = Reader(fobj)
[ 261s] assert reader.snaplen == 0x40000
[ 261s] assert reader.datalink() == DLT_EN10MB
[ 261s]
[ 261s] assert reader.idb.opts[0].data.decode('utf-8') == '\\Device\\NPF_{3BBF21A7-91AE-4DDB-AB2C-C782999C22D5}'
[ 261s] assert reader.idb.opts[2].data.decode('utf-8') == '64-bit Windows 8.1, build 9600'
[ 261s]
[ 261s] ts, buf1 = next(iter(reader))
[ 261s] assert ts == 1442984653.2108380
[ 261s] assert len(buf1) == 74
[ 261s]
[ 261s] assert buf1.startswith(b'\x08\x00\x27\x96')
[ 261s] assert buf1.endswith(b'FGHI')
[ 261s] fobj.close()
[ 261s]
[ 261s] # test pcapng customized writing
[ 261s] if sys.byteorder == 'little':
[ 261s] shb, idb, epb = define_testdata().shb_idb_epb_le
[ 261s] else:
[ 261s] shb, idb, epb = define_testdata().shb_idb_epb_be
[ 261s]
[ 261s] fobj = BytesIO()
[ 261s] writer = Writer(fobj, shb=shb, idb=idb)
[ 261s] writer.writepkt(epb, ts=1442984653.210838)
[ 261s] > assert fobj.getvalue() == buf
[ 261s] E assert b"\n\r\r\n\x0...0\x00\x00\x84" == b"\n\r\r\n|\x...4\x00\x00\x00"
[ 261s] E At index 4 diff: b'\x00' != b'|'
[ 261s] E Full diff:
[ 261s] E (
[ 261s] E - b'\n\r\r\n|\x00\x00\x00M<+\x1a\x01\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff'
[ 261s] E ? - ^^^ ----
[ 261s] E + b'\n\r\r\n\x00\x00\x00|\x1a+<M\x00\x01\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff'
[ 261s] E ? ^ +++++++...
[ 261s] E
[ 261s] E ...Full output truncated (36 lines hidden), use '-vv' to show
[ 261s]
[ 261s] dpkt/pcapng.py:1149: AssertionError
[ 261s] ____________________________ test_multi_idb_writer _____________________________
[ 261s]
[ 261s] def test_multi_idb_writer():
[ 261s] """Test writing multiple interface description blocks into pcapng and read it"""
[ 261s] fobj = BytesIO()
[ 261s] shb, idb, epb = define_testdata().shb_idb_epb_le
[ 261s]
[ 261s] > writer = Writer(fobj, shb=shb, idb=[idb, idb])
[ 261s]
[ 261s] dpkt/pcapng.py:1168:
[ 261s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
[ 261s] dpkt/pcapng.py:371: in __init__
[ 261s] self._validate_block('shb', shb, SectionHeaderBlock)
[ 261s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
[ 261s]
[ 261s] self = <dpkt.pcapng.Writer object at 0x3ff9d930240>, arg_name = 'shb'
[ 261s] blk = SectionHeaderBlockLE(opts=[PcapngOptionLE(code=3, data=b'64-bit Windows 8.1, build 9600'), PcapngOptionLE(code=4, data=b'Dumpcap 1.12.7 (v1.12.7-0-g7fc8978 from master-1.12)'), PcapngOptionLE(opt_endofopt)])
[ 261s] expected_cls = <class 'dpkt.pcapng.SectionHeaderBlock'>
[ 261s]
[ 261s] def _validate_block(self, arg_name, blk, expected_cls):
[ 261s] """Check a user-defined block for correct type and endianness"""
[ 261s] if not isinstance(blk, expected_cls):
[ 261s] raise ValueError('{0}: expecting class {1}'.format(
[ 261s] arg_name, expected_cls.__name__))
[ 261s]
[ 261s] if self.__le and blk.__hdr_fmt__[0] == '>':
[ 261s] raise ValueError('{0}: expecting class {1}LE on a little-endian system'.format(
[ 261s] arg_name, expected_cls.__name__))
[ 261s]
[ 261s] if not self.__le and blk.__hdr_fmt__[0] == '<':
[ 261s] raise ValueError('{0}: expecting class {1} on a big-endian system'.format(
[ 261s] > arg_name, expected_cls.__name__.replace('LE', '')))
[ 261s] E ValueError: shb: expecting class SectionHeaderBlock on a big-endian system
[ 261s]
[ 261s] dpkt/pcapng.py:405: ValueError
[ 261s] =============================== warnings summary ===============================
[ 261s] dpkt/ip.py::test_property_setters
[ 261s] /home/abuild/rpmbuild/BUILD/dpkt-1.9.7.2/dpkt/ip.py:128: UserWarning: IP.off is deprecated
[ 261s] deprecation_warning("IP.off is deprecated")
[ 261s]
[ 261s] dpkt/ip.py::test_property_setters
[ 261s] /home/abuild/rpmbuild/BUILD/dpkt-1.9.7.2/dpkt/ip.py:123: UserWarning: IP.off is deprecated
[ 261s] deprecation_warning("IP.off is deprecated")
[ 262s]
[ 262s] dpkt/ssl.py::TestServerHello::test_ciphersuite
[ 262s] /home/abuild/rpmbuild/BUILD/dpkt-1.9.7.2/dpkt/ssl.py:350: UserWarning: TLSServerHello.cipher_suite is deprecated and renamed to .ciphersuite
[ 262s] deprecation_warning("TLSServerHello.cipher_suite is deprecated and renamed to .ciphersuite")
[ 262s]
[ 262s] dpkt/ssl.py::TestServerHello::test_compression_method
[ 262s] /home/abuild/rpmbuild/BUILD/dpkt-1.9.7.2/dpkt/ssl.py:355: UserWarning: TLSServerHello.compression is deprecated and renamed to .compression_method
[ 262s] deprecation_warning("TLSServerHello.compression is deprecated and renamed to .compression_method")
[ 262s]
[ 262s] -- Docs: https://docs.pytest.org/en/stable/warnings.html
[ 262s] =========================== short test summary info ============================
[ 262s] FAILED dpkt/loopback.py::test_ethernet_unpack - assert 131074 == 33554944
[ 262s] FAILED dpkt/loopback.py::test_ip6_unpack - assert 402653184 == 24
[ 262s] FAILED dpkt/pcapng.py::test_writepkt_epb_ts - ValueError: shb: expecting clas...
[ 262s] FAILED dpkt/pcapng.py::test_custom_read_write - assert b"\n\r\r\n\x0...0\x00\...
[ 262s] FAILED dpkt/pcapng.py::test_multi_idb_writer - ValueError: shb: expecting cla...
[ 262s] ================== 5 failed, 420 passed, 4 warnings in 26.59s ==================
That's with s390x
and ppc64
, all tests pass with x86_64
and similar (including ppc64le
).
These are likely new issues since all earlier issues were fixed. I'll just reopen this ticket.
I used to be a maintainer of PSPP in Fedora and I have learned one thing: endianness is a bitch; forgive me my French. When we started to build on SPARC we had by far more bugs from LE/BE than from anything else combined.
@crocogorical I see you added unit tests to https://github.com/kbandla/dpkt/blob/master/dpkt/loopback.py that are partially failing on big endian. Can you take a look? I have no clue what specific protocol this decoder is processing. There are no references to RFC etc.
Now fixed in master branch, closing.
When building package for dpkt for OpenSUSE/Factory, I get these tests to fail on s390x, which has very weird hardware. Complete build log