I have done my homework, now, I think. I had always though "pseudo-header" referred to the IPv6 header, with some fields zeroed. Now that I've got the correct RFC in hand, I see it is otherwise. (Why they put information pertaining to ICMPv6 in the IPv6 RFC is still beyond me, as is to why they decided to lay out the pseudo-header the way they did - no rational is provided as to why that format is better than the original IPv6 format...)
After doing some tests on some ICMPv6 echo packets I captured, it would seem that you need to fill in source & destination addresses in the pseudo-header. Your entry of the next header value in the pseudo-header seems to be correct, however, I am not sure that your payload length is - offset 32 in the pseudo header is indeed the first byte of the length, but also the most significant - so, you're entering 0x40000000 as the packet's payload length.
I also still doubt your length calculation, as I mentioned earlier. This line is what troubles me:
Code:
datapart = (char *)icHdrPing + sizeof(ICMPHeader);
memset(datapart,'E', 32);
That's 32 'E's, plus sizeof(ICMPHeader), which is 12, which equals 44 bytes total.
Finally, your one's complement code:
Code:
ulChkSum = (ulChkSum >> 16) + (ulChkSum & 0xffff);
ulChkSum += (ulChkSum >> 16);
return (unsigned short)(~ulChkSum);
}
The first line, OK - add in the carries. But that second line? Should we not also do a (ulChkSum & 0xffff) here? In my trying to duplicate the checksum of a captured wireshark ICMPv6 packet, I used:
Code:
while(sum > 0xFFFFUL)
{
sum = (sum & 0xFFFF) + (sum >> 16);
}