我在运行 Linux 的两台 PC 之间生成流量(通过发送以太网帧),目的是捕获一些错误帧。问题是当Phy层在帧上检测到错误时(如果CRC或FCS无效),则该帧被丢弃,我无法在程序中接收到它。

有什么方法可以接收错误的帧(例如,禁用Phy层中的丢包并接收指示该帧错误的指示符),以及如何查询NIC卡的统计信息(丢包的数量等)? )。

最佳答案

您没有指定哪个操作系统,但我至少可以代表 Linux:
这可能取决于您的内核、网卡和驱动程序以及 ethtool 版本。
我们需要告诉驱动程序/硬件做两件它通常不会做的事情:

  • 将 FCS 字段向上传递到网络堆栈。 (通常这在被传递之前会被截断)
  • 不丢弃带有错误 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 时,我还没有找到能够做到这一点的 NIC,并且不得不依赖更复杂的数据采集卡。
    同样,我不知道最低内核/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]
    

    10-07 13:47