Little Endian layout

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

26 Οκτ 2013 (πριν από 3 χρόνια και 9 μήνες)

71 εμφανίσεις

Building TCP/IP packets

A look at the computation
-
steps
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

<http://uw713doc.sco.com/en/NET_tcpip/tcpN.tcpip_stack.html>

© 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
-
header


Then prepend a TCP ‘pseudo’ packet
-
header


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

packet
-
data

Two checksum calculations

TCP Header

TCP Pseudo
-
Header

The TCP Segment

The TCP Checksum is computed over this array of words

packet
-
data

TCP Header


The IP Header Checksum


is computed over this


array of words

IP Header

Frame


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
-
around
-
carries


cksum & 0xFFFF;



// mask for 16
-
bits


cksum ^= 0xFFFF;


// flip the low 16
-
bits


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





In
-
class demonstration


We can use our ‘pktsplit.c’ demo
-
module
to confirm the correctness of our TCP/IP
packet
-
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
reception
--

and that neither was in error

In
-
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)