Date post: | 22-Dec-2015 |
Category: |
Documents |
View: | 219 times |
Download: | 2 times |
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
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 HeaderTCP Pseudo-Header
The TCP Segment
The TCP Checksum is computed over this array of words
packet-dataTCP Header
The IP Header Checksum is computed over this array of words
IP HeaderFrame Header
The TCP Checksum gets inserted here
The IP Header Checksum gets inserted here
Sample checksum algorithm
// to compute and insert the TCP Checksumunsigned 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-carriescksum & 0xFFFF; // mask for 16-bitscksum ^= 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