创建Scapy层时的扩展字段(链接的字节)

时间:2019-03-12 10:50:06

标签: python scapy

我正在尝试在Scapy中为具有自定义字段类型(称为“扩展字段”)的协议创建一个图层。

原理很简单,但是我很难实现。

原理是:

  • 该字段的第一个字节位于已知位置,后跟可变数量的字节。
  • 未在帧中的任何位置定义字节数。
  • 如果字节的LSB为“ 1”,则随后的字节是该字段的一部分
  • 如果字节的LSB为“ 0”,则为该字段的结尾。
  • 结果是一个位字段,每个字节连接了7个MSB位

我做了一张图片以使其更简单:

Extended Field Description

我已经在Scapy中阅读了很多有关可变长度字段的内容,但据我所知,这并不涉及这种情况。

您认为它可以在Scapy层中实现吗?任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

好吧,在深入研究Scapy之后,我回答了自己。

这是一个可行的解决方案(可能不是最佳解决方案,但对我来说足够了):

from scapy.all import *

class LSBExtendedField(Field):
    """
    LSB Extended Field
    ------------------

    This type of field has a variable number of bytes. Each byte is defined as follows:
    - The 7 MSB bits are data
    - The LSB is an extenesion bit
        * 0 means it is last byte of the field ("stopping bit")
        * 1 means there is another byte after this one ("forwarding bit")

    To get the actual data, it is necessary to navigate the binary data byte per byte and to check if LSB until 0
    """

    """
    Converts bytes to field
    """
    def str2extended(self, l=""):
        s = []
        # First bit is the stopping bit at zero
        bits = 0b0
        # Then we retrieve 7 bits. If "forwarding bit" is 1, then we continue on another byte
        i = 0
        for c in l:
            s.append(hex(c & 0xfe))
            bits = bits << 7 | (int(c) >> 1)
            if not int(c)&0b1:
                end = l[i+1:]
                break
            i=i+1
        return end, bits

    """
    Converts field to bytes
    """
    def extended2str(self, l):
        l=int(l)
        s = []
        # First bit is the stopping bit at zero
        bits = 0b0
        # Then we group bits 7 by 7 adding the "forwarding bit" if necessary
        i=1
        while (l>0):
            if i%8 == 0:
                s.append(bits)
                bits = 0b1
                i=0
            else:
                bits = bits | (l & 0b1) << i
                l = l >> 1
            i = i+1
        s.append(bits)
        s.reverse()

        result = "".encode()
        for x in s:
            result = result + struct.pack(">B", x)
        return result

    def i2m(self, pkt, x):
        return self.extended2str(x)

    def m2i(self, pkt, x):
        return self.str2extended(x)[1]

    def addfield(self, pkt, s, val):
        return s+self.i2m(pkt, val)

    def getfield(self, pkt, s):
        return self.str2extended(s)