www.pudn.com > PIPMasq.zip > checksum.cpp


#include "stdafx.h" 
#include "PIPMasq.h" 
 
 
///// CheckSumCalc /////// 
 
unsigned short  
CheckSumCalc::in_cksum(unsigned short *addr, int len) 
{ 
	int				nleft = len; 
	int				sum = 0; 
	unsigned short	*w = addr; 
	unsigned short	answer = 0; 
 
	while (nleft > 1) 
	{ 
		sum += *w++; 
		nleft -= 2; 
	} 
 
	if (nleft == 1) 
	{ 
		*(unsigned char *)(&answer) = *(unsigned char *)w; 
		sum += answer; 
	} 
 
	sum = (sum >> 16) + (sum & 0xffff); 
	sum += (sum >> 16); 
 
	answer = ~sum; 
 
	return(answer); 
}; 
 
 
unsigned short 
CheckSumCalc::tcpchecksum( 
	struct tcphdr *_tcphdr, struct iphdr *_iphdr, int tcpDataLenInPacket) 
{ 
	_tcphdr->check = 0;	  // Checksum should be set "0" first. 
 
	unsigned char buf[MAX_ETH_SIZE]; 
	memset(buf, 0, MAX_ETH_SIZE); 
	 
	int buflen = 0; 
	struct pesudeIphdr _pesudeIphdr; 
 
	// make pesude IP header 
	_pesudeIphdr.saddr = _iphdr->saddr; 
	_pesudeIphdr.daddr = _iphdr->daddr; 
	_pesudeIphdr.zero = 0;	// should be 0 
	_pesudeIphdr.protocol = _iphdr->protocol; 
	_pesudeIphdr.len = htons(sizeof(struct tcphdr) + tcpDataLenInPacket); 
 
	memcpy(buf, &_pesudeIphdr, sizeof(struct pesudeIphdr)); 
	buflen += sizeof(struct pesudeIphdr);	 
 
	// copy packet for TCP to buf 
	memcpy(buf + buflen, _tcphdr, sizeof(struct tcphdr)); 
	buflen += sizeof(struct tcphdr); 
 
	unsigned char *testP = (unsigned char *)_tcphdr; 
	testP += sizeof(struct tcphdr); 
 
	memcpy((buf+buflen), testP , tcpDataLenInPacket); 
	buflen += tcpDataLenInPacket; 
 
 
	return in_cksum((unsigned short *)buf, buflen); 
} 
 
 
unsigned short 
CheckSumCalc::udpchecksum( 
	struct udphdr *_udphdr, struct iphdr *_iphdr, int udpDataLenInPacket) 
{ 
	_udphdr->check = 0;  // Checksum should be set "0" first. 
 
	unsigned char buf[MAX_ETH_SIZE]; 
	memset(buf, 0, MAX_ETH_SIZE); 
	 
	int buflen = 0; 
 
	struct pesudeIphdr _pesudeIphdr; 
 
	// make pesude IP header 
	_pesudeIphdr.saddr = _iphdr->saddr; 
	_pesudeIphdr.daddr = _iphdr->daddr; 
	_pesudeIphdr.zero = 0;	// should be 0 
	_pesudeIphdr.protocol = _iphdr->protocol; 
	_pesudeIphdr.len = _udphdr->len; 
 
	memcpy(buf, &_pesudeIphdr, sizeof(struct pesudeIphdr)); 
	 
	buflen += sizeof(struct pesudeIphdr); 
 
	// copy packet for udp to buf 
	memcpy(buf + buflen, _udphdr, sizeof(struct udphdr)); 
	buflen += sizeof(struct udphdr); 
 
	unsigned char *testP = (unsigned char *)_udphdr; 
	testP += sizeof(struct udphdr); 
 
	memcpy((buf+buflen), testP , udpDataLenInPacket); 
	buflen += udpDataLenInPacket; 
 
	return in_cksum((unsigned short *)buf, buflen); 
}