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); }
沒有留言:
張貼留言