Search code examples
pythonpython-3.xscapynetfilter

Convert a scapy "IP" type to "Bytes"


I'm using python3 and nfqueue to modify packets on-the-fly.

Background

Scapy version: 2.4.1

Python's NetfilterQueue (PyPi) has methods to convert packets to "scapy-compatible" strings/bytes and vice versa, these are:

  • get_payload, that returns scapy-compatible string in python 2, BYTES in python 3.

  • set_payload, that sets the packet's payload after we were done with scapy.

Problem

After I use get_payload, I can use scapy's IP() method to modify sections of the packet pleasingly. However, when I'm done, I'm left with an object of type "IP", which I want to convert to type "bytes" (to be able to use set_payload on it).

Code output while printing IP attrs

('nnnn' is the actual packets data in this case)

running...

<class 'scapy.layers.inet.IP'>

b'E\x00\x008\x82\x00@\x00@\x06\xba\xbd\x7f\x00\x00\x01\x7f\x00\x00\x01\xeaj\x1f\x91(\x02\xb9\xffq\xa4\xd6\xbe\x80\x18\x02\x00\xf2W\x00\x00\x01\x01\x08\n\xa8b\x11*\xa8b\x11*nnnn'

b'nnnn'

Argument 'payload' has incorrect type (expected bytes, got IP)

Q

How do I convert type scapy.layers.inet.IP to type "bytes" in python3?


Solution

  • From the source code, you can either call build method or you can pass your IP object to bytes directly as IP implements the __bytes__ dunder method:

    from scapy.layers.inet import IP
    
    p = IP(dst="github.com")
    
    print(p)         # b'E\x00\x00\x14\x00\x01\x00\x00@\x00l\x82\n\x0c\x02\x05\x8cRv\x04'
    print(p.build()) # b'E\x00\x00\x14\x00\x01\x00\x00@\x00l\x82\n\x0c\x02\x05\x8cRv\x04'
    print(bytes(p))  # b'E\x00\x00\x14\x00\x01\x00\x00@\x00l\x82\n\x0c\x02\x05\x8cRv\x04'
    print(raw(p))    # b'E\x00\x00\x14\x00\x01\x00\x00@\x00l\x82\n\x0c\x02\x05\x8cRv\x04'