set_payload() throws TypeError
etkaar opened this issue · 2 comments
After I was able to install NetfilterQueue (see #53), I received a TypeError when using set_payload() after directly changing a payload attribute.
On Debian Stretch this has worked without any problems for years. At this moment I use Debian Buster 10.2, NetfilterQueue 0.8.1, Python 3.7.3 and python3-scapy 2.4.0-2.
pkt = IP(packet.get_payload())
...
pkt[UDP].payload = bytes(response)
...
packet.set_payload(bytes(pkt))
This problem can be fixed using two different ways:
pkt[UDP].remove_payload()
pkt[UDP].add_payload(bytes(response))
pkt[UDP].payload = conf.raw_layer(load=response)
Exception ignored in: 'netfilterqueue.global_callback'
Traceback (most recent call last):
File "modifier.py", line 117, in modify
packet.set_payload(bytes(pkt))
File "/usr/lib/python3/dist-packages/scapy/packet.py", line 345, in __bytes__
return self.build()
File "/usr/lib/python3/dist-packages/scapy/packet.py", line 444, in build
p = self.do_build()
File "/usr/lib/python3/dist-packages/scapy/packet.py", line 425, in do_build
self = next(iter(self))
File "/usr/lib/python3/dist-packages/scapy/packet.py", line 819, in loop
for x in loop(todo[:], done):
File "/usr/lib/python3/dist-packages/scapy/packet.py", line 819, in loop
for x in loop(todo[:], done):
File "/usr/lib/python3/dist-packages/scapy/packet.py", line 819, in loop
for x in loop(todo[:], done):
[Previous line repeated 9 more times]
File "/usr/lib/python3/dist-packages/scapy/packet.py", line 826, in loop
for payl in payloads:
File "/usr/lib/python3/dist-packages/scapy/packet.py", line 819, in loop
for x in loop(todo[:], done):
File "/usr/lib/python3/dist-packages/scapy/packet.py", line 819, in loop
for x in loop(todo[:], done):
File "/usr/lib/python3/dist-packages/scapy/packet.py", line 819, in loop
for x in loop(todo[:], done):
File "/usr/lib/python3/dist-packages/scapy/packet.py", line 831, in loop
pkt = self.clone_with(payload=payl, **done2)
File "/usr/lib/python3/dist-packages/scapy/packet.py", line 804, in clone_with
pkt.add_payload(payload)
File "/usr/lib/python3/dist-packages/scapy/packet.py", line 188, in add_payload
raise TypeError("payload must be either 'Packet' or 'bytes', not [%s]" % repr(payload))
TypeError: payload must be either 'Packet' or 'bytes', not [255]
When I remove python3-scapy (2.4.0-2) and update to scapy 2.4.3 via pip3, the error message changes:
Exception ignored in: 'netfilterqueue.global_callback'
Traceback (most recent call last):
File "modifier.py", line 117, in modify
packet.set_payload(bytes(pkt))
File "/usr/local/lib/python3.7/dist-packages/scapy/packet.py", line 487, in __bytes__
return self.build()
File "/usr/local/lib/python3.7/dist-packages/scapy/packet.py", line 607, in build
p = self.do_build()
File "/usr/local/lib/python3.7/dist-packages/scapy/packet.py", line 588, in do_build
self = next(iter(self))
File "/usr/local/lib/python3.7/dist-packages/scapy/packet.py", line 960, in loop
for x in loop(todo[:], done):
File "/usr/local/lib/python3.7/dist-packages/scapy/packet.py", line 960, in loop
for x in loop(todo[:], done):
File "/usr/local/lib/python3.7/dist-packages/scapy/packet.py", line 960, in loop
for x in loop(todo[:], done):
[Previous line repeated 9 more times]
File "/usr/local/lib/python3.7/dist-packages/scapy/packet.py", line 968, in loop
if self.fields == done and payloads.__iterlen__() == 1:
File "/usr/local/lib/python3.7/dist-packages/scapy/packet.py", line 1023, in __iterlen__
return length * self.payload.__iterlen__()
AttributeError: 'bytes' object has no attribute '__iterlen__'
I think the problem here is how you are building the packet with Scapy and not the netfilterqueue.
This fails not because set_payload()
function of netfilterqueue, but the bytes()
of the scapy Packet object:
packet.set_payload(bytes(pkt))
Closing because this is not netfilterqueue's fault.