ошибка времени выполнения — нарушение прав доступа при создании пакета ICMP

Я работаю над средством проверки связи и последовательно получаю нарушение прав доступа к моему буферу отправки при вычислении контрольной суммы ICMP при использовании размера пакета 45041 или более (включая заголовок 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 для .NET 4.0

2

Решение

Ваш ipChecksum Функция ожидает указатель на данные, которые она должна проверять, а не указатель на структуру, которая содержит указатель на данные для контрольной суммы. Итак, сначала это контрольные суммы icmpHead, и это хорошо. Но тогда это контрольные суммы указателя на data, что не имеет смысла. И тогда это контрольные суммы от конца EchoRequest состав.

1

Другие решения

Если вы хотите, чтобы этот код интерпретировался как c++ читатели должны исправить некоторые вещи.

  • мемсет действительно?

  • использование reinterpret_cast конвертировать один тип указателя в другой.

  • это обычно считается гораздо лучшей практикой для использования size_t вместо unsigned long

  • использование smart pointers вместо.

  • использование static_cast конвертировать ulong в ushort.

  • USHORT является не гарантированно будет 16 бит. Вместо этого используйте другой тип.

Редактировать: Вы Waaaay выше MTU. Держите ваши пакеты под 1k байтов. IEEE 802.3 ожидает 1492, хотя это значение может варьироваться.

0

По вопросам рекламы [email protected]