![tcpdump 从 pcap 读取 ipv4 和 ipv6 数据包](https://linux22.com/image/1573241/tcpdump%20%E4%BB%8E%20pcap%20%E8%AF%BB%E5%8F%96%20ipv4%20%E5%92%8C%20ipv6%20%E6%95%B0%E6%8D%AE%E5%8C%85.png)
我正在尝试从 TCP 和 UDP 的有效负载中获取一些信息。过滤器
(tcp.stream && tcp.flags.push == 1) || udp.stream
在Wireshark给我 IPv4 和 IPv6 数据包。
但我不知道如何通过tcpdump。 我试过:
tcpdump -X 'tcp[tcpflags] & tcp-push != 0 or udp' -r some.pcap
但只有 IPv4 数据包。例如
tcpdump -X '((tcp[tcpflags] & tcp-push != 0) or udp) and (ip or ip6)' -r some.pcap
也仅显示 IPv4 数据包。任何示例都会有所帮助。
答案1
也许这会对你有帮助:
tcpdump 'ip6[6]==17 or udp or (ip6[6]==6 and ip6[53]&8!=0) or tcp[13]&8!=0' -X -r some.pcap
在tcpdump你无法按照你尝试的方式检索 ipv6 数据包,因为它不支持(至少到 4.9.2 版本)ipv6 下的 BPF 过滤器。
所以,
ip6[6]==17
方法IPv6 上的 UDP(第 6 个字节是 ipv6-header 协议字段),ip6[6]==6
意味着ipv6 上的 tcp分别;ip6[53]&8!=0
方法通过 IPv6 进行 TCP 推送(ipv6-header的40个字节,以及tcp-header的第13个字节,也就是tcp-flags);tcp[13]&8!=0
和你的一样tcp[tcpflags] & tcp-push != 0
。
更多信息:ipv6 tcpip 袖珍指南和这里。
请记住(!):如果存在任何扩展标头,则使用ip6[6]
来识别协议会失败(正如卡斯帕德). 有关 IPv6 扩展标头的更多信息这里。因此,这种方式 tcp 数据包通过带扩展头的 ipv6将不会被捕获。
此外,您可以为特定目的(例如获取有效负载的最后一个字符)编写自己的简单过滤器,例如:
perl -le 'print map { /(?:Flags \[P\.\]|UDP).*(\S)$/s } split /\d{2}:\d{2}:\d{2}\.\d{6}/, `tcpdump -X -r some.pcap 2>/dev/null`'