Building scapy packets with PacketFields shorter than 8 bits
سؤال
I'm trying to add a new protocol with scapy, and I'm running into difficulties building packets that store other BitEnumField "packets" that are under one byte of length. I was wondering if there is a workaround to make it work (without bundling packets into full byte fields). Here is the example:
from scapy.packet import Packet
from scapy.fields import *
class Status(Packet):
name = '4 bit status'
fields_desc = [
BitEnumField('a', 0, 1, {0:'Disabled', 1:'Enabled'}),
BitEnumField('b', 0, 1, {0:'Disabled', 1:'Active'}),
BitEnumField('c', 0, 1, {0:'Disabled', 1:'Active'}),
BitEnumField('d', 0, 1, {0:'Disabled', 1:'Active'}),
]
#this is added for debug purposes only
def post_build(self, pkt,pay):
print "pkt:", pkt, "type:", type(pkt)
return pkt+pay
Now I can understand why Status().show2()
fails with pkt
being only 4 bits long. but this one dies too (I guess because each packet is formed independently):
class TotalStatus(Packet):
name = "8 bit status"
fields_desc = [
PacketField('axis0', Status(), Status),
PacketField('axis1', Status(), Status),
]
TotalStatus().show2()
gives you lengthy traceback that ends in self.post_build()
unable to cat pkt
tuple and the rest of payload, which is empty string. I.e.:>>> TypeError: can only concatenate tuple (not "str") to tuple
Is there any way to avoid bundling of bit fields into full bytes?
المحلول
I guess that a Packet is always byte aligned so you may have to use a field somehow, e.g:
class StatusField(FlagsField):
name = '4 bit status'
def __init__(self, name):
FlagsField.__init__(self, name, 0, 4, ["a", "b", "c", "d"])
class TotalStatus(Packet):
name = "8 bit status"
fields_desc = [
StatusField("axis0"),
StatusField("axis1"),
]