Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you send an Ethernet frame with a corrupt FCS?

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.

like image 612
user83753 Avatar asked Apr 06 '09 23:04

user83753


People also ask

What is FCS error Ethernet?

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.

How does FCS work in Ethernet frame?

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.

How does the FCS field in the Ethernet provide error recovery?

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.

How are Ethernet frames sent?

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.


2 Answers

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.

like image 22
deagol Avatar answered Sep 24 '22 14:09

deagol


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

like image 88
brice Avatar answered Sep 21 '22 14:09

brice