我在运行Linux的两台PC之间产生流量(通过发送以太网帧),其目的是捕获一些错误帧。问题是当Phy层检测到帧上的错误时(如果CRC或FCS无效)帧丢失,我无法在程序中接收到它。
是否有任何接收错误帧的方法(禁用Phy层中的丢弃并接收指示此帧错误的指示符)以及如何查询NIC卡的统计信息(丢弃的数量)。 ..等)。
答案 0 :(得分:9)
您没有指定哪个操作系统,但我至少可以代表Linux:
它可能在您的内核,NIC和驱动程序以及ethtool版本上。
我们需要告诉驱动程序/硬件做两件通常不会做的事情: 1)将FCS字段传递到网络堆栈。 (通常这会在被传递之前被截断) 2)不丢弃包含错误FCS字段的数据包,而是将其按原样传递
有两种ethtool选项可以实现这些目标:
ethtool -K eth0 rx-fcs on #1 above: give us the FCS field
ethtool -K eth0 rx-all on #2 above: even receive bad packets
通过这些,我可以使用wireshark或tcpdump来查看FCS字段,即使它们不正确。 (在我的情况下,我有一些网络设备可以使用准确的时间戳来实时替换校验和 - 这会导致数据包显示为“错误”,并使用上述内容进行恢复)
并非所有卡都会实现此功能!他们可能将上述ethtool选项“修复”或不回应。
以1G的速度,我看到e1000卡运行良好。在10G,我还没有找到一个可以完成此任务的网卡,而且必须依赖更复杂的数据采集卡。
同样,我不知道最低内核/ ethtool版本要求是什么,但我确实记得要升级CentOS服务器以使其工作。
我也知道r8169和e1000驱动程序/卡可以做到这一点,但根本不能说任何其他组合。
另请注意,您将无法在发送它们的计算机上捕获传出的FCS值,因为它们在过程中很晚才添加(可能已卸载到卡本身),因此pcap无法看到。
在Linux 3.10.11内核上,使用ethtool 3.10:
$ ethtool -k eth0
Features for eth0:
rx-checksumming: on
tx-checksumming: on
tx-checksum-ipv4: off [fixed]
tx-checksum-ip-generic: on
tx-checksum-ipv6: off [fixed]
tx-checksum-fcoe-crc: off [fixed]
tx-checksum-sctp: off [fixed]
scatter-gather: on
tx-scatter-gather: on
tx-scatter-gather-fraglist: off [fixed]
tcp-segmentation-offload: on
tx-tcp-segmentation: on
tx-tcp-ecn-segmentation: off [fixed]
tx-tcp6-segmentation: on
udp-fragmentation-offload: off [fixed]
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: off [fixed]
rx-vlan-offload: on
tx-vlan-offload: on
ntuple-filters: off [fixed]
receive-hashing: on
highdma: on [fixed]
rx-vlan-filter: on [fixed]
vlan-challenged: off [fixed]
tx-lockless: off [fixed]
netns-local: off [fixed]
tx-gso-robust: off [fixed]
tx-fcoe-segmentation: off [fixed]
tx-gre-segmentation: off [fixed]
tx-udp_tnl-segmentation: off [fixed]
fcoe-mtu: off [fixed]
tx-nocache-copy: on
loopback: off [fixed]
rx-fcs: off
rx-all: off
tx-vlan-stag-hw-insert: off [fixed]
rx-vlan-stag-hw-parse: off [fixed]
rx-vlan-stag-filter: off [fixed]
然后:
$ sudo ethtool -K eth0 rx-fcs on rx-all on
给我:
$ ethtool -k eth0
Features for eth0:
rx-checksumming: on
tx-checksumming: on
tx-checksum-ipv4: off [fixed]
tx-checksum-ip-generic: on
tx-checksum-ipv6: off [fixed]
tx-checksum-fcoe-crc: off [fixed]
tx-checksum-sctp: off [fixed]
scatter-gather: on
tx-scatter-gather: on
tx-scatter-gather-fraglist: off [fixed]
tcp-segmentation-offload: on
tx-tcp-segmentation: on
tx-tcp-ecn-segmentation: off [fixed]
tx-tcp6-segmentation: on
udp-fragmentation-offload: off [fixed]
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: off [fixed]
rx-vlan-offload: on
tx-vlan-offload: on
ntuple-filters: off [fixed]
receive-hashing: on
highdma: on [fixed]
rx-vlan-filter: on [fixed]
vlan-challenged: off [fixed]
tx-lockless: off [fixed]
netns-local: off [fixed]
tx-gso-robust: off [fixed]
tx-fcoe-segmentation: off [fixed]
tx-gre-segmentation: off [fixed]
tx-udp_tnl-segmentation: off [fixed]
fcoe-mtu: off [fixed]
tx-nocache-copy: on
loopback: off [fixed]
rx-fcs: on
rx-all: on
tx-vlan-stag-hw-insert: off [fixed]
rx-vlan-stag-hw-parse: off [fixed]
rx-vlan-stag-filter: off [fixed]
答案 1 :(得分:-1)
您可以使用raw socket
电话打开socket()
。例如,以下调用会打开raw TCP socket
:
int fd = socket (PF_INET, SOCK_RAW, IPPROTO_TCP);
您可以将协议更改为您想要的任何协议,并确保收到每个数据包。
上面的代码只会让你捕获好的数据包,因为损坏的数据包甚至没有进入操作系统,并且在交换机首先或连接到PC的线路卡驱动程序时丢弃。有关同一主题的更多讨论可以在Wireshark wiki page
找到