GetUfEntry和netsh之间的MTU不匹配

时间:2010-05-07 17:48:33

标签: windows-vista netsh mtu iphelper

我正在研究在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相同的值?

1 个答案:

答案 0 :(得分:3)

有本地MTU大小和路径MTU(参见RFC 1191)。您可以使用

之类的命令
ping -f -l 1464 www.stackoverflow.com
ping -f -l 1465 www.stackoverflow.com

确定路径MTU。考虑ICMP包和IP头的头大小。有关API解决方案,请参阅Path MTU Discovery

更新:请不要再提出这样的问题!我找到答案非常有趣,我花了几个小时才完成这个。但是......我找到了!要获得正确的MTU大小值,您应该使用GetIpInterfaceTable API,它返回具有PMIB_IPINTERFACE_TABLE结构数组的MIB_IPINTERFACE_ROW结构。 MIB_IPINTERFACE_ROW hat InterfaceIndex可以帮助您识别IP接口,它与其他众所周知的IP Helper功能相同。您还可以使用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 Driver Kit文档中也可以找到相同的文本(请参阅http://msdn.microsoft.com/en-us/library/ff559254(VS.85).aspx)。您要搜索的字段 NlMtu 。例如,我的计算机通过DSL路由器连接到Internet,NlMtu不像没有路由器那样1500,而是具有正确的值1492。在你的情况下,它必须是1300。

如果您安装了最新版本的Microsoft SDK,则可以在 C:\ Program Files \ Microsoft SDKs \ Windows \ v7.0 \ Samples \ netds \ iphelp \ Netinfo 中找到目录使用GetIpInterfaceTable API的示例。只需在 netinfo.c 文件中的约270行设置制动点,您将在InterfaceTable->Table[i].NlMtu中看到相应接口适配器的 IP MTU 的正确值。如果您在HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ services \ Tcpip \ Parameters \ Interfaces {34407201-997C-41FF-9EBF-1B7D6DF92B38}下的注册表中验证哪个值具有您的接口卡的MTU REG_DWORD({34407201-997C-41FF-9EBF-1B7D6DF92B38在我的情况下)它必须是相同的值。

函数GetIpInterfaceTable从Vista开始存在,但是如何从名称PMIB_IPINTERFACE_TABLE中看到值来自TCP适配器的MIB信息(Windows DDK)。几年前它根本没有IP帮助DLL,并且接收显示IpConfig.exe的信息,必须使用CreateFile和DeviceIoControl从TCP TDI驱动程序提供这样的信息(参见L“\ Device \ Tcp”和IOCTL_TCP_QUERY_INFORMATION_EX等常量) tcpioctl.h)。所以也许可以在Windows XP上提供相同的信息,但这并不重要。