raw BSD ソケット経由で ICMP を使用して管理対象ホストに ping を実行するネットワーク管理アプリケーションに取り組んでいます ( sendto
)。
私の質問はそれを行う方法ではなく、実際には非常にうまく機能します。ターゲット ホストがICMP エコー要求をそのホストに送信しようとしているときに、ターゲット ホストが宛先到達不能メッセージを管理サーバーに送信している場合にのみ、問題が発生するようです。
ホストが管理アプリケーションに追加されると、ホストは前述の ICMP ping を使用してテストされ、同時に「検出」が開始され、それぞれのプロトコルを使用して SNMP (161) などのホスト上のさまざまなポートがテストされます。そうする必要があります。
さて、ホストが存在するか応答するか (つまり、ICMP エコー応答を送信したか) がわからないホストでその「検出」を実行することはあまり意味がないことを認識していますが、この質問ではこれが重要です。また、問題のホストが実際に到達可能であり、たとえばコマンド ライン経由で ICMP ping に応答すると仮定しますping
。
「検出」により、最終的に ICMP 「Destination unreachable: Port unreachable」パケットが管理サーバーに送り返されます。たとえば、ターゲット ホストで実行されている SNMP エージェントがなく、ポート 161 に実際に到達できない場合などです。
これはまったく問題ありませんが、何らかの理由で、ICMP ping に必要な ICMP エコー要求を ICMP ソケットがそのホストに送信するのを妨げているようです。そのリクエストは決して送信されないため、私のアプリケーションには応答がなく、ホストはしばらくすると「到達不能」と見なされます (タイムアウト)。
Wireshark を使用してネットワーク トラフィックを分析した結果、実際にはターゲット ホストに ICMP エコー リクエストが送信されていないことがわかります。私が取り組んでいるアプリケーションには、そのホストで別の ICMP ping を「手動で」実行するために使用できる「ステータス ポール」機能もあります。ホストが追加された後にこれが使用された場合 (つまり、Destination unreachableパケットが着信しなくなった場合)、エコー要求は問題なく送信されます。
上記で説明した状況で ICMP エコー要求が送信されないことに当惑しています。すべての着信 ICMP パケットを受信する別の ICMP ソケットがありますが (応答に反応するために)、送信ソケットに影響を与えるべきではありませんか? 私のコードでは、 Destination unreachableメッセージに対して定義された反応はありません。それらは単に無視されるため、リクエストの送信を無効にするのは私自身のコードではないことは確かです。
実際、sendto
リクエストの送信を担当する関数が実行され (デバッグによって確認されます)、成功 (送信されたバイト数) が返されますが、パケットは実際には送信されていません。これは Windows システムと Linux システムの両方で再現できるので、オペレーティング システムの問題ではないと思います。
これらの宛先到達不能メッセージが送り返される原因となる「検出」を無効にすると、すべてが正常に機能するようになるため、ICMP エコー要求の送信を妨げているのはこれらのメッセージであると確信しています。私が答えを見つけることができない大きな疑問は、なぜですか?
必要に応じてさらに情報を提供できますが、これは商用製品であるため、ここにコードを投稿することは許可されていません。ただし、コードは特別なものではなく、未加工の ICMP ソケットを使用TOS=0
して ICMP (IPv4) パケットを送受信するだけです。TTL=64