Search code examples
pythonnetwork-programmingscapy

Scapy bit fields to preserve leading 0's


I'm about to implement a new protocol layer. Currently, I'm stuck with the implementation of the first class inheriting from packet. This class only has two fields: f_code = 4 bit address = 12 bit.

The problem is that I tried to use BitField, but this class does convert to int, which eliminated leading 0's, so the resultant packet isn't always 16 bit in size.

Another idea would be to handle this fields as string, but I can't find the best field type for that.
I tried xStrField, the problem here is, that the size of this fields in my packet isn't always a full multiple of 8, but rather 0.5 * 8 (4 bit) and 1.5 * 8 (12 bit),

class xy(Packet):
    name = "xy packet"

    fields_desc = [
        XStrField("f_code", b'\x00' * 0.5),
        XStrField("s_address", b'\x00' * 1.5)
    ]

which throws the error

XStrField("f_code", b'\x00' * 0.5), 
TypeError: can't multiply sequence by non-int of type 'float'

Has anyone a idea what to do here? The Documentation for fields is rather incomplete in describing all the respective fields, Scapy Fields Documentation. I'm expecting that a Packet of my class which is initialized like:

xy = XY(f_code=0x1, s_address=0x420)

results in a 0x4420, binary representation of: 0100 0100 0010 0000


Solution

  • This is the working solution for me, I had to use BitEnumField & BitField:

    class xy(Packet): name = "xy packet"

    fields_desc = [     
        BitEnumField(name="f_code", default=None, enum=MY_TYPES, size=4),
        BitField("s_address", 0, 12)    
    ]