2

我正在使用 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 与适用于 .NET 4.0 的平台工具集 v100 一起使用

4

2 回答 2

1

您的ipChecksum函数需要一个指向它应该校验和的数据的指针,而不是一个指向包含指向校验和数据的指针的结构的指针。所以首先它校验和icmpHead,这很好。但随后它校验和指向的指针data,这是没有意义的。然后它在EchoRequest结构的末尾校验和。

于 2013-08-14T21:35:05.863 回答
0

如果您希望此代码被c++读者解释为您需要修复一些问题。

  • 真的吗?

  • 用于reinterpret_cast将一种指针类型转换为另一种。

  • 它通常被认为是一种更好的做法,size_t而不是unsigned long

  • 改为使用smart pointers

  • 用于static_cast将 ulong 转换为 ushort。

  • USHORT保证为 16 位。请改用其他类型。

编辑:你在MTU之上。将数据包保持在 1k 字节以下。IEEE 802.3预计为 1492,但该值可能会有所不同。

于 2013-08-14T21:42:39.620 回答