Little Endian layout

candleberryinfamousΔίκτυα και Επικοινωνίες

26 Οκτ 2013 (πριν από 4 χρόνια και 17 μέρες)

76 εμφανίσεις

Building TCP/IP packets

A look at the computation
which need to be performed for
utilizing the TCP/IP protocol

NIC’s ‘offloading’ capabilities

An advanced feature of Intel’s most recent
PRO1000 gigabit ethernet controllers is an
ability to perform many of the calculations
associated with the processing of network
packets which otherwise would have to be
programmed by device
driver authors and
then executed at runtime by a CPU that
has much other vital work to attend to

How much work?

To gain a concrete idea of the work that is
required to set up a conventional network
packet for transmission, and then to take it
apart when it’s received, we have created
a character
mode Linux driver that shows
us all of the essential calculation
steps, as
it does not rely on the usual networking
software included within Linux’s kernel

TCP/IP over Ethernet

Here is a diagram, from Intel’s Software Developer’s Manual,

of the widely deployed TCP/IP Ethernet packet format

UnixWare: online tutorial


© 2002 Caldera International, Inc. All rights reserved.

UnixWare 7 Release 7.1.3

30 October 2002

“The TCP/IP Protocol Stack”

recommended background reading

TCP/IP Protocol Stack

by Caldera, Incorporated

Encapsulation and Decapsulation
of Data within a network stack

by Caldera, Incorporated

Network stack support for TCP/IP

by Caldera, Incorporated

Internet Protocol Header

IP Header (Little Endian layout)

Transport Control Protocol Header

TCP Header (Little
Endian layout)

TCP Pseudo Header layout

Our ‘nictcp.c’ demo

This device
driver’s ‘write()’ function will
show the sequence of steps needed for
building a packet with the TCP/IP format:

Setup the packet’s data ‘payload’

Prepend a TCP packet

Then prepend a TCP ‘pseudo’ packet

Compute and insert the TCP checksum

Replace the pseudo
header with an IP header

Compute and insert the IP Header Checksum

Finally prepend the Ethernet Header


Two checksum calculations

TCP Header

TCP Pseudo

The TCP Segment

The TCP Checksum is computed over this array of words


TCP Header

The IP Header Checksum

is computed over this

array of words

IP Header



The TCP Checksum gets inserted here

The IP Header Checksum gets inserted here

Sample checksum algorithm

// to compute and insert the TCP Checksum

unsigned char

*cp = phys_to_virt( txring[ txtail ].base_addr );

unsigned short

*wp = (unsigned short *)( cp + 22 );

unsigned int

nbytes = 12 + 20 + len;

unsigned int

nwords = (nbytes / 2) + (nbytes % 2);

unsigned int

cksum = 0;

if ( len & 1 ) cp[ 14 + 20 + 20 + len ] = 0;

// padding

for (int i = 0; i < nwords; i++) cksum += htons( wp[ i ] );

cksum += (cksum >> 16);

// end

cksum & 0xFFFF;

// mask for 16

cksum ^= 0xFFFF;

// flip the low 16

*(unsigned short*)(cp + 50) = htons( cksum );

class demonstration

We can use our ‘pktsplit.c’ demo
to confirm the correctness of our TCP/IP
format as far as the NIC hardware
is concerned

it reports (in its descriptor
‘status’ and ‘errors’ fields) that both of our
checksums were computed by the NIC on

and that neither was in error

class exercise

Can you adapt these ideas in our ‘nictcp.c’
driver to produce the analogous ‘nicudp.c’
demonstration module?

A similar ‘pseudo’ UDP Header is used to
calculate the UDP Checksum value (see
the Intel Software Developer’s Manual for
the layout and size of the UDP Header)