首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将dpkt与802.1Q和SLL结合使用?

如何将dpkt与802.1Q和SLL结合使用?
EN

Stack Overflow用户
提问于 2020-03-27 22:51:52
回答 1查看 714关注 0票数 1

我正在编写python中的PCAP,并使用dpkt读取它。数据在PCAP文件是Linux熟捕获,SLL为朋友。这是一个示例包,如Wireshark中所示:

代码语言:javascript
运行
复制
Frame 3: 578 bytes on wire (4624 bits), 578 bytes captured (4624 bits)
Linux cooked capture
    Packet type: Unicast to another host (3)
    Link-layer address type: 1
    Link-layer address length: 6
    Source: VMware_ZZ:ZZ:ZZ (ZZ:ZZ:ZZ:ZZ:ZZ:ZZ)
    Unused: 0000
    Protocol: IPv4 (0x0800)
Internet Protocol Version 4, Src: XX.X.XX.XX, Dst: YYY.YY.YYY.YYY
Transmission Control Protocol, Src Port: 65382, Dst Port: 443, Seq: 1, Ack: 1, Len: 522
Transport Layer Security

这是用于获取TCP数据的代码

代码语言:javascript
运行
复制
import dpkt

pcap_path = 'example-packet.pcap'
with open(pcap_path, 'rb') as fp:
    try:
        capture = dpkt.pcap.Reader(fp)
    except ValueError as e:
        raise Exception("Wrong file: %s" % e)

    for timestamp, buf in capture:
        eth = dpkt.sll.SLL(buf)
        print("Ethernet: ", eth)
        ip = eth.data
        print("IP: ", ip)
        tcp = ip.data         # <-- This is line 15, for error reference
        print("TCP: ", tcp)

这就是代码output是字节编码的,但这很好,因为程序的其他部分并不关心,我不需要让它具有可读性:

代码语言:javascript
运行
复制
Ethernet: b'\x00\x03\x00\x01\x00\x06\x00PV\x9auT\x00\x00\x08\x00E\x00\x05\x8cT3@\x00...
IP: b'E\x00\x05\x8cT3@\x00\x80\x06O\x1f\xac\x1f\xaed\xc6\x8f1\x06\x01\xbb%\x7f\xccz...
TCP: b'\x01\xbb%\x7f\xccz\xdf\x9d\xe5\xbe\xb98\x80\x10\x01\xfd\x047\x00\x00\x01\x01...

现在,问题。我转到另一个PCAP,它仍然是一个Linux熟捕获,但是这个PCAP有IP over 802.1QVLAN。这里有问题包

代码语言:javascript
运行
复制
Frame 11: 577 bytes on wire (4616 bits), 577 bytes captured (4616 bits)
Linux cooked capture
    Packet type: Unicast to another host (3)
    Link-layer address type: 1
    Link-layer address length: 6
    Source: Cisco_ZZ:ZZ:ZZ (ZZ:ZZ:ZZ:ZZ:ZZ:ZZ)
    Unused: 0000
    Protocol: 802.1Q Virtual LAN (0x8100)
802.1Q Virtual LAN, PRI: 0, DEI: 0, ID: 1328
    000. .... .... .... = Priority: Best Effort (default) (0)
    ...0 .... .... .... = DEI: Ineligible
    .... 0101 0011 0000 = ID: 1328
    Type: IPv4 (0x0800)
Internet Protocol Version 4, Src: XXX.XX.XXX.XX, Dst: YY.YYY.YYY.YY
Transmission Control Protocol, Src Port: 54545, Dst Port: 443, Seq: 1, Ack: 1, Len: 517
Transport Layer Security

但是,如果我运行相同的代码,这就是我得到的输出:

代码语言:javascript
运行
复制
Traceback (most recent call last):
  File "myproject.py", line 15, in <module>
    tcp = ip.data
AttributeError: 'bytes' object has no attribute 'data'
Ethernet: b'\x00\x03\x00\x01\x00\x06\x00PV\xa7(\x93\x00\x00\x81\x00\x050\x08\x00E\x00\x00...
IP: b'\x050\x08\x00E\x00\x00\xb2\xba\xd6@\x004\x06y\xf7_\xf9H \xac\x15\xbdI...

现在,我想问题在于添加到数据包中的4字节802.1Q : eth.data被读取为字节,因为没有IP头被识别,所以当我去做ip.data时,就没有属性'data‘了。但我不知道如何绕过这个问题。如果这是另一个捕获,我知道dpkt有一个dpkt.ethernet.VLANTag8021Q类,但就我尝试过的情况而言,这并不适用于Linux熟捕获。我可以考虑迁移到dpkt以外的库中,但我真的不想这么做,因为这是一个工作项目的一部分,有着非常严格的截止日期。

那么,当TCP数据在IP上、802.1Q上、SLL上有dpkt时,如何访问它们呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-28 09:26:44

我很惭愧我以前没这么想过。由于eth.data标记被视为字节,所以它是sliceable.Therefore:

代码语言:javascript
运行
复制
for timestamp, buf in capture:
    eth = dpkt.sll.SLL(buf)
    print("Ethernet: ", eth)
    ip = eth.data
    print("IP: ", ip)
    tcp = ip.data
    print("TCP: ", tcp)

变成这样:

代码语言:javascript
运行
复制
for timestamp, buf in capture:
    eth = dpkt.sll.SLL(buf)
    print("Ethernet: ", eth)

    if not isinstance(eth.data, dpkt.ip.IP):
        vlan_tag = dpkt.ethernet.VLANtag8021Q(eth.data[:4])
        ip = dpkt.ip.IP(eth.data[4:])
    else:
        ip = eth.data

    print("IP: ", ip)
    tcp = ip.data
    print("TCP: ", tcp)

仅此而已。

请注意进一步的参考,因为我已经知道我的整个捕获仅由IP包组成。如果捕获中有其他协议,这将有不同的行为,您将不得不修改If - Tag语句,以便检查这4个字节,寻找IP头或VLAN标记。我实际上可以这样做,因为它是更正确的,但这超出了这个问题的范围。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60895161

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档