unsigned short checksum(unsigned short* usBuf, unsigned int nSize)
{
unsigned long usChksum=0;
//Calculate the checksum
while (nSize>1)
{
usChksum+=*usBuf++;
nSize-=sizeof(unsigned short);
}
//If we have one char left
if (nSize)
usChksum+=*(unsigned char*)usBuf;
//Complete the calculations
usChksum=(usChksum >> 16) + (usChksum & 0xffff);
usChksum+=(usChksum >> 16);
//Return the value (inversed)
return (unsigned short)(~usChksum);
}
ip部分
ippacket.GetIpHeader()->check=0;
checksum((unsigned short *)ippacket.GetIpHeader(),sizeof(iphdr));
UDP需要加入伪首部,再计算校验和
PseudoHeader ph;
ph.dwSrcIP = ippacket.GetIpHeader()->saddr;
ph.dwDestIP = ippacket.GetIpHeader()->daddr;
ph.cReserved = 0;
ph.cProtocol = IPPROTO_UDP;
ph.wLength = htons((WORD)ntohs( ippacket.GetUdpHeader()->uh_ulen));
ippacket.GetUdpHeader()->uh_sum=0;
ippacket.GetUdpHeader()->uh_sum=checksumudp(&ph,(unsigned short *)ippacket.GetUdpHeader(),ntohs( ippacket.GetUdpHeader()->uh_ulen));