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.

.NET 4.0 用のプラットフォーム ツールセット v100 で Visual Studio Professional 2012 を使用する

4

2 に答える 2

1

関数ipChecksumは、チェックサムするデータへのポインターを含む構造体へのポインターではなく、チェックサムするはずのデータへのポインターを期待しています。したがって、最初に checksums icmpHead、これは良いことです。しかし、その後、 へのポインターをチェックサムしますがdata、これは意味がありません。そして、EchoRequest構造体の最後でチェックサムを計算します。

于 2013-08-14T21:35:05.863 に答える
0

このコードをc++読者が解釈するようにしたい場合は、いくつか修正する必要があります。

  • 本当にmemset?

  • reinterpret_castあるポインター型を別の型に変換するために使用します。

  • size_t一般に、代わりに使用する方がはるかに優れていると考えられていますunsigned long

  • 代わりに使用smart pointersします。

  • static_castulong から ushort への変換に使用します。

  • USHORT16 ビットであるとは限りません。代わりに別のタイプを使用してください。

編集:あなたはMTUを超えています。パケットを 1k バイト未満に保ちます。IEEE 802.3は 1492 を想定していますが、この値は異なる場合があります。

于 2013-08-14T21:42:39.620 に答える