Is ethernet checksum exposed via AF_PACKET?
No, you do not need to include the CRC.
When using a packet socket in Linux using socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL) )
, you must provide the layer 2 header when sending. This is defined by struct ether_header
in netinet/if_ether.h
and includes the destination host, source host, and type. The frame check sequence is not included, nor is the preamble, start of frame delimiter, or trailer. These are added by the hardware.
Why is the Frame Check Sequence at the end of an Ethernet frame and not somewhere else
You are correct: placing the CRC at the end of a frame reduces packet latency and reduces hardware buffering requirements. On the transmit side, hardware can read and transmit bytes of the frame immediately. The transmitter calculates the CRC on the fly as data passes through, then simply appends the CRC the tail of the frame.
Consider the alternative where the CRC comes somewhere in the Ethernet header. Hardware must read and store the entire frame in order to calculate the CRC. This amounts to a large look-ahead operation and adds significantly to transmit latency and hardware cost. The situation also becomes more complex for the receiver as well.
How to reliably generate Ethernet frame errors in software?
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 ).
It's been a long time since I've done this, so I'm not going to attempt to write a representative code snippet...
How Do I Use Raw Socket in Python?
You do it like this:
First you disable your network card's automatic checksumming:
sudo ethtool -K eth1 tx off
And then send your dodgy frame from python 2 (You'll have to convert to Python 3 yourself):
#!/usr/bin/env python
from socket import socket, AF_PACKET, SOCK_RAW
s = socket(AF_PACKET, SOCK_RAW)
s.bind(("eth1", 0))
# We're putting together an ethernet frame here,
# but you could have anything you want instead
# Have a look at the 'struct' module for more
# flexible packing/unpacking of binary data
# and 'binascii' for 32 bit CRC
src_addr = "\x01\x02\x03\x04\x05\x06"
dst_addr = "\x01\x02\x03\x04\x05\x06"
payload = ("["*30)+"PAYLOAD"+("]"*30)
checksum = "\x1a\x2b\x3c\x4d"
ethertype = "\x08\x01"
s.send(dst_addr+src_addr+ethertype+payload+checksum)
Done.
Related Topics
Nginx Location Deny by File Extension Syntax
Execute Sudo Using Expect Inside Ssh from Bash
Shell Script: Hexadecimal Loop
Substitution on Range of Lines
Bash Script to Get Specific User(S) Id and Processes Count
Linux Script- Date Manipulations
Bash: Update a Variable Within a File
How to Fix Numpy Dependencies Path on a Python 3.7.3 Script on Linux Frozen with Cx_Freeze 6.0B1
Usb Modem Is Echoing Back Wrong Characters
Gnuplot Doesn't Work Through Ssh Command
Bash Assign Output to Variable Inside Here Document
How to Monitor the Amount of Simd Instruction Usage
Requirement for Transport Stream Streaming Server