英文:
Create a BitField with dynamic bitwidth in scapy
问题
class CustomPacket(Packet):
name="CustomPacket"
fields_desc = [
BitField("bitstring", 0, 8),
BitField("offsets",0, length_from=xxx),
BitField("_padding",0, length_from=xxx), # to make the whole pkt byte aligned
]
class CustomPacket(Packet):
name = "CustomPacket"
offset_len = 6 # each offset part in the whole string shall be 6 bits long, e.g.
bitstring_len = 8
fields_desc = [
BitField("bitstring", 0, bitstring_len),
StrLenField(
"offsetstring",
0,
length_from=lambda pkt: pkt._calculate_amount_of_offsets(),
),
StrLenField(
"_padding", 0, length_from=lambda pkt: pkt._calculate_needed_padding()
),
]
def _calculate_amount_of_offsets(self):
bits = "{0:08b}".format(self.bitstring)
bits = [int(bit) for bit in list(bits)]
return sum(bits) * self.offset_len
def _calculate_needed_padding(self):
offset_len = self._calculate_amount_of_offsets()
if remainder:= offset_len % 8 != 0:
return 8 - remainder
else:
return remainder
def extract_padding(self, p):
return "", p
英文:
I'm trying to implement a custom Packet
type for scapy. My Problem is that I need BitField
s with a dynamic width depending of another field in the packet:
class CustomPacket(Packet):
name="CustomPacket"
fields_desc = [
BitField("bitstring", 0, 8),
BitField("offsets",0, length_from=xxx),
BitField("_padding",0, length_from=xxx), # to make the whole pkt byte aligned
]
The length should depend on how much 1 are in the 8bit bitstring
field.
I tried it with StrLenField
but that didn't work as the length_from function returns the length in byte not bit, as I understand it:
class CustomPacket(Packet):
name = "CustomPacket"
offset_len = 6 # each offset part in the whole string shall be 6 bits long, e.g.
bitstring_len = 8
fields_desc = [
BitField("bitstring", 0, bitstring_len),
StrLenField(
"offsetstring",
0,
length_from=lambda pkt: pkt._calculate_amount_of_offsets(),
),
StrLenField(
"_padding", 0, length_from=lambda pkt: pkt._calculate_needed_padding()
),
]
def _calculate_amount_of_offsets(self):
bits = "{0:08b}".format(self.bitstring)
bits = [int(bit) for bit in list(bits)]
return sum(bits) * self.offset_len
def _calculate_needed_padding(self):
offset_len = self._calculate_amount_of_offsets()
if remainder:= offset_len % 8 != 0:
return 8 - remainder
else:
return remainder
# necessary for show2()
def extract_padding(self, p):
return "", p
Maybe I can somehow create a own FieldType, but I don't get how I can specify a length function there.
答案1
得分: 0
名字很糟糕,因为它说“Fixed”,但实际上它并没有固定,但你可以使用BitFixedLenField
:https://scapy.readthedocs.io/en/latest/api/scapy.fields.html#scapy.fields.BitFixedLenField 来达到这个目的。
英文:
The name is terrible because it says Fixed
where it's actually not fixed, but you can use BitFixedLenField
: https://scapy.readthedocs.io/en/latest/api/scapy.fields.html#scapy.fields.BitFixedLenField for this purpose.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论