创建 Scapy 层时的扩展字段(链接字节)
Extended fields when creating a Scapy Layer (chained bytes)
我正在尝试在 Scapy 中为一个协议创建一个层,该协议具有一个名为 "Extended Field" 的自定义字段类型。
原理很简单,实现起来却很吃力
原理是:
- 字段的第一个字节位于已知位置,后跟可变数量的字节。
- 帧中的任何地方都没有定义字节数。
- 如果一个字节的 LSB 是“1”,那么接下来的字节是该字段的一部分
- 如果一个字节的 LSB 为“0”,那么它就是该字段的结尾。
- 结果是一个位字段,每个字节的 7 个 MSB 位连接在一起
为了简单起见,我做了一张图:
Extended Field Description
我已经阅读了很多关于 Scapy 中可变长度字段的内容,但据我所知,这并不涵盖这种情况。
你觉得可以用Scapy Layer来实现吗?任何帮助将不胜感激。
好的,我在深入研究 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)
我正在尝试在 Scapy 中为一个协议创建一个层,该协议具有一个名为 "Extended Field" 的自定义字段类型。
原理很简单,实现起来却很吃力
原理是:
- 字段的第一个字节位于已知位置,后跟可变数量的字节。
- 帧中的任何地方都没有定义字节数。
- 如果一个字节的 LSB 是“1”,那么接下来的字节是该字段的一部分
- 如果一个字节的 LSB 为“0”,那么它就是该字段的结尾。
- 结果是一个位字段,每个字节的 7 个 MSB 位连接在一起
为了简单起见,我做了一张图:
Extended Field Description
我已经阅读了很多关于 Scapy 中可变长度字段的内容,但据我所知,这并不涵盖这种情况。
你觉得可以用Scapy Layer来实现吗?任何帮助将不胜感激。
好的,我在深入研究 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)