Title: What is a packet checksum?
1What is a packet checksum?
- Here we investigate the NICs capabilities for
computing and detecting errors using checksums
2Gigabit Ethernet frame-format
Carrier Extension
Data
Preamble
Destination Address
Source Address
Type/Lenth
Frame Check Sequence
Start-Of-Frame Delimiter
Frame is extended to occupy a slot-time of 512
bytes
3Some lowest-level details
- The frames Preamble consists of 7 bytes of an
alternating bit-pattern of 1s and 0s - The Start-of-Frame Delimiter is a one-byte
bit-pattern which continues the alternation of
1s and 0s until the final bit is reached (which
breaks the pattern-of-alternation) -
10101010 10101010 10101010 10101010 10101010
10101010 10101010 10101011
The 64-bit Preamble and SFD
In hexadecimal notation 0xAA 0xAA 0xAA 0xAA 0xAA
0xAA 0xAA 0xAB
The Start-of-Frame Delimiter
4The FCS field
- The Frame Check Sequence is a four-byte integer,
usually computed by the hardware according to a
sophisticated mathematical error-detection scheme
known as Cyclic-Redundancy Check (CRC) -
- The CRC is calculated by performing a modulo 2
division of the data by a generator polynomial
and recording the remainder after division - CRC-32 x32 x26 x23 x22 x16 x12 x11
x10 x8 x7 x5 x4 x2 x 1
5The CRCERRS register
- Our Intel Pro1000 ethernet controller has a
statistical counter register (the first one, at
offset 0x4000 in the memory-mapped I/O- space)
which counts any received frames which arrived
with a CRC-error indicated - Our nic2.c was programmed to strip the 4-byte
FCS field from all received frames, by setting
the SECRC-bit in register RCTL
6Another (simpler) checksum
The Pro1000s legacy-format Receive-Descriptor
16 bytes
Base-address (64-bits)
status
Packet- length
Packet- checksum
VLAN tag
errors
The device-driver initializes this
base-address field with the physical address
of a packet-buffer
The network controller will
write-back the values for these fields
when it has transferred a received packets
data into the packet-buffer
7What is this packet checksum?
- According to the Intel documentation, the packet
checksum is the unadjusted 16-bit ones
complement of the packet (page 24) - Now what exactly does that mean?
- And why did Intels hardware designers believe
that device-driver software would need this value
to be available for every ethernet packet that
the NIC receives?
8The idea of complements
- Whenever a whole object gets divided into two
parts, those pieces often referred to as
complements - Example
- complementary angles in a right-triangle
B
ABC BAC 90
A
C
9Set Theory
Venn Diagram
B
A
Within the universe represented here by
the box, the orange set B is the complement of
the green set A.
10Arithmetic
- Among the digits in our base ten system
- the values 1 and 9 are complements
- the values 2 and 8 are complements
- the values 3 and 7 are complements
- the values 4 and 6 are complements
- Complements are useful when performing
subtractions in modular arithmetic - 4 - 6 (mod 10) 4 4 (mod 10)
11Twos complement
- Digital computers use modular arithmetic in the
base two number system - Two 8-bit numbers are complements if their sum
equals 28 ( 256) - 00000001 is the twos-complement of 11111111
- 00000010 is the twos-complement of 11111110
- 00000011 is the twos-complement of 11111101
- As a consequence, subtractions can be done with
the same circuits as additions
12Ones complement
- But for some purposes there is a different kind
of complement that results in better
arithmetical properties its known as the
diminished radix complement - For the case of radix ten, its called nines
complement, and for the case of radix two its
called ones complement
13Nines complements
- A pair of 3-digit numbers x and y in the
radix ten number system would be called nines
complements if xy 103-1 999 - Thus 321 and 678 are nines-complements
- A pair of 3-digit numbers x and y in the
radix two number system would be called ones
complements if xy 23-1 111 - Thus 110 and 001 are ones-complements
14end-around-carry
- When you want to add two binary numbers using the
ones complement system, you can do it by first
performing ordinary binary addition, and then
adding in the carry-bit
10101010 (8-bit number)
11110000 (8-bit number)
--------------------- 1
10011010 (9-bits in the normal total)
1 (apply end-around carry)
--------------------- 10011011 (8-bits in the
ones-complement total)
15NIC uses ones complement
- For network programming nowadays it is common
practice for ones complement to be used when
computing checksums - It is also common practice for multi-byte
integers to be sent out over the wire in so
called big-endian byte-order (i.e., the most
significant byte goes out ahead of the bytes
having lesser significance)
16Intels cpu uses little endian
- Whenever our x86 processor stores a multi-byte
value into a series of cells in memory, it puts
the least significant byte first (i.e., at the
earliest memory address), followed by the
remaining bytes having greater significance)
0x3456
AX
mov ax, buf
buf
0x56
0x34
17Checksum using C
unsigned char cp phys_to_virt( rxring
rxhead .base_address ) unsigned int nbytes
rxring rxhead .packet_length unsigned
int nwords ( nbytes / 2 ) unsigned short wp
(unsigned short)cp unsigned int i, checksum
0 if ( nbytes 1 ) cp nbytes 0
nwords // pad odd length packet for ( i
0 i lt nwords i ) checksum wp i //
twos complement sum checksum (checksum gtgt
16) // do end-around carries checksum
htons( checksum ) // -- adjustment 1 swap the
bytes checksum checksum // -- adjustment
2 and flip the bits checksum 0xFFFF //
mask to lowest 16-bits // Lets compare our
checksum-calculation with the one done by the
PRO1000 printk( cpu-computed checksum04X
, checksum ) printk( nics rx
packet-checksum04X , rxring rxhead
.packet_chksum ) printk( \n )
18In-class demonstration 1
TIMEOUT We will insert into our nic2.c
device-drivers read() function our C code
that computes and displays the unadjusted
16-bit ones complement sum for each received
packet and compare our calculation with the
NICs packet_checksum
19Checksum offloading
- Our Intel 82573L network controller has the
capability of performing several useful checksum
calculations on normal network packets if this
desired by a device-driver
Receive CheckSum control register
31
9 8 7
0
reserved (0)
PCSS
I P O F L D
T U O F L D
RXCSUM (0x5000)
Legend PCSS Packet Checksum Start
(default0x00) IPOFLD IP-checksum
Off-load Enable (1yes, 0no) TUOFLD
TCP/UDP checksum Off-load Enable (1yes, 0no)
20Using nicecho.c
- To compensate for the modifications made to the
DA and SA fields by our echo.c, we can omit the
first six words (12 bytes) from the
checksum-calculations done both by our read()
code and by the nic hardware
// we start our addition-loop at i6 instead of
i0 for ( i 6 i lt nwords i ) checksum
wp i AND // we initialize the
CRXCSUM register with PCSS12 iowrite(
0x0000000C, io E1000_RXCSUM )
21In-class demonstration 2
TIMEOUT We will modify the nics RXCSUM
register (as well as our own previous checksum
computation) and observe the resulting effects
22The Legacy Transmit-Descriptor
16 bytes
Base-address (64-bits)
status
Packet- length
special
CSS
cmd
CSO
CSO CheckSum Offset
CSS CheckSum Start
Command-Byte Format
I D E
V L E
0
0
W B
I C
I F C S
E O P
23Our drivers packet-layout
destn-address
source-address
TYPE/ LENGTH
count
-- data --
-- data --
-- data
-- data --
-- data --
-- data --
Lets make room for a new 16-bit field at offset
0x0010, by starting our packets
data-payload at offset 0x0012 instead of offset
0x0010
24Further driver modifications
- We can demonstrate Checksum Insertion performed
by the NIC with these changes
define HDR_LEN (144) // two more bytes
precede packets data enum E1000_RXCSUM
0x5000, // define symbolic register-offset
ssize_t my_write( struct file file, const char
buf, size_t len, loff_t pos ) // add these
assignments in our drivers write()
function txring txtail .cksum_offset 16 //
where to insert the checksum txring txtail
.cksum_origin 12 // where to start its
calculation txring txtail .desc_command
(1ltlt2) // IC-bit (Insert Checksum)
25In-class demonstration 3
TIMEOUT We will modify the packet-layout used in
our device-drivers write() and read()
functions, and then program our TX descriptors
to utilize the IC command-option and the CSO
and CSS descriptor fields and then observe the
resulting effects