我正在使用ping工具,当使用45041或更大的数据包大小(包括ICMP标头)计算ICMP校验和时,我一直在发送缓冲区周围遇到访问冲突。任何大小为45040或更小的数据包都不会引发错误,并使用正确的校验和进行正确传输。缩写代码如下;在第一次迭代时在校验和函数中取消引用while循环内的缓冲区时会发生访问冲突。
typedef struct ICMPHeader
{
BYTE type; // ICMP packet type
BYTE code; // Type sub code
USHORT checksum;
USHORT id;
USHORT seq;
} ICMPHeader;
typedef struct echoRequest
{
ICMPHeader icmpHead;
char *data;
} EchoRequest;
// ...
EchoRequest *sendBuffer = new EchoRequest();
sendBuffer->data = new char[packetSize];
memset((void *)sendBuffer->data, 0xfa, packetSize);
sendBuffer->icmpHead.checksum = ipChecksum((USHORT *)sendBuffer,
packetSize + sizeof(sendBuffer->icmpHead));
// ...
// checksum function
USHORT ipChecksum(USHORT *buffer, unsigned long size)
{
unsigned long cksum = 0;
while (size > 1)
{
cksum += *buffer++;
size -= sizeof(USHORT);
}
if (size)
cksum += *(UCHAR *)buffer;
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >> 16);
return (USHORT)(~cksum);
}
有关为何发生这种情况的任何想法?
确切的错误措辞:Unhandled exception at 0x009C2582 in PingProject.exe: 0xC0000005: Access violation reading location 0x004D5000.
将Visual Studio Professional 2012与平台工具集v100 for .NET 4.0一起使用
答案 0 :(得分:1)
您的ipChecksum
函数需要指向它应该校验和的数据的指针,而不是指向包含指向校验和的数据的指针的结构的指针。首先是校验和icmpHead
,这很好。但是它会将指针校验到data
,这没有任何意义。然后它在EchoRequest
结构的末尾进行校验和。
答案 1 :(得分:0)
如果您希望读者将此代码解释为c++
,则需要修改一些内容。
memset吗?
使用reinterpret_cast
将一种指针类型转换为另一种指针类型。
使用size_t
代替unsigned long
改为使用smart pointers
。
使用static_cast
将ulong转换为ushort。
USHORT
不保证为16位。改为使用其他类型。
编辑:您在MTU之上 waaaay 。保持您的数据包低于1k字节。 IEEE 802.3预计1492可能会有所不同。