MTU несовпадение между GetIfEntry и netsh

Я работаю над программным обеспечением псевдотранспортного уровня, которое работает по протоколу UDP, обеспечивая надежную передачу, ориентированную на соединение, в качестве альтернативы TCP. Чтобы максимизировать эффективность сети, мы запрашиваем MTU "лучшего" сетевого адаптера при инициализации.

MIB_IFROW row = {0};
row.dwIndex = dwBestIfIndex;

dwRes = GetIfEntry(&row);

Поиск в Интернете Я обнаружил, что вы можете использовать следующие команды netsh для запроса этого же значения из командной строки (не API C++)

netsh interface ipv4 show interfaces
netsh interface ipv4 show subinterfaces

Беспокойство вызывает то, что хотя row.dwMtu может быть установлен на 1500, отслеживание сетевого трафика на отправляющем ноутбуке показывает, что наши пакеты фрагментированы в пакеты по 1300 байт.NETsh также сообщает, что MTU составляет 1300.

Очевидно, что значение, сообщаемое командой netsh, является фактическим используемым значением. Кто-нибудь знает, какой API я могу вызвать, чтобы получить те же значения, что и netsh?

1 ответ

Решение

Существуют локальный размер MTU и Path MTU (см. RFC 1191). Вы можете использовать такие команды, как

ping -f -l 1464 www.stackru.com
ping -f -l 1465 www.stackru.com

определить путь MTU. Учитывайте размер заголовков пакетов ICMP и заголовков IP. См. Path MTU Discovery для решения API.

ОБНОВЛЕНО: Пожалуйста, не надо больше таких вопросов! Мне было очень интересно найти ответ, и я трачу на это несколько часов. Но... я нашел! Чтобы получить правильное значение размера MTU, вы должны использовать GetIpInterfaceTable API, который возвращает PMIB_IPINTERFACE_TABLE структура, которая имеет массив MIB_IPINTERFACE_ROW структур. MIB_IPINTERFACE_ROW шапка InterfaceIndex который помогает вам идентифицировать IP-интерфейс, он такой же, как и в других известных функциях IP Helper. Вы также можете использовать ConvertInterfaceLuidToNameW функция для получения из другого поля InterfaceLuid имя интерфейса.

Но самое интересное это поле НлМту

typedef struct _MIB_IPINTERFACE_ROW {
    ADDRESS_FAMILY Family;
    NET_LUID InterfaceLuid;
    NET_IFINDEX InterfaceIndex;
    // ...
    ULONG NlMtu;
    // ...
};

В документации (см. http://msdn.microsoft.com/en-us/library/aa814496(v=VS.85).aspx) он описывается как " Размер MTU сетевого уровня в байтах ". Тот же текст и больше не найдете также в документации Windows Driver Kit (см. http://msdn.microsoft.com/en-us/library/ff559254(VS.85).aspx). Это поле NlMtu - то, что вы ищете. Мой компьютер, например, подключен к Интернету через маршрутизатор DSL и NlMtu не 1500, как это было бы без маршрутизатора, но вместо этого имеет правильное значение 1492. В вашем случае это должно быть 1300.

Если у вас установлена ​​одна из последних версий Microsoft SDK, вы можете найти в каталоге C:\Program Files\Microsoft SDKs\Windows\v7.0\Samples\netds\iphelp\Netinfo пример использования GetIpInterfaceTable API. Просто установите точку торможения на линии около 270 в файле netinfo.c, и вы увидите в InterfaceTable->Table[i].NlMtu правильное значение IP MTU соответствующего интерфейсного адаптера. Если вы проверите в реестре в разделе HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters\Interfaces{34407201-997C-41FF-9EBF-1B7D6DF92B38}, у какого значения есть MTU REG_DWORD для вашей карты интерфейсов ({34407201-997BF-41BF-416-RUF-41BF-416FF-41BF-416FF-41BF-416FBF-416-FF-367-FF-41BF-416FF-41BF-416F6BF-416F6BF) } в моем случае) это должно быть одинаковое значение.

Функция GetIpInterfaceTable существует, начиная с Vista, но как вы можете видеть из названия PMIB_IPINTERFACE_TABLE значения поступают из информации MIB TCP-адаптера (см. Windows DDK). Несколько лет назад это была вообще не DLL-помощник DLL, и для получения информации, отображающей IpConfig.exe, необходимо использовать CreateFile и DeviceIoControl для выдачи такой информации из драйвера TCP TDI (см. Константы, такие как L"\Device\Tcp" и IOCTL_TCP_QUERY_INFORMATION_EX в tcpioctl.h). Так что, возможно, можно дать ту же информацию о Windows XP, но это не важно.

Другие вопросы по тегам