2013-08-14 2 views
2

Я работаю над инструментом ping, и я постоянно получаю нарушение доступа вокруг моего отправляющего буфера при вычислении контрольной суммы ICMP при использовании размера пакета 45041 или выше (включая заголовок ICMP). Любой пакет размером 45040 или ниже не выдает ошибки и корректно передает правильную контрольную сумму. Сокращенный код приведен ниже; нарушение прав доступа происходит при разыменовании буфера внутри цикла while в функции контрольной суммы на первой итерации.C++ - Нарушение прав доступа при построении ICMP-пакета

Любые идеи относительно того, почему это происходит?

Точная формулировка ошибки: Unhandled exception at 0x009C2582 in PingProject.exe: 0xC0000005: Access violation reading location 0x004D5000.

с помощью Visual Studio Professional 2012 с платформой набор инструментов v100 для .NET 4.0

ответ

1

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

+0

Я изменил 'EchoRequest' только как' icmpHeader' и выделил достаточно места за ним для части данных, и теперь он работает для любого пакета размера. Благодаря! (хотя я до сих пор не понимаю, почему он все еще работал для меньших пакетов, чем этот порог). –

+0

@MikeBogochow Это работало, потому что защита памяти распространяется на целые страницы. До тех пор, пока вы не закончите выделенную страницу, она не сработает, хотя и не будет генерировать правильную контрольную сумму. –

+0

Но контрольные суммы были правильными в соответствии с wirehark, и я получал ответы от хоста, которого я пинговал, которого я не был, когда контрольные суммы не были правильными –

0

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

  • MemSet на самом деле?

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

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

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

  • static_cast для перевода ulong в ushort.

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

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

+0

Проект начался с чистого C, но я изменил C++, когда столкнулся с некоторыми проблемами, и я думаю, что этот раздел по-прежнему был главным образом C, поэтому я прошу прощения за это. Спасибо за советы! –

+0

Для MTU моему приложению не важно, будет ли пакет фрагментирован, а также может быть отправлен по другим вещам, кроме ethernet, поэтому я просто убеждаюсь, что он находится в пределах определенных границ для ICMP –

Смежные вопросы