迂回ソケットは bind(2) システムコールを経由して特定の ポートにバインドすることができることを除き、 生の IP ソケットとほぼ同じです。 bind での IP アドレスは無視され、ポート番号のみが意味を持ちます。 迂回ポートにバインドされた迂回ソケットは、 何らか (ここでは特定しません) の カーネルメカニズムによってそのポートに迂回された全てのパケットを受信します。 パケットを迂回ポートに書き込むこともできます。 その場合はカーネルの IP パケット処理に再び入力されます。
通常、迂回ソケットは FreeBSD のパケットフィルタリングの実装や ipfw(8) プログラムと共に使われます。 迂回ソケットからの読み出しや書き込みによって、 合致するパケットをホストマシンを経由する時に任意の ``フィルタ'' を通したり、 特別なルーティングの細工を行うといったことができます。
迂回パケットは read(2), recv(2), もしくは recvfrom(2) によってそのままの形で読み出すことができます。 後者の場合に得られるアドレスでは、 ポート番号にはパケット迂回者が提供するなんらかのタグ (通常は ipfw のルール番号) が設定され、 IPアドレス部には 入力パケットの場合はパケットが受信された (最初の) インタフェースアドレス、 出力パケットの場合は INADDR_ANY が設定されます。 入力パケットの場合はアドレスに続く 8 バイトの中に インタフェース名も (そこに収まるものとして) おかれます。
後者の場合では、 指定された IP アドレスは、 どれかのローカルインタフェースのアドレスと一致するか、 インタフェース名が IP アドレスの後に見つからなければなりません。 もしインタフェース名が見つかれば、 そのインタフェースが使われ、IP アドレスの値は無視されます (それが INADDR_ANY でないことは無視されません)。 これは、どのインタフェースからパケットが ``到着'' したかを示すためです。
通常、入力として読み出されるパケットは入力として書かれなければなりません。 出力パケットについても同様です。 パケットを読み出して書き戻す時には、 recvfrom(2) によって与えられたソケットアドレスと同じものを、そのままの形で sendto(2) に渡すことで物事が単純になります (下記参照)。
sendto(2) へ渡されるソケットアドレスのポート部分には、 迂回モジュールにとって意味のあるタグが含まれます。 ipfw(8) の場合には、タグは、 この次の ルール番号からルール処理を再開すべきと解釈されます。
パケットは迂回されるがポートにバインドされるソケットがない場合、 もしくは IPDIVERT がカーネルにおいて有効にされていない場合は、パケットは捨てられます。
迂回される入力パケットフラグメントは配送前に全てリアセンブルされます。 フラグメントが 1 つでも迂回されると全てのパケットが迂回されることになります。 もし、フラグメントのいくつかが違うポートに迂回されると、 最後にどのポートが選択されるかは予期できません。
パケットは受信されて、変更されずに送信されますが、 出力として書かれたパケットの IP ヘッダのチェックサムは 正しい値に書き換えられます。 入力として書かれ、誤ったチェックサムを持つパケットは捨てられます。 それら以外は、全てのヘッダフィールドは変更されません (もちろんネットワークに届いた順番で)。
タイプ SOCK_RAW のソケットの生成と同様に、 1024 より小さいボート番号をバインドするためには スーパユーザアクセスが必要となります。
入力のフラグメントが迂回の前に再構成されるべきかどうか については疑問の余地があります。 例えば、他のマシン宛のパケットのうち数個のフラグメントが ローカルマシン経由でルーティングされないだけで、 パケットが失われます。 これはおそらく何らかの方法で設定可能なオプションにするべきです。