Skip to content

Commit

Permalink
Merge branch 'master' into fix-#499
Browse files Browse the repository at this point in the history
  • Loading branch information
obormot committed Dec 27, 2020
2 parents c1b4cbc + 4ce0b89 commit 0803479
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 27 deletions.
12 changes: 10 additions & 2 deletions dpkt/compat.py
@@ -1,5 +1,6 @@
from __future__ import absolute_import

from struct import pack, unpack
import sys

if sys.version_info < (3,):
Expand All @@ -19,9 +20,9 @@ def compat_ord(char):
except ImportError:
from io import StringIO

try:
try:
from BytesIO import BytesIO
except ImportError:
except ImportError:
from io import BytesIO

if sys.version_info < (3,):
Expand All @@ -37,3 +38,10 @@ def iteritems(d, **kw):

# python3 will return an int if you round to 0 decimal places
intround = round


def ntole(v):
"""convert a 2-byte word from the network byte order (big endian) to little endian;
replaces socket.ntohs() to work on both little and big endian architectures
"""
return unpack('<H', pack('!H', v))[0]
24 changes: 13 additions & 11 deletions dpkt/dpkt.py
@@ -1,15 +1,13 @@
# $Id: dpkt.py 43 2007-08-02 22:42:59Z jon.oberheide $
# -*- coding: utf-8 -*-
"""Simple packet creation and parsing."""
from __future__ import absolute_import
from __future__ import absolute_import

import copy
import socket
import struct
import array
from functools import partial

from .compat import compat_ord, compat_izip, iteritems
from .compat import compat_ord, compat_izip, iteritems, ntole


class Error(Exception):
Expand Down Expand Up @@ -48,7 +46,7 @@ class Packet(_MetaPacket("Temp", (object,), {})):
"""Base packet class, with metaclass magic to generate members from self.__hdr__.
Attributes:
__hdr__: Packet header should be defined as a list of
__hdr__: Packet header should be defined as a list of
(name, structfmt, default) tuples.
__byte_order__: Byte order, can be set to override the default ('>')
Expand Down Expand Up @@ -146,7 +144,7 @@ def __repr__(self):

def __str__(self):
return str(self.__bytes__())

def __bytes__(self):
return self.pack_hdr() + bytes(self.data)

Expand Down Expand Up @@ -200,16 +198,17 @@ def hexdump(buf, length=16):
def in_cksum_add(s, buf):
n = len(buf)
cnt = (n // 2) * 2
a = array.array('H', buf[:cnt])
a = struct.unpack('<{}H'.format(n // 2), buf[:cnt]) # unpack as little endian words
res = s + sum(a)
if cnt != n:
a.append(compat_ord(buf[-1]))
return s + sum(a)
res += compat_ord(buf[-1])
return res


def in_cksum_done(s):
s = (s >> 16) + (s & 0xffff)
s += (s >> 16)
return socket.ntohs(~s & 0xffff)
return ntole(~s & 0xffff)


def in_cksum(buf):
Expand All @@ -222,9 +221,11 @@ def test_utils():
__hd = ' 0000: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e ...............'
h = hexdump(__buf)
assert (h == __hd)
assert in_cksum_add(0, __buf) == 12600 # endianness
c = in_cksum(__buf)
assert (c == 51150)


def test_getitem():
""" create a Packet subclass and access its properties """
class Foo(Packet):
Expand All @@ -244,6 +245,7 @@ class Foo(Packet):
except Exception as e:
assert isinstance(e, KeyError)


def test_pack_hdr_overflow():
""" Try to fit too much data into struct packing """
class Foo(Packet):
Expand All @@ -260,6 +262,7 @@ class Foo(Packet):
else:
assert False, "There should have been an exception raised"


def test_pack_hdr_tuple():
""" Test the unpacking of a tuple for a single format string """
class Foo(Packet):
Expand All @@ -270,4 +273,3 @@ class Foo(Packet):
foo = Foo()
b = bytes(foo)
assert b == b'\x00\x00\x00\x01\x00\x00\x00\x02'

21 changes: 11 additions & 10 deletions dpkt/ieee80211.py
Expand Up @@ -8,6 +8,7 @@
import struct

from . import dpkt
from .compat import ntole

# Frame Types
MGMT_TYPE = 0
Expand Down Expand Up @@ -329,7 +330,7 @@ def unpack(self, buf):

# Strip off the FCS field
if self.fcs_present:
self.fcs = struct.unpack('I', self.data[-1 * FCS_LENGTH:])[0]
self.fcs = struct.unpack('<I', self.data[-1 * FCS_LENGTH:])[0]
self.data = self.data[0: -1 * FCS_LENGTH]

if self.type == MGMT_TYPE:
Expand Down Expand Up @@ -362,7 +363,7 @@ def unpack(self, buf):
if self.type == MGMT_TYPE:
self.unpack_ies(field.data)
if self.subtype in FRAMES_WITH_CAPABILITY:
self.capability = self.Capability(socket.ntohs(field.capability))
self.capability = self.Capability(ntole(field.capability))

if self.type == DATA_TYPE and self.subtype == D_QOS_DATA:
self.qos_data = self.QoS_Data(field.data)
Expand Down Expand Up @@ -421,7 +422,7 @@ def tid(self, val):
def unpack(self, buf):
dpkt.Packet.unpack(self, buf)
self.data = buf[self.__hdr_len__:]
self.ctl = socket.ntohs(self.ctl)
self.ctl = ntole(self.ctl)

if self.compressed:
self.bmp = struct.unpack('8s', self.data[0:_COMPRESSED_BMP_LENGTH])[0]
Expand Down Expand Up @@ -654,7 +655,7 @@ def test_802211_ack():
assert ieee.wep == 0
assert ieee.order == 0
assert ieee.ack.dst == b'\x00\x12\xf0\xb6\x1c\xa4'
fcs = struct.unpack('I', s[-4:])[0]
fcs = struct.unpack('<I', s[-4:])[0]
assert ieee.fcs == fcs

def test_80211_beacon():
Expand All @@ -677,7 +678,7 @@ def test_80211_beacon():
assert ieee.rate.data == b'\x82\x84\x8b\x0c\x12\x96\x18\x24'
assert ieee.ds.data == b'\x01'
assert ieee.tim.data == b'\x00\x01\x00\x00'
fcs = struct.unpack('I', s[-4:])[0]
fcs = struct.unpack('<I', s[-4:])[0]
assert ieee.fcs == fcs

def test_80211_data():
Expand All @@ -689,7 +690,7 @@ def test_80211_data():
assert ieee.data_frame.src == b'\x00\x16\x44\xb0\xae\xc6'
assert ieee.data_frame.frag_seq == 0x807e
assert ieee.data == b'\xaa\xaa\x03\x00\x00\x00\x08\x00\x45\x00\x00\x28\x07\x27\x40\x00\x80\x06\x1d\x39\x8d\xd4\x37\x3d\x3f\xf5\xd1\x69\xc0\x5f\x01\xbb\xb2\xd6\xef\x23\x38\x2b\x4f\x08\x50\x10\x42\x04'
assert ieee.fcs == struct.unpack('I', b'\xac\x17\x00\x00')[0]
assert ieee.fcs == struct.unpack('<I', b'\xac\x17\x00\x00')[0]

from . import llc
llc_pkt = llc.LLC(ieee.data_frame.data)
Expand All @@ -706,7 +707,7 @@ def test_80211_data_qos():
assert ieee.data_frame.frag_seq == 0x207b
assert ieee.data == b'\xaa\xaa\x03\x00\x00\x00\x88\x8e\x01\x00\x00\x74\x02\x02\x00\x74\x19\x80\x00\x00\x00\x6a\x16\x03\x01\x00\x65\x01\x00\x00\x61\x03\x01\x4b\x4c\xa7\x7e\x27\x61\x6f\x02\x7b\x3c\x72\x39\xe3\x7b\xd7\x43\x59\x91\x7f\xaa\x22\x47\x51\xb6\x88\x9f\x85\x90\x87\x5a\xd1\x13\x20\xe0\x07\x00\x00\x68\xbd\xa4\x13\xb0\xd5\x82\x7e\xc7\xfb\xe7\xcc\xab\x6e\x5d\x5a\x51\x50\xd4\x45\xc5\xa1\x65\x53\xad\xb5\x88\x5b\x00\x1a\x00\x2f\x00\x05\x00\x04\x00\x35\x00\x0a\x00\x09\x00\x03\x00\x08\x00\x33\x00\x39\x00\x16\x00\x15\x00\x14\x01\x00'
assert ieee.qos_data.control == 0x0
assert ieee.fcs == struct.unpack('I', b'\xff\xff\xff\xff')[0]
assert ieee.fcs == struct.unpack('<I', b'\xff\xff\xff\xff')[0]

def test_bug():
s = b'\x88\x41\x2c\x00\x00\x26\xcb\x17\x44\xf0\x00\x1e\x52\x97\x14\x11\x00\x1f\x6d\xe8\x18\x00\xd0\x07\x00\x00\x6f\x00\x00\x20\x00\x00\x00\x00'
Expand Down Expand Up @@ -765,7 +766,7 @@ def test_action_block_ack_request():
assert ieee.action.category == BLOCK_ACK
assert ieee.action.code == BLOCK_ACK_CODE_REQUEST
assert ieee.action.block_ack_request.timeout == 0
parameters = struct.unpack('H', b'\x10\x02')[0]
parameters = struct.unpack('<H', b'\x10\x02')[0]
assert ieee.action.block_ack_request.parameters == parameters

def test_action_block_ack_response():
Expand All @@ -775,9 +776,9 @@ def test_action_block_ack_response():
assert ieee.subtype == M_ACTION
assert ieee.action.category == BLOCK_ACK
assert ieee.action.code == BLOCK_ACK_CODE_RESPONSE
timeout = struct.unpack('H', b'\x13\x88')[0]
timeout = struct.unpack('<H', b'\x13\x88')[0]
assert ieee.action.block_ack_response.timeout == timeout
parameters = struct.unpack('H', b'\x10\x02')[0]
parameters = struct.unpack('<H', b'\x10\x02')[0]
assert ieee.action.block_ack_response.parameters == parameters

if __name__ == '__main__':
Expand Down
8 changes: 7 additions & 1 deletion dpkt/pcapng.py
Expand Up @@ -1112,7 +1112,10 @@ def test_custom_read_write():
fobj.close()

# test pcapng customized writing
shb, idb, epb = define_testdata().shb_idb_epb_le
if sys.byteorder == 'little':
shb, idb, epb = define_testdata().shb_idb_epb_le
else:
shb, idb, epb = define_testdata().shb_idb_epb_be

fobj = BytesIO()
writer = Writer(fobj, shb=shb, idb=idb)
Expand Down Expand Up @@ -1238,6 +1241,9 @@ def test_writepkts():
writer.writepkts(pkts)
return pkts

def test_pcapng_block_pack():
assert bytes(_PcapngBlock())

def test_pcapng_block_unpack():
block = _PcapngBlock()
buf = b'012345678901'
Expand Down
5 changes: 2 additions & 3 deletions dpkt/radiotap.py
Expand Up @@ -3,10 +3,9 @@
from __future__ import print_function
from __future__ import absolute_import

import socket

from . import dpkt
from . import ieee80211
from .compat import ntole

# Ref: http://www.radiotap.org
# Fields Ref: http://www.radiotap.org/defined-fields/all
Expand Down Expand Up @@ -234,7 +233,7 @@ def ext_present(self, val):

def unpack(self, buf):
dpkt.Packet.unpack(self, buf)
self.data = buf[socket.ntohs(self.length):]
self.data = buf[ntole(self.length):]

self.fields = []
buf = buf[self.__hdr_len__:]
Expand Down

0 comments on commit 0803479

Please sign in to comment.