I'm not sure if this is even possible since this might be handled in hardware, but I need to send some Ethernet frames with errors in them. I'd like to be able to create runts, jabber, misalignment, and bad FCS errors. I'm working in Python.
Basic definition: An FCS error is a legal sized frame with a bad frame check sequence (CRC error). An FCS error can be caused by a duplex mismatch, faulty NIC or driver, cabling, hub, or induced noise. What you should do to fix this problem: Cause 1: FCS errors can be caused by a duplex mismatch on a link.
The FCS field contains a number that is calculated by the source node based on the data in the frame. This number is added to the end of a frame that is sent. When the destination node receives the frame the FCS number is recalculated and compared with the FCS number included in the frame.
FCS code is again calculated at the destination site and compared with FCS bits of the frame, if FCS matches then the transmission is considered successful else frames are discarded. Hence, it is used for error detection. FCS is only used for error detection and does not specify any detail about error recovery.
The frame is sent onto the network where an Ethernet switch checks the destination address of the frame against a MAC lookup table in its memory. The lookup table tells the switch which physical port, i.e., RJ45 port, is associated with the device whose MAC address matches destination address of the frame.
The program did not work as intended for me to generate FCS errors.
The network driver added the correct checksum at the end of the generated frame again. Of course it's quite possible that the solution is working for some cards, but I'm sure not with any from Intel. (It's also working without any ethtool changes for me.)
With at least an Intel e1000e network card you need a small change to the code above: Add the following line after "s = socket(AF_PACKET, SOCK_RAW)":
s.setsockopt(SOL_SOCKET,43,1)
This tell the NIC driver to use the "SO_NOFCS" option defined in socket.h and send the frame out without calculating and adding the FCS.
You may also be interested in the following C-programm, which did show me how to do it: http://markmail.org/thread/eoquixklsjgvvaom
But be aware that the program will not work on recent kernels without a small change. The SOL_SOCKET seems to have changed the numeric ID from 42 to 43 at some time in the past.
According to the original author the feature should be available for at least the following drivers: e100, e1000, and e1000e. A quick grep in the kernel sources of 3.16.0 is indicating that ixgbe igb and i40e should also work. If you are not using any of these cards this socket option will probably not be available.
First, you disable your ethernet card's checksumming:
sudo ethtool -K eth1 tx off
Then, you send the corrupt frames from 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)
See A similar question
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With