www.pudn.com > csum.rar > csum.c, change:2009-04-24,size:2059b


#include <stdio.h> 
#include <conio.h> 
 
//利用wireshark抓包,抓去ping www.163.com的ping报文 
unsigned char Ping[] = {0x00,0x0f,0xe2,0x29,0x51,0x67,0x00,0x18,0xf3,0x1d,0xb1,0x79,0x08,0x00,0x45,0x00, 
							0x00,0x3c,0x07,0xf5,0x00,0x00,0x40,0x01,0xf3,0x70,0xac,0x13,0x46,0x0a,0x3c,0xbf, 
								0x50,0x7f,0x08,0x00,0x48,0x5c,0x04,0x00,0x01,0x00,0x61,0x62,0x63,0x64,0x65,0x66, 
									0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76, 
									   0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69}; 
 
 //在ping报文的第15个字节开始的20个字节为ip头数据 
unsigned char IP_Package [] = {0x45,0x00,0x00,0x3c,0x07,0xf5,0x00,0x00,0x40,0x01, 
								0xf3,0x70,0xac,0x13,0x46,0x0a,0x3c,0xbf,0x50,0x7f}; //其中,ip头的第10、11位为f3 70为校验和字段 
 
/**********************************************************************   
* 函数名称:csum   
* 功能描述:计算ip校验和   
* 参数	  :1、addr  ip头; 2、count ip头的字节数 
* 返回值  :unsigned short     
* 其它说明:无   
* 作者    :钟金棠 
************************************************************************/  
unsigned short csum(unsigned char *addr, int count)  
{  
    unsigned long checksum = 0; //32位双字节数,存放校验和 
 
	//把ip头数据分成若干个16位序列 
	for(; count > 1; count -= 2) {  
		checksum += *addr++ < 8; //前一字节存checksum的高字段 
		checksum += *addr++;      //后一字节存checksum的低字段 
	} 
 
	if(0 != count) { 
		checksum += *addr; //加上剩余字节 
	} 
 
    checksum = (checksum >> 16) + (checksum & 0xFFFF); //加上反码求和运算中产生的进位 
    return  (unsigned short)(~checksum); //取反后返回 
} 
 
int main() 
{ 
	unsigned short check = ((IP_Package[10] < 8) & 0xff00 ) + IP_Package[11]; //取出ip头中的校验和字段  
	IP_Package[10] = 0; //校验和字段置零 
	IP_Package[11] = 0; 
	 
	if(check = csum(IP_Package, 10))   { 
		printf("GOOD: True !!\n"); 
		printf("BAD : False !!\n"); 
		printf("checksum = %x\n", csum(IP_Package, 20)); 
	} 
	else { 
		printf("GOOD: False !!\n"); 
		printf("BAD : True !!\n"); 
	} 
	getch(); 
    return 0; 
}