GetIfEntry と netsh の間の MTU の不一致
-
04-10-2019 - |
質問
私は、TCP の代替として、信頼性の高い接続指向の送信を提供する、UDP 上で実行される疑似トランスポート層ソフトウェアに取り組んでいます。ネットワーク効率を最大化するために、初期化時に「最適な」ネットワーク アダプタの 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 コマンドによって報告される値が実際に使用される値であることは明らかです。netsh と同じ値を取得するにはどの API を呼び出すことができるか知っている人はいますか?
解決
ローカル 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
インターフェース名。
しかし、最も興味深いのは、 NILMTU 分野
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)。このフィールド NILMTU あなたが探しているものです。たとえば、私のコンピュータは DSL ルーター経由でインターネットに接続されており、 NlMtu
はルーターなしの場合のように 1500 ではなく、代わりに正しい値 1492 になります。あなたの場合は 1300 でなければなりません。
Microsoft SDK の最新バージョンのいずれかがインストールされている場合は、次の場所にあります。 C:\Program Files\Microsoft SDKs\Windows\v7.0\Samples
etds\ihelp
etinfo ディレクトリの使用例 GetIpInterfaceTable
API。ラインの約270にブレーキポイントを設定するだけです。 ネットインフォ.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-1B7D6DF) 92B38私の場合)同じ値である必要があります。
関数 GetIpInterfaceTable
Vista から存在しますが、名前からどのようにわかるか PMIB_IPINTERFACE_TABLE
値は TCP アダプターの MIB 情報から取得されます (Windows DDK) を参照してください。数年前には IP ヘルパー DLL はまったく存在せず、IpConfig.exe を表示する情報を受け取るには、CreateFile と DeviceIoControl を使用して TCP TDI ドライバーからそのような情報を提供する必要がありました (L"\Device cp" や IOCTL_TCP_QUERY_INFORMATION_EX などの定数を参照) tcpioctl.h)。したがって、おそらく Windows XP でも同じ情報を提供することは可能ですが、それは重要ではありません。