如何接收错误的以太网帧并禁用 CRC/FCS 计算?
Posted
技术标签:
【中文标题】如何接收错误的以太网帧并禁用 CRC/FCS 计算?【英文标题】:How can i receive the wrong Ethernet frames and disable the CRC/FCS calcul? 【发布时间】:2014-04-01 20:07:03 【问题描述】:我在运行 Linux 的两台 PC 之间生成流量(通过发送以太网帧),其目的是捕获一些错误帧。问题是当 Phy 层检测到帧上的错误(如果 CRC 或 FCS 无效)时,该帧被丢弃并且我无法在我的程序中接收它。
是否有任何方法接收错误帧(例如禁用物理层中的丢弃并接收指示该帧错误的指示器)以及如何查阅 NIC 卡的统计信息(丢弃数。 ..等)。
【问题讨论】:
这将取决于平台。假设驱动程序支持,您需要进行某种设备驱动程序 ioctl() 调用。 是的,我正在寻找一种方法让设备不会丢弃坏帧(交付它们并通知我它们是坏帧) 现代以太网接口会检查 FCS 并丢弃硬件中的坏帧,从不将帧发送到软件。 【参考方案1】:您没有指定哪个操作系统,但我至少可以为 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 选项“固定”关闭或不响应。
我看到 e1000 卡在 1G 速度下运行良好。在 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]
【讨论】:
我正在使用 ubuntu 12.04 我尝试使用 ethtool 工具,但我没有 rx-fcs 和 rx-all 参数。这是我输入 man ethtool ethtool -K|--offload devname [rx on|off] [tx on|off] [sg on|off] [tso on|off] [ufo on|off] 时的参数] [gso on|off] [gro on|off] [lro on|off] [rxvlan on|off] [txvlan on|off] [rxhash on|off] 和 -K --offload 改变指定的卸载参数网络设备。 @A2maridz,好的,我不知道内核/NIC/ethtool 组合工作的完整列表。我已经用我可以访问的一个已知良好的组合更新了答案。 ubuntu 提供什么版本的 ethtool?而且我相信他们将选项放在 -K 下,因为您正在有效地配置卡是否执行 FCS 检查和截断(即卸载它)。【参考方案2】:您可以使用socket()
调用打开raw socket
。例如下面的调用会打开一个raw TCP socket
:
int fd = socket (PF_INET, SOCK_RAW, IPPROTO_TCP);
您可以将协议更改为您想要的任何协议,并且可以确保收到每个数据包。
上面的代码只会让您捕获到好的数据包,因为损坏的数据包甚至不会进入操作系统,并且会在交换机首先或连接到您的 PC 的线卡驱动程序处被丢弃。更多关于同一主题的讨论可以在这里找到Wireshark wiki page
【讨论】:
我想你会发现这行不通。在接收处理期间,MAC 会丢弃坏帧。设备驱动程序需要配置为告诉设备接受坏帧。 是的,同意你的看法。我已经编辑了答案。标准网卡驱动程序会在驱动程序级别自动丢弃损坏的数据包,并且不会将其转发给操作系统,这也是有道理的。但是有什么方法可以配置标准线卡驱动程序甚至将损坏的数据包转发到操作系统? 不,没有标准的方法可以做到这一点。您需要通读驱动程序的源代码,看看驱动程序是否有一个配置选项,可能阅读数据表为芯片自己实现,如果芯片支持的话。 是的,我正在寻找一种方法,让设备不会丢弃坏帧(交付它们并通知我它们是坏的)我认为有办法做到这一点,因为有一些流量生成器可以发送和接收流量并提供统计信息(甚至丢帧)以上是关于如何接收错误的以太网帧并禁用 CRC/FCS 计算?的主要内容,如果未能解决你的问题,请参考以下文章