构建长度小于8位的Scapy数据包字段

4 投票
1 回答
2816 浏览
提问于 2025-04-17 05:00

我正在尝试用scapy添加一个新协议,但在构建一些存储其他BitEnumField“数据包”的数据包时遇到了困难,这些数据包的长度不到一个字节。我想知道有没有什么方法可以解决这个问题(不把数据包打包成完整的字节字段)。下面是一个例子:

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

现在我明白为什么Status().show2()会失败,因为pkt只有4位长。但是这个也出问题了(我想是因为每个数据包都是独立形成的):

class TotalStatus(Packet):
    name = "8 bit status"

    fields_desc = [
        PacketField('axis0', Status(), Status),
        PacketField('axis1', Status(), Status),
        ]

TotalStatus().show2()会给你一个很长的错误追踪,最后在self.post_build()的时候出错,无法把pkt元组和其他的负载(这是个空字符串)连接起来。也就是说:>>> TypeError: can only concatenate tuple (not "str") to tuple

有没有办法避免把比特字段打包成完整的字节呢?

1 个回答

4

我想一个数据包(Packet)总是以字节为单位对齐,所以你可能需要以某种方式使用一个字段,比如:

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"),
  ] 

撰写回答