【问题标题】:How to read packets with VLAN layer如何使用 VLAN 层读取数据包
【发布时间】:2020-08-15 04:23:44
【问题描述】:

我正在用 Python 编写一个程序来读取和解码 .pcap 文件中的 GOOSE 数据包。到目前为止,我已经能够使用 Pypcapfile 库读取数据包:

from pcapfile import savefile
file = input("Enter the name of the pcap file: ")
try:
    pcap = open(file, 'rb')
except IOError:
    print("No file with name \"{}\" was found.\n".format(file))
    return
capfile = savefile.load_savefile(pcap, verbose=True)
print(capfile)

终端:

Enter the name of the pcap file: goose2.pcap
[+] attempting to load goose2.pcap
[+] found valid header
[+] loaded 8023 packets
[+] finished loading savefile.
b'little'-endian capture file version 2.4
microsecond time resolution
snapshot length: 262144
linklayer type: LINKTYPE_ETHERNET
number of packets: 8023

问题是,当我使用包含 VLAN 标头(仅两个字节)的数据包测试我的代码时,它说 pcap 文件有 0 个数据包:

Enter the name of the pcap file: vlan.pcap
[+] attempting to load vlan.pcap
[+] found valid header
[+] loaded 0 packets
[+] finished loading savefile.
b'big'-endian capture file version 2.4
nanosecond time resolution
snapshot length: 65535
linklayer type: LINKTYPE_ETHERNET
number of packets: 0

我围绕 Pypcapfile 库编写了整个代码,因此我想避免从头开始使用另一个库,例如 Scapy。我已经尝试将 "layers=" 参数添加到 load_savefile ,但这不起作用。有没有办法解决这个问题?

【问题讨论】:

  • 您有任何示例数据可以在某处发布吗?
  • 我能够匿名化 goose2.pcap 但不能匿名化 vlan.pcap。如果这仍然有帮助,我应该在哪里发布?
  • 我从 WireShark Sample Captures 页面抓取了 vlanp.cap.gz,但我无法重现您的问题:pcapfile 模块似乎可以很好地读取文件。如果您可以使用该示例文件重现您的问题,那将更容易诊断。
  • 有趣的是,我什至无法使用 load_savefile(未知的幻数)打开文件,但是在我将扩展名重命名为 .pcap 后,它读取良好 - 数据包数:395。我注意到打印(capfile) 输出 b'little'-endian 就像使用 goose2.pcap 一样,而使用 vlan.pcap 它输出 b'big'-endian。
  • 注意vlan.cap.gz是gzip压缩的;在尝试打开它之前,您需要解压缩它 (gunzip vlan.cap.gz)。

标签: python wireshark pcap vlan


【解决方案1】:

以下是我测试结果的方式。我从 wireshark wiki 中抓取了示例 vlan 并解压:

$ curl -o vlan.cap.gz 'https://wiki.wireshark.org/SampleCaptures?action=AttachFile&do=get&target=vlan.cap.gz'
$ gunzip vlan.cap.gz

我们可以使用例如tshark 验证此捕获是否包含带有 VLAN 标记的数据包:

$ tshark -r vlan.cap -V
Frame 1: 1518 bytes on wire (12144 bits), 1518 bytes captured (12144 bits)
[...]
Ethernet II, Src: AniCommu_40:ef:24 (00:40:05:40:ef:24), Dst: 3com_9f:b1:f3 (00:60:08:9f:b1:f3)
[...]
    Type: 802.1Q Virtual LAN (0x8100)
802.1Q Virtual LAN, PRI: 0, DEI: 0, ID: 32
    000. .... .... .... = Priority: Best Effort (default) (0)
    ...0 .... .... .... = DEI: Ineligible
    .... 0000 0010 0000 = ID: 32
    Type: IPv4 (0x0800)
Internet Protocol Version 4, Src: 131.151.32.129, Dst: 131.151.32.21

我可以使用pcapfile 模块打开这个:

$ pip install --user Pypcapfile
$ python
>>> import pcapfile.savefile
>>> with open('vlan.cap', 'rb') as fd:
...   capfile = pcapfile.savefile.load_savefile(fd, layers=2)
...
>>> capfile
b'little'-endian capture file version 2.4
microsecond time resolution
snapshot length: 65535
linklayer type: LINKTYPE_ETHERNET
number of packets: 395
>>> capfile.packets[0]
ethernet from b'00:40:05:40:ef:24' to b'00:60:08:9f:b1:f3' type unknown

但看起来pcapfile 没有针对 VLAN 帧的特定解码器。


dpkt 模块效果很好:

>>> import dpkt
>>> fd = open('vlan.cap', 'rb')
>>> capfile = dpkt.pcap.Reader(fd)
>>> ts, buf = next(capfile)
>>> pkt = dpkt.ethernet.Ethernet(buf)
>>> pkt.vlan_tags
[VLANtag8021Q(pri=0, cfi=0, id=32)]

scapy 也是如此:

>>> import scapy.all
>>> capfile = scapy.all.rdpcap('vlan.cap')
>>> capfile[0].vlan
32

【讨论】:

  • 太棒了,我将尝试将其集成到我的代码中。非常感谢您的帮助!
猜你喜欢
  • 2021-11-23
  • 2014-10-28
  • 2019-11-01
  • 1970-01-01
  • 2020-08-01
  • 1970-01-01
  • 2018-05-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多