これは、生のソケットをプログラミングする Linux C に関する簡単な質問です。raw ソケットを使用して任意のインターフェイスをリッスンしたい場合、トラフィックをリッスンするために実際に IP アドレスまたはインターフェイスにバインドする必要がありますか? 私が理解していることから、私は sock(); を呼び出すことができるはずだと感じています。そして recvfrom() トラフィックを開始します。私が間違っているかもしれませんが、それを使用しないプログラムを見たことがあります。
2 に答える
そうです、あなたがする必要があるのは、電話socket()
してからrecvfrom()
. ただし、 を使用したリスニングにはいくつかの制限があることに注意してSOCK_RAW
ください。
「send-and-forget」ベースで raw ソケットを使用していない場合は、raw パケットの応答パケットを読み取ることに関心があるでしょう。パケットが raw ソケットに配信されるかどうかの決定ロジックは、次のように列挙できます。
TCP および UDP パケットは raw ソケットに配信されることはなく、常にカーネル プロトコル スタックによって処理されます。
ICMP パケットのコピーは、一致する raw ソケットに配信されます。一部の ICMP タイプ (ICMP エコー要求、ICMP タイムスタンプ要求、マスク要求) では、カーネルが同時に何らかの処理を行い、応答を生成する場合があります。
すべての IGMP パケットは raw ソケット (OSPF パケットなど) に配信されます。
カーネル サブシステムによって処理されないプロトコル宛ての他のすべてのパケットは、raw ソケットに配信されます。
応答パケットが生のソケットに配信されるプロトコルを扱っているという事実は、必ずしも応答パケットを取得することを意味しません。このために、次のことも考慮する必要があります。
socket(2) システムコールを介してソケットを作成する際に、それに応じてプロトコルを設定します。たとえば、ICMP エコー要求パケットを送信していて、ICMP エコー応答を受信したい場合は、プロトコル引数 (3 番目の引数) を IPPROTO_ICMP に設定できます)。
socket(2) の protocol 引数を 0 に設定すると、受信したパケット ヘッダーのプロトコル番号がすべて一致します。
ソケットのローカル アドレスを定義する (bind(2) などを使用)。宛先アドレスがソケットのローカル アドレスと一致する場合は、アプリケーションにも配信されます。
詳細については、たとえばthisを参照してください。
インターフェイス上のトラフィックをキャプチャするつもりなら、libpcap を使用できます。