2010年9月9日 星期四

TCP checksum

For some reason I needed to write a TCP checksum program and google helped me find a sample code here: http://www.netfor2.com/tcpsum.htm . Unfortunately, I found the code is not completely correct. My fix is as below:



The major change is the type of src_addr, dest_addr and buff. The original sample considers them as array of unsigned 16 bit words, however array of unsigned 8 bit words are more appropriate for octets.  Another change is about checking if len_tcp is even or odd. The original code exams a redundant function argument padding, which is removed in my modified version; should exam len_tcp instead.

typedef unsigned short u16;
typedef unsigned long  u32;
typedef unsigned char  u8;
u16 tcp_sum_calc(u16 len_tcp, u8 src_addr[],u8 dest_addr[], u8 buff[])
{
u16 prot_tcp=6;
u16 padd=0;
u16 word16;
u32 sum;

  // Find out if the length of data is even or odd number. 
  // If odd, add a padding byte = 0 at the end of packet
  if ((len_tcp&1)==1){
    padd=1;
    buff[len_tcp]=0; // FIXME: possibly overrun the buffer!
  }

  //initialize sum to zero
  sum=0;

  // make 16 bit words out of every two adjacent 8 bit
  // words and calculate the sum of all 16 bit words
for (i=0;i<len_tcp+padd;i=i+2){
    word16 =((((u16)buff[i])<<8)&0xFF00)+
            (((u16)buff[i+1])&0xFF);
    sum = sum + (unsigned long)word16;
  }
  // add the TCP pseudo header which contains:
  // the IP source and destinationn addresses,
  for (i=0;i<4;i=i+2){
    word16 =((((u16)src_addr[i])<<8)&0xFF00)+
            (((u16)src_addr[i+1])&0xFF);
    sum=sum+word16;
  }
  for (i=0;i<4;i=i+2){
    word16 =((((u16)dest_addr[i])<<8)&0xFF00)+
            (((u16)dest_addr[i+1])&0xFF);
    sum=sum+word16;
  }
  // the protocol number and the length of the TCP packet
  sum = sum + prot_tcp + len_tcp;

  // keep only the last 16 bits of the 32 bit calculated 
  // sum and add the carries
  while (sum>>16)
    sum = (sum & 0xFFFF)+(sum >> 16);

  // Take the one's complement of sum
  sum = ~sum;

return ((unsigned short) sum);
}

沒有留言:

張貼留言