如何在软件中可靠地生成以太网帧错误?

时间:2020-12-15 15:06:01

Question:

I'm testing a section of cable-fault finding software, and I'd like to reliably and reproducibly generate cable faults on a cat5 cable.

我正在测试一段电缆故障查找软件,我想在cat5电缆上可靠且可重复地产生电缆故障。

At the moment I'm using a meter length of untwisted cable, and wriggle the cable manually next to a power supply, but I cannot detect any faults in the application (I'm reading the Ethernet fault counters off the Ethernet ASIC.) Whether this is because no faults are generated, or because the software/hardware detection is faulty, I cannot tell.

目前我正在使用一米长的无线电缆,并在电源旁边手动蠕动电缆,但我无法检测到应用中的任何故障(我正在读取以太网ASIC上的以太网故障计数器。)是否这是因为没有产生故障,或者因为软件/硬件检测有问题,我无法分辨。

Is there a way to do this in software?

有没有办法在软件中执行此操作?

I'd settle for writing something in a higher level language, like Java or python, and as a last resort would be willing to put it together in C, but I'd really rather not re-write an Ethernet driver purely to fix a possible bug.

我决定用更高级别的语言编写一些东西,比如Java或python,并且作为最后的手段愿意将它放在C中,但我真的不想重写以太网驱动程序纯粹是为了修复可能的错误。

[EDIT]: I want to create cable faults - not detect them.

[编辑]:我想创建电缆故障 - 不检测它们。

[EDIT]: I've transferred large files through FTP and SCP without problems with the doctored cable, and I see no errors coming up while inspecting the traffic with wireshark

[编辑]:我通过FTP和SCP传输大文件而没有使用篡改电缆的问题,我发现在使用wireshark检查流量时没有出现错误

[EDIT]: See also a similar question in python.

[编辑]:请参阅python中的类似问题。

Solution:

Well, after spending over a day fighting with C, this is the python solution.

好吧,花了一天时间与C战斗后,这就是python解决方案。

First disable automatic checksumming of the ethernet card:

首先禁用以太网卡的自动校验和:

sudo ethtool -K eth1 tx off

Then, send your dodgy frame from python:

然后,从python发送你的狡猾的框架:

#!/usr/bin/env python

from socket import *

#
# Ethernet Frame:
# [
#   [ Destination address, 6 bytes ]
#   [ Source address, 6 bytes      ]
#   [ Ethertype, 2 bytes           ]
#   [ Payload, 40 to 1500 bytes    ]
#   [ 32 bit CRC chcksum, 4 bytes  ]
# ]
#

s = socket(AF_PACKET, SOCK_RAW)
s.bind(("eth1", 0))
src_addr = "\x01\x02\x03\x04\x05\x06"
dst_addr = "\x01\x02\x03\x04\x05\x06"
payload = ("["*30)+"PAYLOAD"+("]"*30)
checksum = "\x00\x00\x00\x00"
ethertype = "\x08\x01"
s.send(dst_addr+src_addr+ethertype+payload+checksum)

Who said it had to be complicated...

谁说它必须复杂......

PS: I Love Python.

PS:我喜欢Python。

1 个解决方案

#1


6  

If you're working in C, you can send a raw Ethernet frame using socket(AF_PACKET, SOCK_RAW, ...), and passing it a pointer to a raw buffer that you've generated yourself (e.g. by following the frame layout at wikipedia ).

如果您在C中工作,则可以使用套接字(AF_PACKET,SOCK_RAW,...)发送原始以太网帧,并将指针传递给您自己生成的原始缓冲区(例如,通过遵循以下框架布局:*)。

It's been a long time since I've done this, so I'm not going to attempt to write a representative code snippet...

我已经很久没有这样做了,所以我不会尝试编写代表性的代码片段......

#1


6  

If you're working in C, you can send a raw Ethernet frame using socket(AF_PACKET, SOCK_RAW, ...), and passing it a pointer to a raw buffer that you've generated yourself (e.g. by following the frame layout at wikipedia ).

如果您在C中工作,则可以使用套接字(AF_PACKET,SOCK_RAW,...)发送原始以太网帧,并将指针传递给您自己生成的原始缓冲区(例如,通过遵循以下框架布局:*)。

It's been a long time since I've done this, so I'm not going to attempt to write a representative code snippet...

我已经很久没有这样做了,所以我不会尝试编写代表性的代码片段......