Hi Guys,
For a reqt, we are doing ping and traceroute on our application using Raw Sockets. This code supports both IPv4 and IPv6. On IPv4 environment, both ping and traceroute works fine in Vista / Non Vista (Win XP, Win 2003). But on IPv6 environment, both ping and tracroute are working fine only on Vista and not working on Windows XP or Windows 2003. We tried with ethereal and captured all the packets that are being send during ping. It says that "checksum incorrect" in the ping request. When gone through ICMPv6 RFC, they mentioned that checksum has to be calculated along with Pseudo-header. We included pseudo-header based on the information provided on sites, that didn't worked. We tried various options on pseudo header by including and not including source address, destination address. But nothing worked.
Kindly note that ping and traceroute are working fine from command line using ping and tracert on Win XP / Win 2003 in IPv6 environment. While going through some sites and forums I came to know that IPv6 is not completely implemented on Win XP or Win Server 2003. Is it causing this problem?

The issues I guess here are,

* Checksum calculation have some issues
* Pseudo-header format and its size that we mentioned may be incorrect
* IPv6 may not work on Win XP / Win 2003. If this is the case, how to get this one work on Win XP and Win 2003 (both 32 and 64 bits)

The following is the part of source code that fills ICMP data and calculate checksum.

Code:

Code:
// ICMP packet types
#define ICMP_ECHO_REPLY 0
#define ICMP_ECHO_REPLY_V6 129

#define ICMP_DEST_UNREACH 3
#define ICMP_DEST_UNREACH_V6 1

#define ICMP_TTL_EXPIRE 11
#define ICMP_TTL_EXPIRE_V6 3

#define ICMP_ECHO_REQUEST 8
#define ICMP_ECHO_REQUEST_V6 128

// ICMP header structure
typedef struct _icmpHdr
{
unsigned char i_type; // ICMP packet type
unsigned char i_code; // Sub code type
unsigned short i_checksum; // ICMP Checksum
unsigned short i_id; // Process Id
unsigned short i_seq; // ICMP Sequence number
//
// This is not the std header, but we reserve space for time
//
unsigned long i_ulTimeStamp;
} ICMPHeader;

// Fill in ICMP Packet field
void ping::InitICMPData(char* cHdrPing, int nPacketSize, int nSeqNo, struct addrinfo* dest)
{
ICMPHeader *icHdrPing;
char *datapart;
int family = dest->ai_family ;

if(AF_INET6 == family)
{
//memcpy( cHdrPing + 16 , (void *)&(((struct sockaddr_in6 *)dest->ai_addr)->sin6_addr.u) , 16);
*(cHdrPing + 32) = 40 ;
*(cHdrPing + 39) = 58;
icHdrPing = (ICMPHeader*)(cHdrPing + 40);
nPacketSize += 40;
}
else
{
icHdrPing = (ICMPHeader*)cHdrPing;
}

icHdrPing->i_type = AF_INET6 == family ? ICMP_ECHO_REQUEST_V6:ICMP_ECHO_REQUEST;
icHdrPing->i_code = 0;
icHdrPing->i_checksum = 0;

icHdrPing->i_id = htons(whatIsProcessId());
icHdrPing->i_seq = htons(nSeqNo);
icHdrPing->i_ulTimeStamp = GetTickCount ();

datapart = (char *)icHdrPing + sizeof(ICMPHeader);

memset(datapart,'E', 32);
// Calculate a checksum on the result
icHdrPing->i_checksum = CalcCheckSum((unsigned short*)cHdrPing, nPacketSize);
printf("TYPE = %d\n" , icHdrPing->i_type);
printf("CHECk = %x\n" , icHdrPing->i_checksum);

printf("End of InitICMPdata\n");
}

// Calculate check sum of the packet
unsigned short ping::CalcCheckSum(unsigned short* usBuffer, int nSize)
{
unsigned long ulChkSum = 0;

while(nSize > 1)
{
ulChkSum += *usBuffer++;
nSize -= sizeof(unsigned short);
}

if (nSize)
{
ulChkSum += *(unsigned char*)usBuffer;
}

ulChkSum = (ulChkSum >> 16) + (ulChkSum & 0xffff);
ulChkSum += (ulChkSum >> 16);

return (unsigned short)(~ulChkSum);
}
As it is a very critical reqt. we have to fix this problem immediately. Please help me find a solution on this issue to get this work on Win XP / Win 2003.

Thanks in advance.


Regards,
Vignesh