Я работаю над средством проверки связи и последовательно получаю нарушение прав доступа к моему буферу отправки при вычислении контрольной суммы 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
Ваш ipChecksum
Функция ожидает указатель на данные, которые она должна проверять, а не указатель на структуру, которая содержит указатель на данные для контрольной суммы. Итак, сначала это контрольные суммы icmpHead
, и это хорошо. Но тогда это контрольные суммы указателя на data
, что не имеет смысла. И тогда это контрольные суммы от конца EchoRequest
состав.
Если вы хотите, чтобы этот код интерпретировался как c++
читатели должны исправить некоторые вещи.
мемсет действительно?
использование reinterpret_cast
конвертировать один тип указателя в другой.
это обычно считается гораздо лучшей практикой для использования size_t
вместо unsigned long
использование smart pointers
вместо.
использование static_cast
конвертировать ulong в ushort.
USHORT
является не гарантированно будет 16 бит. Вместо этого используйте другой тип.
Редактировать: Вы Waaaay выше MTU. Держите ваши пакеты под 1k байтов. IEEE 802.3 ожидает 1492, хотя это значение может варьироваться.