pythonscapy

How do I get a scapy field as bytes?


I converted raw bytes into a scapy Ether instance like this:

scapy_packet = Ether(data)

Now I want to get the source mac address of this frame as bytes. So assuming the source mac address is 01:02:03:04:05:06, I want the same object as bytes((0x01, 0x02, 0x03, 0x04, 0x05, 0x06)) would create.

How can I go about this? I feel like there should be a trivial way to do this. I obviously do not want to convert the mac address string back into a bytes object because then I essentially converted the bytes into a string just to convert it back into bytes.

And yes, I know I could just do data[6:12] with the raw bytes, but I also want this approach for other things like the IP address, whose position is not fixed. I want to get this value from scapy.

I am using Python 3.9.5.

The following things have thus far been unsuccessful:

bytes(scapy_packet.src) -> TypeError: string argument without an encoding

scapy_packet[Ether].src.__bytes__() -> 'str' object has no attribute '__bytes__'

bytes(scapy_packet[Ether].src) -> TypeError: string argument without an encoding

scapy_packet.src.__bytes__() -> 'str' object has no attribute '__bytes__'

bytes(scapy_packet.get_field("src")) -> TypeError: cannot convert 'SourceMACField' object to bytes

scapy_packet.get_field("src").__bytes__() -> AttributeError: 'SourceMACField' object has no attribute '__bytes__'


Solution

  • You can use something like this: (doc)

    def get_field_bytes(pkt, name):
         fld, val = pkt.getfield_and_val(name)
         return fld.i2m(pkt, val)
    

    Demo:

    >>> a = Ether(src="aa:aa:aa:aa:aa:aa")/IP(dst="192.168.0.1")
    >>> get_field_bytes(a[Ether], "src")
    b'\xaa\xaa\xaa\xaa\xaa\xaa'
    >>> get_field_bytes(a[IP], "dst")
    b'\xc0\xa8\x00\x01'