4

これは@stackoverflowでの最初の質問です。

私は一部の VoIP 運用サーバー用の監視ツール、特に Perl の pcap ライブラリを使用して特定のパターンに一致するすべてのトラフィック (VoIP 呼び出し) をキャプチャできるスニフ ツールを作成しています。

「udp」などの貧弱な選択的フィルターを使用して、アプリのコードですべてのフィルタリングを行うことはできません。これは、トラフィックが多すぎて、カーネルがパケット損失の報告に対処できないためです。

次に行うことは、キャプチャ中に可能な限り選択的なフィルターを繰り返し構築することです。最初に、(すべての) SIP シグナリング トラフィックと IP フラグメントのみをキャプチャします (パターン マッチは、どのような場合でもアプリケーション レベルで実行する必要があります)。次に、RTP に関する情報を SIP パケットに見つけたら、「or」句を追加します。特定の IP と PORT を含む実際のフィルター文字列を取得し、setfilter() でフィルターを再設定します。

したがって、基本的には次のようなものです。

  1. 初期フィルター : "(udp and port 5060) or (udp and ip[6:2] & 0x1fff != 0)" -> すべての SIP トラフィックと IP フラグメントをキャプチャします

  2. 更新されたフィルター: "(udp and port 5060) or (udp and ip[6:2] & 0x1fff != 0) or (host IP and port PORT)" -> 特定の IP、PORT の RTP もキャプチャします

  3. 更新されたフィルター: "(udp and port 5060) or (udp and ip[6:2] & 0x1fff != 0) or (host IP and port PORT) or (host IP2 and port PORT2)" -> 2 番目の RTP ストリームをキャプチャします同じように

等々。

監視目的でRTPストリームの「実際の」パケット損失を取得できるため、これは非常にうまく機能しますが、ツールの選択的フィルターバージョンが不十分な場合、いくつかのパケットがあったため、RTPパケット損失率は信頼できませんでしたカーネルによるパケット ドロップが原因で欠落しています。

しかし、このアプローチの欠点に取り掛かりましょう。

キャプチャ中に setfilter() を呼び出すと、関数 set_kernel_filter() のコード コメントで pcap-linux.c (libpcap バージョン 0.9 および 1.1 を確認) に記載されているように、libpcap が「フィルターの変更中に」受信したパケットをドロップするという事実が含まれます。

setfilter() を呼び出すと、一部のパケットが IP フラグメント化されて到着し、一部のフラグメントが失われます。これは、最後に libpcap 統計によって報告されません: トレースを掘り下げているのを見つけました。

これで、このアクションが libpcap によって行われる理由がわかりましたが、私の場合、パケットをドロップする必要はまったくありません (関係のないトラフィックを取得することは気にしません)。

libpcap のコードを変更していないこの問題を解決する方法について何か考えはありますか?

4

3 に答える 3

1

丸い穴、四角いペグ。

あなたはあなたのニーズに完全に合わないツールを持っています。

もう1つのオプションは、第1レベルのフィルター(上記のように、必要以上に多くをキャプチャする)を実行し、必要なより細かいフィルターを実装する別のツールにパイプすることです(呼び出しごとの場合まで)。RTPトラフィックが多いために、その第1レベルのフィルターがカーネルに対して多すぎる場合は、個々の呼び出しをキャプチャするためにプロセスの安定性を維持するなど、他のことを行う必要があります(したがって、「メイン」のフィルターを変更しないでください)。プロセス;それは単に他の人に彼らのフィルターを設定する方法を指示するだけです。)

はい、これは、キャプチャをその場で(すべてを「キャプチャの保存」プロセスに渡す)または事後にマージすることを意味する場合があります。

フィルタをすばやくインストールしないと、とにかくRTPパケットを見逃す可能性があることに気づきます。RTPパケットは、200 OKが着信する前に(または一緒に)発信者に着信する可能性があり、ACKの前(またはその上)に応答者に戻る可能性があることを忘れないでください。また、SDPなしのINVITEを忘れないでください(200 OKで提供、ACKで回答)。など:-)

于 2010-12-17T21:46:34.473 に答える
1

より具体的なフィルターを使用して新しいプロセスを開始するのはどうですか。一度に 2 つの並列 pcap キャプチャを実行できます。しばらくすると (または両方が同じパケットを受信したことを確認すると)、元のパケットを停止できます。

于 2010-12-02T17:17:50.713 に答える
1

すべての RTP トラフィックをキャプチャできますか?

キャプチャ フィルタからの RTP トラフィックの提案は次のとおりです。

udp[1] & 1 != 1 && udp[3] & 1 != 1 && udp[8] & 0x80 == 0x80 && length < 250

リンクが指摘しているように、DNS およびおそらく他の UDP パケットに、RTP パケットで使用されるヘッダー バイト 0x80 が含まれている場合に、いくつかの誤検知が発生しますが、その数は無視でき、カーネル ドロップを引き起こすほどではありません。

于 2010-12-04T11:36:15.850 に答える