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