kamene
kamene copied to clipboard
Big endian systems: RadioTap FlagsField incorrect
Hi, I'm encountering an issue processing the RadioTap headers of packets correctly on big endian systems. For example:
raw = b'\x00\x00\x1a\x00/H\x00\x00\xe1\xd3\xcb\x05\x00\x00\x00\x00@0x\x14@\x01\xac\x00\x00\x00'
r = RadioTap(raw)
r.show()
On big endian system (incorrect):
###[ RadioTap dummy ]###
version = 0
pad = 0
len = 26
present = MCS+b22+b24+b25+b26+b27+Reset
notdecoded= b'\xe1\xd3\xcb\x05\x00\x00\x00\x00@0x\x14@\x01\xac\x00\x00\x00'
On little endian system (correct):
###[ RadioTap dummy ]###
version = 0
pad = 0
len = 26
present = TSFT+Flags+Rate+Channel+dBm_AntSignal+Antenna+RX_Flags
tsft = 97244129
flags = failed
rate = 48
channel_freq= 5240
channel_flags= OFDM+5GHz
dbm_antsignal= -84
antenna = 0
rx_flags =
notdecoded= ''
Also compare integer value of r.present:
- 793247744 on big endian system
- 18479 on little endian
struct.unpack('<I',struct.pack('>I', 793247744))[0] == 18479
clearly seems to be endian related.
Can somebody point me to the likely source of this issue?
Many thanks for all your work on scapy.
It will work on the big endian system if I do the following dodgy hack to reverse the order of bytes for the FlagsField (obviously this is going to break little endian systems and probably a bunch of other stuff too).
--- a/scapy/fields.py
+++ b/scapy/fields.py
@@ -693,6 +693,7 @@ class BitField(Field):
# split the substring byte by byte
bs = struct.unpack('!%dB' % nb_bytes , w)
+ bs = b[::-1]
b = 0
for c in range(nb_bytes):
Ok, the problem seems to be with the reverse function for the BitField class, on a big endian system the socket.ntohl/socket.ntohs functions don't actually reverse the bytes so nothing happens, changing to a more manual method using struct seems to fix the problem:
--- a/scapy/fields.py
+++ b/scapy/fields.py
@@ -657,9 +657,9 @@ class BitField(Field):
self.size = abs(size)
def reverse(self, val):
if self.size == 16:
- val = socket.ntohs(val)
+ val = struct.unpack('>H',struct.pack('<H', val))[0]
elif self.size == 32:
- val = socket.ntohl(val)
+ val = struct.unpack('>I',struct.pack('<I', val))[0]
return val
def addfield(self, pkt, s, val):
Sorry for the multiple comment spam (didn't realise I would find as much myself), hopefully the above, or something like it, will fix this issue.
Great, you found the solution. Can you prepare a pull request? A test case (going into regression.uts) would, also, be nice.