【问题标题】:Get all the layers in a packet获取数据包中的所有层
【发布时间】:2012-11-13 00:16:47
【问题描述】:

如何获取 scapy 中所有层的列表? 例如:Ether/IP/UDP/DNSEther/IP/TCP/HTTP。 我唯一能想到的就是做一个packet.summary() 并解析输出,这看起来很粗糙。我认为应该有一个内置的方法,但在文档中找不到任何方法。有什么建议吗?

我要做的是遍历用户给定的特定协议的所有字段并显示其值。

更新: 我正在寻找的东西可以在wireshark中看到:打开任何捕获,选择一个数据包,然后在“框架”菜单中,可以看到 Protocols in frame: eth:ip:udp:data 这正是我在 Scapy 中寻找的。我希望我现在更清楚了。

【问题讨论】:

    标签: python scapy


    【解决方案1】:

    每个附加层都是数据包的有效负载,因此您可以迭代

    def expand(x):
        yield x
        while x.payload:
            x = x.payload
            yield x
    

    然后

    res = list(expand(packet))
    

    我希望这就是你的意思。

    【讨论】:

    • 这并没有给我数据包中的层。它只是打印数据包内容。我正在寻找的东西可以在wireshark中看到:打开任何捕获,选择一个数据包,然后在“框架”菜单中,可以看到Protocols in frame: eth:ip:udp:data。这正是我在 Scapy 中寻找的。我希望我现在更清楚了。
    • 确实如此,只是每个数据包通过构造包含所有上层。看看@eminor,他用我的方法打印了名字。
    【解决方案2】:

    在循环中使用packet.getLayer(<id>)。例如:

    from scapy.all import Ether
    
    def get_packet_layers(packet):
        counter = 0
        while True:
            layer = packet.getlayer(counter)
            if layer is None:
                break
    
            yield layer
            counter += 1
    
    
    packet = 'ffffffffffff00ffd59c64320806000108000604000100ffd59c6432000000000000000000000a000001'.decode('hex')
    packet = Ether(_pkt=packet)
    
    for layer in get_packet_layers(packet):
        print (layer.name)
    

    输出

    Ethernet
    ARP
    

    【讨论】:

    • 输出:Layers are: ['Ethernet', 'IP', 'TCP']
    【解决方案3】:

    我查看了source code并没有找到这样的方法,所以我稍微修改了cronos的代码,它看起来就像你现在想要的那样。

    您可以为 scapy 编写错误报告并提出新方法。

    >>> ip = Ether()/IP()/TCP()
    >>> ip
    <Ether  type=0x800 |<IP  frag=0 proto=tcp |<TCP  |>>>
    >>> ip.name
    'Ethernet'
    >>> def expand(x):
    ...     yield x.name
    ...     while x.payload:
    ...         x = x.payload
    ...         yield x.name
    ... 
    >>> list(expand(ip))
    ['Ethernet', 'IP', 'TCP']
    >>> l=list(expand(ip))
    >>> ":".join(l)
    'Ethernet:IP:TCP'
    >>> 
    

    【讨论】:

    • 当你回答这个问题并登录发布我的答案时,我正在尝试类似的事情!在下面检查我的代码。
    【解决方案4】:

    使用packet.payload.layers(),我得到了数据包的层类列表。然后我可以访问数据包层,例如:

    
    def sniff_callback(packet):
        print(packet.payload.layers())  # display all layers
        first_layer = packet[packet.payload.layers()[0]]  # access first layer of the list
    
    

    【讨论】:

    • 以太网层没有显示在列表中,请问您知道吗?
    猜你喜欢
    • 2014-04-25
    • 1970-01-01
    • 2018-09-26
    • 2021-02-17
    • 2021-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多