Вопрос

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

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

dwRes = GetIfEntry(&row);

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

netsh interface ipv4 show interfaces
netsh interface ipv4 show subinterfaces

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

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

Это было полезно?

Решение

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

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

чтобы определить MTU пути.Примите во внимание размер заголовка ICMP-пакетов и IP-заголовков.Видишь Обнаружение MTU пути для решения API.

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

Но самое интересное заключается в том, что NlMtu поле

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 (см. http://msdn.microsoft.com/en-us/library/ff559254 (ПРОТИВ 85).aspx).Это поле NlMtu это то, что вы ищете.Например, мой компьютер подключен к Интернету через DSL-маршрутизатор и NlMtu это не 1500, как было бы без маршрутизатора, а вместо этого имеет правильное значение 1492.В вашем случае это должно быть 1300.

Если у вас установлена одна из последних версий Microsoft SDK, то вы найдете в C:\Program Файлы\Microsoft SDKs\Windows\версия 7.0\Образцы etds\iphelp etinfo каталог - пример, который использует GetIpInterfaceTable API.Просто установите точку торможения на линии около 270 в netinfo.c файл, и вы увидите в InterfaceTable->Table[i].NlMtu правильное значение IP MTU соответствующего интерфейсного адаптера.Если вы подтвердите это в реестре в разделе HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services cpip\Parameters\Interfaces{34407201-997C-41FF-9EBF-1B7D6DF92B38 } какое значение имеет MTU REG_DWORD для вашей интерфейсной платы ({34407201-997C-41FF-9EBF-1B7D6DF92B38} в моем случае), это должно быть то же значение.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top