Is Ethernet Checksum Exposed via Af_Packet

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



Leave a reply



Submit