Scapy 可变长度字段

2023-12-22

我试图理解 PacketListField 和 FieldListField 之间的区别。有人可以让我知道在添加新协议时如何使用它们吗?

我也不清楚StrLenField、FieldLenField和PacketLenField。我正在尝试制作一条 BGP 更新消息,以便我能够了解它是如何工作的。我看到这就是 BGPUpdate 消息的定义方式。当我尝试制作 BGP 数据包时,我不确定如何传递“撤回路由”字段和 nlri 字段的值。我也不确定如何传递路径属性的值。

>>> pkt=BGPUpdate()
>>> pkt.show()
###[ BGP Update fields ]###
  withdrawn_len= None
  withdrawn= []
  tp_len= None
  \total_path\
  nlri= []
>>>                        

class BGPPathAttribute(Packet):
"the attribute of total path"
    name = "BGP Attribute fields"
    fields_desc = [
    FlagsField("flags", 0x40, 8, ["NA0","NA1","NA2","NA3","Extended-Length","Partial","Transitive","Optional"]), #Extened leght may not work
    ByteEnumField("type", 1, {1:"ORIGIN", 2:"AS_PATH", 3:"NEXT_HOP", 4:"MULTI_EXIT_DISC", 5:"LOCAL_PREF", 6:"ATOMIC_AGGREGATE", 7:"AGGREGATOR"}),
    ByteField("attr_len", None),
    StrLenField("value", "", length_from = lambda p: p.attr_len),
   ]
   def post_build(self, p, pay):
        if self.attr_len is None:
            l = len(p) - 3 # 3 is regular length with no additional options
            p = p[:2] + struct.pack("!B",l)  +p[3:]
        return p+pay
    def extract_padding(self, p):
        """any thing after this packet is extracted is padding"""
        return "",p

class BGPUpdate(Packet):
    """Update the routes WithdrawnRoutes = UnfeasiableRoutes"""
    name = "BGP Update fields"
    fields_desc = [
        ShortField("withdrawn_len", None),
        FieldListField("withdrawn",[], BGPIPField("","0.0.0.0/0"), length_from=lambda p:p.withdrawn_len),
        ShortField("tp_len", None),
        PacketListField("total_path", [], BGPPathAttribute, length_from = lambda p: p.tp_len),
        FieldListField("nlri",[], BGPIPField("","0.0.0.0/0"), length_from=lambda p:p.underlayer.len - 23 - p.tp_len - p.withdrawn_len), # len should be BGPHeader.len
        ]
    def post_build(self,p,pay):
        wl = self.withdrawn_len
        subpacklen = lambda p: len ( str( p ))
        subfieldlen = lambda p: BGPIPField("", "0.0.0.0/0").i2len(self,  p )
        if wl is None:
            wl = sum ( map ( subfieldlen , self.withdrawn))
            p = p[:0]+struct.pack("!H", wl)+p[2:]
        if self.tp_len is None:
            l = sum ( map ( subpacklen , self.total_path))
            p = p[:2+wl]+struct.pack("!H", l)+p[4+wl:]
        return p+pay

它们只是对不同类型的对象进行操作。看scapy 构建解剖 http://www.secdev.org/projects/scapy/doc/build_dissect.html

数据包列表字段

描述了一个列表数据包字段同一类型,而一个数据包字段代表一个Packet类型对象放入另一个数据包字段中。它以数据包原型作为第三个参数cls __init__(self, name, default, cls, count_from=None, length_from=None)。 PacketListField 的构造函数需要设置 count_from (对象数量)或 lengt_from (字节)参数,以便了解要传递到数据包列表的字节数或要解析的对象数。(例如,您可以有BGPUpdate作为 PacketField 或 PacketListField 的原型)。

例如:

PacketListField("total_path", [], BGPPathAttribute, length_from = lambda p: p.tp_len),

创建一个名为“total_path”的字段,默认值为空列表 [],并尝试将 raw_bytestream 的 length_from 字节解析为 BGPPathAttribute(Packet)。

字段列表字段

相比之下字段列表字段将 Field 作为原型并尝试将 raw_bytestream 剖析为原型字段列表__init__(self, name, default, field, length_from=None, count_from=None):

FieldListField("withdrawn",[], BGPIPField("","0.0.0.0/0"), length_from=lambda p:p.withdrawn_len),

字段长度

通常最多可容纳 length_from 字节的 DataField__init__(self, name, default, fld=None, length_from=None):.

场Len场

保存同一数据包中另一个字段长度的数字字段__init__(self, name, default, length_of=None, fmt = "H", count_of=None, adjust=lambda pkt,x:x, fld=None):

class SomePacket(Packet):
    name = "SomePacket"
    fields_desc = [ByteEnumField("type", 0x00, {0x00:"SomeType"}),  
                  FieldLenField("length", None, length_of="data"),          # hold length of data
                  StrLenField("data", "", length_from=lambda x:x.length),   # holds data
                  ]

解剖中, scapy 会将第一个字节放入“type”,接下来的 2 个字节(默认 fmt="H" 表示短整型“length”,最多将“length”个字节放入“data”

On build,scapy会自动用len(data)填充'length'。

数据包长度字段

是一个将 length_from 字节解析为一个原型数据包的字段__init__(self, name, default, cls, length_from=None):

class AnotherPacket(Packet):
    name = "AnotherPacket"
    fields_desc = [
                  BLenField("length", None, length_of="data"),
                  PacketLenField("data", None, SomePacket, length_from=lambda x:x.length),]
                  ]

解剖中,scapy 会将第一个字节放入 ByteLengthField 'length' 中,并将最多 'length' 个字节解析为 'SomePacket' 放入 'data' 中

On build,scapy 会自动用序列化 SomePacket 的大小填充“length”。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Scapy 可变长度字段 的相关文章

  • docker-compose:容器之间的 Redis 连接被拒绝

    我正在尝试设置一个 docker compose 文件 该文件旨在替换运行多个进程 RQ 工作线程 RQ 仪表板和 Flask 应用程序 的单个 Docker 容器解决方案导师 http supervisord org 主机系统是 Debi
  • 在 sympy 绘图中,如何获得具有固定纵横比的绘图?

    如果我用这个片段画一个圆 from sympy import x y symbols x y p1 plot implicit Eq x 2 y 2 1 aspect ratio 1 1 我会得到一个像这样的图形窗口 现在长宽比不是我所期望
  • 如何在模型 Django 中创建必需:布尔字段

    我有一个模型 其中有一个名为的字段is student and is teacher Student and Teacher forms is teacher models BooleanField teacher status defau
  • python 打开相对文件夹中所有以.txt结尾的文件

    我需要打开并解析文件夹中的所有文件 但我必须使用相对路径 类似于 input files 我知道在 JavaScript 中你可以使用 path 库来解决这个问题 我怎样才能在Python中做到这一点 这样您就可以获得路径中的文件列表作为列
  • Python绕相机轴旋转图像

    假设我有一个图像 是在对某些原始图像应用单应性变换 H 后获得的 未显示原始图像 将单应性 H 应用于原始图像的结果是该图像 我想围绕合适的轴 可能是相机所在的位置 如果有的话 将此图像旋转 30 度以获得此图像 如果我不知道相机参数 如何
  • 如何逐行替换(更新)文件中的文本

    我试图通过读取每一行 测试它 然后写入是否需要更新来替换文本文件中的文本 我不想保存为新文件 因为我的脚本已经先备份文件并对备份进行操作 这是我到目前为止所拥有的 我从 os walk 获取路径 并且保证 pathmatch var 正确返
  • 将元组列表转换为字符串 Python

    例如 我用 python 编写了一个返回列表的函数 1 1 2 2 3 3 但我希望输出为字符串 这样我就可以用另一个字符替换逗号 这样输出就是 1 1 2 2 3 3 有什么简单的方法可以解决这个问题吗 感谢您提前提供任何提示 这看起来像
  • 为什么 np.linalg.norm(..., axis=1) 比写出向量范数公式慢?

    标准化矩阵的行X对于单位长度 我通常使用 X np linalg norm X axis 1 keepdims True 在尝试优化算法的此操作时 我非常惊讶地发现在我的机器上写出标准化的速度大约快了 40 X np sqrt X 0 2
  • PRAW 出现 SSLError?

    我正在尝试开始使用 PRAW 但在使用 login 时遇到问题 我有以下代码 import praw r praw Reddit This is a test bot r login myRedditUsername password 我收
  • UTF-8 解码如何知道字节边界?

    我一直在阅读大量有关 unicode 编码的文章 尤其是有关 Python 的文章 我想我现在对此已经有了相当深入的了解 但仍有一个小细节我有点不确定 解码如何知道字节边界 例如 假设我有一个带有两个 unicode 字符的 unicode
  • Django 单元测试数据库没有被拆除?

    我编写了一些单元测试来测试我的 Django 应用程序 特别是一个测试套件中包含大量代码setUp 功能 所述代码的目的是为数据库创建测试数据 是的 我了解固定装置 并且选择在这种情况下不使用它们 当我运行单元测试套件时 运行的第一个测试通
  • Python textwrap.wrap 导致 \n 问题

    所以我只是重新格式化了一堆代码以合并textwrap wrap 却发现我所有的 n都消失了 这是一个例子 from textwrap import wrap def wrapAndPrint msg width 25 wrap msg to
  • Python 的二进制字符串列表

    我有一个像这样的二进制字符串 1100011101 我想将其解析为一个列表 其中每个 1 或 0 块都是列表中的单独值 例如 1100011101 变成 11 000 111 0 1 您可以通过使用正则表达式而不是从中获得一点 次要 性能g
  • 尝试安装 python 包 Box2D 时出错

    我正在尝试通过 pip 安装 Box2D 软件包的版本 2 3 10 但是 pip 返回以下错误消息 ERROR Could not find a version that satisfies the requirement Box2D 2
  • “gi.repository.Gtk”对象没有属性“gdk”

    我正在尝试使用 GTK 创建多线程 需要 Gtk gdk 但我收到有关没有 gdk 属性的错误 我正在使用带有 Raspbian 的 Raspberry Pi 这就是我导入 GTK 库的方式 try import pygtk pygtk r
  • 无法从源 pylance 解析导入烧瓶

    我正在学习 Python 课程的一部分是使用 Flask 设置网络服务器 我按照 Flask 安装文档执行了步骤 由于某种原因 flask 模块带有下划线 如下所示 当我将鼠标悬停时 我会得到如下附加信息 无法从源 pylance 解析导入
  • 类型错误:不可散列的类型:pandas 的“切片”

    我有一个 pandas 数据结构 我这样创建 test inputs pd read csv input test csv delimiter 它的形状 print test inputs shape is this 28000 784 我
  • 如何在Python中仅列出顶级目录?

    我希望能够仅列出某个文件夹内的目录 这意味着我不需要列出文件名 也不需要其他子文件夹 让我们看看一个例子是否有帮助 在当前目录中我们有 gt gt gt os listdir os getcwd cx Oracle doc DLLs Doc
  • Python,质数检查器[重复]

    这个问题在这里已经有答案了 你好 我正在创建一个函数来检查一个数字是否是素数 但它告诉我 9 是一个素数 def eprimo num if num lt 2 return False if num 2 return True else f
  • PyQt 和 QSignalMapper/lambdas - 多个信号,单槽

    我在 PyQt 的菜单上有一个操作列表 每个操作对应我想要显示的每个不同的提要 所以我有一个 Y 将活动源设置为 Y Z 将其设置为 Z 等等 对于网络漫画阅读程序 我的菜单上都有 并且觉得自动化方法可能更好 而不是每次都打字 类似于将其添

随机推荐