FreeBSD 日本語マニュアル検索 (jman/japropos/jwhatis)


日本語 man コマンド類 (ja-man-1.1j_5) と日本語 man ドキュメント (ja-man-doc-5.4 (5.4-RELEASE 用) など) をインストールすると、以下のような man コマンド閲覧、キーワード検索が コンソールからできるようになります。

4.11-RELEASE-K, 5.4-RELEASE-K, 5.5-RELEASE-K, 6.0-RELEASE-K から 6.4-RELEASE-K, 7.0-RELEASE-K から 7.4-RELEASE-K, 8.0-RELEASE-K から 8.4-RELEASE-K, 9.0-RELEASE-K から 9.3-RELEASE-K, 10.0-RELEASE-K から 10.3-RELEASE-K, 11.0-RELEASE-K から 11.4-RELEASE-K, 12.0-RELEASE-K, 12.1-RELEASE-K は、 プライベート版 (小金丸が編集してまとめたもの) ですが、 より多くの翻訳したファイルが含まれています。 (5.4-RELEASE-K から 6.4-RELEASE-K, 7.0-RELEASE-K から 7.4-RELEASE-K, 8.0-RELEASE-K から 8.4-RELEASE-K, 9.0-RELEASE-K から 9.3-RELEASE-K, 10.0-RELEASE-K から 10.3-RELEASE-K, 11.0-RELEASE-K から 11.4-RELEASE-K, 12.0-RELEASE-K から 12.3-RELEASE-K, 13.0-RELEASE-K から 13.2-RELEASE-K は、全翻訳済み)

13.3-STABLE-K, 15.0-CURRENT-K は現在、作成中で日々更新されています。



検索コマンド: man apropos whatis
コマンド/キーワード:
日本語マニュアル RELEASE :
セクション:
Table of Contents
名称 | 書式 | 解説 | バッファモード | IOCTL | BPF ヘッダ | フィルタマシン | SYSCTL 変数 | 使用例 | 関連項目 | 歴史 | 作者 | バグ
BPF(4)             FreeBSD カーネルインタフェースマニュアル             BPF(4)

名称
     bpf -- バークレイパケットフィルタ

書式
     device bpf

解説
     バークレイパケットフィルタは、プロトコルの独立の方法でデータリンク層 (レ
     イヤ) に生のインタフェースを提供します。ネットワーク上のすべてのパケット
     は、たとえ他のホストに向けられたものでも、この機構を通してアクセスできま
     す。

     パケットフィルタは、キャラクタ特殊デバイス /dev/bpf として現れます。デバ
     イスをオープンした後に、ファイル記述子は、BIOCSETIF ioctl で特定のネット
     ワークインタフェースにバインドしなければなりません。あるインタフェース
     は、複数のリスナによって共有することができ、各記述子の基礎となるフィルタ
     は、同じパケットのストリームを見ることになります。

     別々のデバイスファイルは、それぞれのマイナデバイスが必要とされます。ファ
     イルが使用中であるなら、オープンは、失敗し、errno は、EBUSY に設定されま
     す。

     オープンしている bpf ファイルのインスタンスそれぞれに関連づけられているの
     は、ユーザが設定可能なパケットフィルタです。インタフェースでパケットが受
     信されるときはいつでも、そのインタフェースで listen (接続を受け付け) して
     るすべてのファイル記述子は、それらのフィルタを適用します。パケットを受け
     付ける各記述子は、それ自身のコピーを受け付けます。

     パケットフィルタは、固定長ヘッダを持っているどんなリンクレベルプロトコル
     もサポートします。これまでのところ、イーサネット、SLIP および PPP ドライ
     バだけが bpf と交信するように変更されています。

     パケットデータは、ネットワークバイト順になっているので、アプリケーション
     は、マルチバイトの値を抽出するためには byteorder(3) マクロを使用するべき
     です。

     bpf ファイル記述子に書き込むことによってネットワークにパケットを送出する
     ことができます。書き込みは、バッファリングされないので、1 回の書き込みに
     つき 1 つのパケットだけしか処理されません。現在イーサネットと SLIP リンク
     への書き込みだけがサポートされています。

バッファモード
     bpf デバイスは、アプリケーションによって提供されたメモリバッファを通して
     パケットデータをアプリケーションに配信します。バッファモードは、
     BIOCSETBUFMODE ioctl を使用して設定され、BIOCGETBUFMODE ioctl を使用して
     読み込まれます。

   バッファリングされた読み込みモード
     デフォルトで、bpf デバイスは、パケットデータが、read(2) システムコールを
     使用してカーネルからユーザメモリへ明白にコピーされる、BPF_BUFMODE_BUFFER
     モードで動作します。ユーザプロセスは、内部のバッファをサイズを決めるため
     と、ファイル上のすべての read(2) 操作の両方ために使用される、固定のバッ
     ファサイズを宣言します。このサイズは、BIOCGBLEN ioctl を使用して問い会わ
     され、BIOCSBLEN ioctl を使用して設定されます。バッファサイズより大きい個
     別のパケットは、必ずしも切り詰められないことに注意してください。

   0 コピーバッファ (zero-copy buffer) モード
     また、bpf デバイスは、パケットデータが、システムコールとコピーのオーバ
     ヘッドの両方を避けて、カーネルによって 2 つのユーザメモリバッファに直接書
     き込まれる、BPF_BUFMODE_ZEROCOPY モードで動作します。バッファは、固定の
     (等しい) サイズ、ページで整列され、偶数で複数ページサイズです。最大の 0
     コピーバッファサイズは、BIOCGETZMAX ioctl によって返されます。バッファサ
     イズより大きい個別のパケットは、必ずしも切り詰められないことに注意してく
     ださい。

     ユーザプロセスは、引数として struct bpf_zbuf ポインタを受け付ける
     BIOCSETZBUF ioctl を使用して 2 つのメモリバッファを登録します:

     struct bpf_zbuf {
             void *bz_bufa;
             void *bz_bufb;
             size_t bz_buflen;
     };

     bz_bufa は、書き込まれる最初のバッファのユーザ空間のアドレスへのポインタ
     で、bz_bufb は、2 番目のバッファへのポインタです。bpf は、バッファが満杯
     となり、認識されるとき、2 つのバッファの間を循環 (切り替え) します。

     各バッファは、バッファのための同期とデータ長さの情報を保持するために、固
     定長のヘッダで始まります:

     struct bpf_zbuf_header {
             volatile u_int  bzh_kernel_gen; /* カーネル世代番号. */
             volatile u_int  bzh_kernel_len; /* バッファ内のデータ長. */
             volatile u_int  bzh_user_gen;   /* ユーザ世代番号. */
             /* ...将来の使用のための埋め草... */
     };

     すべての詰め物も含めて、各バッファのヘッダ構造は、それが BIOCSETZBUF を使
     用して設定される前に、0 クリアされるべきです。バッファ中の残りの空間は、
     バッファリングされる読み込みモードと同様に、パケットデータを格納し、同じ
     形式でレイアウトするために、カーネルによって使用されます。

     カーネルとユーザプロセスは、バッファへのアクセスを同期するためにバッファ
     ヘッダを通して簡単な承認プロトコルに従います: ヘッダ世代番号、
     bzh_kernel_genbzh_user_gen が同じ値を保持するとき、カーネルが、バッ
     ファを所有し、異なるとき、ユーザ空間が、バッファを所有しています。

     カーネルが、バッファを所有している間、内容は、不安定であり、非同期に変化
     するかもしれません。ユーザプロセスが、バッファを所有している間、内容は、
     安定していて、バッファが認識されるまで、変更されません。

     バッファを登録する前にバッファヘッダをすべての 0 に初期化することは、両方
     のバッファの最初の所有権をカーネルに割り当てるという効果があります。カー
     ネルは、バッファが bzh_kernel_gen を修正することによってユーザ空間に割り
     当てられることで、シグナルを発生し、ユーザ空間がバッファを認識し、
     bzh_user_gen の値を bzh_kernel_gen の値を設定することによって、それをカー
     ネルに返します。

     キャッシュとメモリ再順序付けの効果を避けるために、ユーザプロセスは、バッ
     ファをチェックして、認識するとき、不可分な操作とメモリバリアを使用しなけ
     ればなりません:

     #include <machine/atomic.h>

     /*
      * 再利用のためにバッファの所有権をカーネルに返す.
      */
     static void
     buffer_acknowledge(struct bpf_zbuf_header *bzh)
     {

             atomic_store_rel_int(&bzh->bzh_user_gen, bzh->bzh_kernel_gen);
     }

     /*
      * バッファがカーネルによってユーザ空間に割り当てられているかどうか
      * チェックする. ユーザ空間がバッファを所有しているなら, 真を返し,
      * そうでなければ, 偽を返します.
      */
     static int
     buffer_check(struct bpf_zbuf_header *bzh)
     {

             return (bzh->bzh_user_gen !=
                 atomic_load_acq_int(&bzh->bzh_kernel_gen));
     }

     ユーザプロセスは、任意のデータが、BIOCROTZBUF ioctl を使用するユーザ空間
     で、保留中 (pending) であるなら、次のバッファの割り当てを強制します。これ
     によって、ユーザプロセスは、タイムアウトに続くような、バッファが満杯にな
     る前に、部分的に書き込まれたバッファのデータを検索することができます。プ
     ロセスは、データが存在していなかったなら、バッファがユーザ空間に割り当て
     られないときに、ヘッダの世代番号を使用してバッファの所有権を再チェックし
     なければなりません。

     バッファリングされた読み込みモードで見られるように、kqueue(2), poll(2)select(2) は、完了したバッファの利用可能性を待ってスリープするために使用
     されます。それらは、次のバッファの所有権がユーザ空間に割り当てられると
     き、読み込み可能なファイル記述子を返します。

     現在の実装では、カーネルは、0、1 または両方のバッファをユーザプロセスに割
     り当てます。しかしながら、初期の実装は、多くても 1 つのバッファが、一度に
     ユーザプロセスに割り当てられる、不変条件を保っていました。発展と高性能を
     ともに確実にするために、ユーザプロセスは、できるだけはやく、再利用のため
     にそれを返して、別のバッファを保持している間に、2 番目のバッファでブロッ
     クのウェートしないで、完全に処理されたバッファを認識するべきです。

IOCTL
     次の ioctl(2) コマンドコードは、<net/bpf.h> で定義されています。すべての
     コマンドは、次のインクルードを必要とします:

             #include <sys/types.h>
             #include <sys/time.h>
             #include <sys/ioctl.h>
             #include <net/bpf.h>

     さらに、BIOCGETIF と BIOCSETIF は、<sys/socket.h> と <net/if.h> を必要と
     します。

     FIONREAD に加えて、次のコマンドは、どんな bpf ファイルのオープンに適用さ
     れます。ioctl(2) への (3 番目の) 引数は、指示されたタイプへのポインタであ
     るべきです。

     BIOCGBLEN       (u_int) bpf ファイル上で読み込みのために必要なバッファ長
                     を返します。

     BIOCSBLEN       (u_int) bpf ファイル上での読み込みのためのバッファ長を設
                     定します。バッファは、ファイルが BIOCSETIF によってインタ
                     フェースにアタッチされる前に設定されなければなりません。
                     要求されたバッファサイズの場所を適用することができないな
                     ら、許容できる最も近いサイズが設定され、引数に返されま
                     す。このサイズでないバッファが渡されるなら、read (読み込
                     み) 呼び出しは、EIO エラーとなります。

     BIOCGDLT        (u_int) アタッチされたインタフェースの基礎となるデータリ
                     ンク層のタイプを返します。インタフェースが指定されていな
                     いなら、EINVAL を返します。``DLT_'' が前に付いたデバイス
                     タイプは、<net/bpf.h> で定義されています。

     BIOCPROMISC     強制的にインタフェースを無差別 (promiscuous) モードにしま
                     す。ローカルホストに向けられたものだけではなく、すべての
                     パケットが処理されます。2 つ以上のファイルが与えられたイ
                     ンタフェースで listen (接続を受け付け) されるかもしれない
                     ので、インタフェースを無差別でないモードでオープンした
                     listen する側は、無差別にパケットを受信することができま
                     す。この問題は、適切なフィルタで改善することができます。

     BIOCFLUSH       着信パケットのバッファをフラッシュし、BIOCGSTATS によって
                     返される統計値をリセットします。

     BIOCGETIF       (struct ifreq) ファイルが listen (接続を受け付け) してい
                     るハードウェアインタフェースの名前を返します。名前は、
                     ifreq 構造体の ifr_name フィールドに返されます。他のすべ
                     てのフィールドは、未定義です。

     BIOCSETIF       (struct ifreq) ファイルに関連するハードウェアインタフェー
                     スを設定します。このコマンドは、どんなパケットも読み込む
                     ことができるようになる前に実行されなければなりません。デ
                     バイスは、ifreq 構造体の ifr_name フィールドを使用する名
                     前によって示されます。さらに BIOCFLUSH の動作を実行しま
                     す。

     BIOCSRTIMEOUT

     BIOCGRTIMEOUT   (struct timeval) 読み込みタイムアウトパラメータを設定また
                     は取得します。引数は、読み込み要求でタイムアウトする前の
                     待ち時間の長さを指定します。このパラメータは、open(2) に
                     よって 0 に初期化され、タイムアウトしないことを示します。

     BIOCGSTATS      (struct bpf_stat) パケットの統計値の次の構造体を返します:

                     struct bpf_stat {
                             u_int bs_recv;    /* 受信したパケット数 */
                             u_int bs_drop;    /* 落としたパケット数 */
                     };

                     フィールドは、次の通りです:

                           bs_recv オープンまたはリセット以後にこの記述子に
                                   よって受信したパケットの数 (最後の read (読
                                   み込み) 呼び出しのときからのバッファされて
                                   いるものを含みます)。

                           bs_dropフィルタで受け付けられましたが、バッファの
                                   オーバフローためにカーネルに落されたパケッ
                                   トの数 (すなわち、アプリケーションの読み込
                                   みは、パケットトラフィックについていってい
                                   ません)。

     BIOCIMMEDIATE   (u_int) 引数の真偽値に基づいて ``直接モード'' を有効また
                     は無効にします。直接モードが有効にされるとき、read (読み
                     込み) は、パケットの受信でただちに返ります。そうでなけれ
                     ば、read は、カーネルバッファが満杯になるかタイムアウトが
                     起こるまでブロックされます。これは、リアルタイムでメッ
                     セージに応答しなければならない rarpd(8) のようなプログラ
                     ムで役に立ちます。新しいファイルに対するデフォルトは、オ
                     フです。

     BIOCSETF

     BIOCSETFNR      (struct bpf_program) 興味のないパケットを捨てるためにカー
                     ネルによって使用される読み込みフィルタプログラムを設定し
                     ます。命令の配列とその長さは、次の構造体を使用して渡され
                     ます:

                     struct bpf_program {
                             int bf_len;
                             struct bpf_insn *bf_insns;
                     };

                     フィルタプログラムは、bf_insns フィールドで指されますが、
                     `struct bpf_insn' のユニット中のフィルタプログラムの長さ
                     は、bf_len フィールドによって与えられます。フィルタ言語の
                     説明については、セクションフィルタマシンを参照してくださ
                     い。BIOCSETF と BIOCSETFNR の唯一の違いは、BIOCSETF が、
                     BIOCFLUSH の動作を実行しますが、BIOCSETFNR は、実行しませ
                     ん。

     BIOCSETWF       (struct bpf_program) インタフェースへのどのようなタイプの
                     パケットを書き込むことができるかを制御するカーネルによっ
                     て使用される書き込みフィルタプログラムを設定します。bpf
                     フィルタプログラムに関する詳しい情報については、BIOCSETF
                     コマンドを参照してください。

     BIOCVERSION     (struct bpf_version) 現在カーネルで認識されているフィルタ
                     言語のメジャーとマイナバージョン番号を返します。フィルタ
                     をインストールする前に、アプリケーションは、現在のバー
                     ジョンが実行しているカーネルと互換性があるかどうかチェッ
                     クしなければなりません。メジャー番号が一致し、アプリケー
                     ションのマイナ番号がカーネルのマイナ番号と等しいか小さい
                     なら、バージョン番号は互換性があります。カーネルのバー
                     ジョン番号は、次の構造体で返されます:

                     struct bpf_version {
                             u_short bv_major;
                             u_short bv_minor;
                     };

                     現在のバージョン番号は、<net/bpf.h> の BPF_MAJOR_VERSION
                     と BPF_MINOR_VERSION によって与えられます。互換性のない
                     フィルタは、未定義の動作となるかもしれません (たぶん、
                     ioctl() によってエラーが返されるかまたは偶然にパケットが
                     一致します)。

     BIOCSHDRCMPLT

     BIOCGHDRCMPLT   (u_int) ``ヘッダ完全'' フラグの状態を設定するか取得しま
                     す。リンクレベルソースアドレスがインタフェース出力ルーチ
                     ンによって自動的に書き込まれるなら、0 が設定されます。リ
                     ンクレベルソースアドレスが書き込まれるなら、通信する配線
                     に供給するように 1 に設定されます。このフラグは、デフォル
                     トで 0 に初期化されます。

     BIOCSSEESENT

     BIOCGSEESENT    (u_int) これらのコマンドは、時代遅れですが、互換性のため
                     に残されています。代わりに BIOCSDIRECTION と
                     BIOCGDIRECTION を使用します。インタフェースで局所的で生成
                     されるパケットが BPF によって返されるべきであるかどうかを
                     決定するフラグを設定または取得します。インタフェースで着
                     信パケットだけを見るために 0 に設定します。インタフェース
                     で局所的およびリモートに起因するパケットを見るために 1 に
                     設定します。このフラグは、デフォルトで 1 に初期化されま
                     す。

     BIOCSDIRECTION

     BIOCGDIRECTION  (u_int) インタフェースの着信、発信、またはすべてのパケッ
                     トが BPF によって返されるべきであるかどうか決定する設定を
                     設定するか、取得します。インタフェースの着信パケットのみ
                     を見るためには、BPF_D_IN に設定します。インタフェースの
                     ローカルとリモートから始まるパケットを見るためには
                     BPF_D_INOUT に設定します。インタフェースの発信パケットの
                     みを見るためには BPF_D_OUT に設定します。この設定は、デ
                     フォルトで BPF_D_INOUT に初期化されます。

     BIOCSTSTAMP

     BIOCGTSTAMP     (u_int) BPF によって返されるタイムスタンプの形式と解像度
                     を設定するか、または取得します。64 ビットの struct
                     timeval 形式でタイムスタンプを取得するために
                     BPF_T_MICROTIME, BPF_T_MICROTIME_FAST,
                     BPF_T_MICROTIME_MONOTONIC または
                     BPF_T_MICROTIME_MONOTONIC_FAST を設定します。64 ビットの
                     struct timespec 形式でタイムスタンプを取得するために
                     BPF_T_NANOTIME, BPF_T_NANOTIME_FAST,
                     BPF_T_NANOTIME_MONOTONIC または
                     BPF_T_NANOTIME_MONOTONIC_FAST を設定します。64 ビットの
                     struct bintime 形式でタイムスタンプを取得するために
                     BPF_T_BINTIME, BPF_T_BINTIME_FAST,
                     BPF_T_NANOTIME_MONOTONIC または
                     BPF_T_BINTIME_MONOTONIC_FAST を設定します。タイムスタンプ
                     を無視するために BPF_T_NONE を設定します。すべての 64
                     ビットのタイムスタンプの形式は、struct bpf_ts でラップさ
                     れます。BPF_T_MICROTIME_FAST, BPF_T_NANOTIME_FAST,
                     BPF_T_BINTIME_FAST, BPF_T_MICROTIME_MONOTONIC_FAST,
                     BPF_T_NANOTIME_MONOTONIC_FAST と
                     BPF_T_BINTIME_MONOTONIC_FAST は、_FAST 接尾辞のない対応す
                     る形式に似ていますが、フルタイムカウンタ問い合わせを実行
                     しないので、それらの精度は、ワンタイマチック (one timer
                     tick) です。BPF_T_MICROTIME_MONOTONIC,
                     BPF_T_NANOTIME_MONOTONIC, BPF_T_BINTIME_MONOTONIC,
                     BPF_T_MICROTIME_MONOTONIC_FAST,
                     BPF_T_NANOTIME_MONOTONIC_FAST と
                     BPF_T_BINTIME_MONOTONIC_FAST は、カーネルのブート以来の経
                     過時間を格納しています。この設定は、デフォルトで
                     BPF_T_MICROTIME に初期化されています。

     BIOCFEEDBACK    (u_int) パケットフィードバックモードに設定します。これに
                     よって、インタフェースを通る出力が成功するとき、インタ
                     フェースへの入力のように、注入されたパケットをフィード
                     バックすることができます。BPF_D_INOUT 方向が設定されると
                     き、注入された発信パケットは、重複を避けるために BPF に
                     よって返されません。このフラグは、デフォルトで 0 に初期化
                     されます。

     BIOCLOCK        bpf 記述子でロックされたフラグを設定します。これは、デバ
                     イスの基本的な操作パラメータを変更することができるかもし
                     れない ioctl コマンドの実行を防ぎます。

     BIOCGETBUFMODE

     BIOCSETBUFMODE  (u_int) 現在の bpf のバッファリングモードを取得か、または
                     設定します。指定できる値は、バッファリングされた読み込み
                     モードの BPF_BUFMODE_BUFFER と 0 コピーバッファモードの
                     BPF_BUFMODE_ZBUF です。

     BIOCSETZBUF     (struct bpf_zbuf) 現在の 0 コピーバッファ位置を設定しま
                     す。バッファ位置は、いったん 0 コピーバッファモードが選択
                     されて、インタフェースにアタッチする前にだけ設定されま
                     す。バッファは、同じサイズ、ページで整列され、ページの整
                     数の倍数のサイズでなければなりません。3 つのフィールド
                     bz_bufa, bz_bufbbz_buflen は、書き込まなければなりま
                     せん。バッファが、既にこのデバイスに設定されていたなら、
                     ioctl は、失敗します。

     BIOCGETZMAX     (size_t) 許された最も大きい個々の 0 コピーバッファサイズ
                     を取得します。2 つのバッファが 0 コピーバッファモードで使
                     用されるとき、(実際の) 制限は、返されたサイズの 2 倍で
                     す。0 コピーバッファが、カーネルアドレス空間を消費すると
                     き、特に 32 ビットのシステムで使用中の複数の bpf 記述子が
                     あるとき、バッファサイズの保守的な選択が勧められます。

     BIOCROTZBUF     任意のデータがバッファに存在するなら、次のバッファの所有
                     権を強制的にユーザ空間に割り当てられます。データが在して
                     いないなら、バッファは、カーネルによって所有されていたま
                     まとなります。これによって、0 コピーバッファリングの消費
                     者は、タイムアウトを実装することができ、部分的に満たされ
                     たバッファを検索することができます。データがバッファに存
                     在しなくて、したがって、所有権が割り当てられない場合を扱
                     うために、ユーザプロセスは、bzh_kernel_gen に対して
                     bzh_user_gen をチェックしなければなりません。

BPF ヘッダ
     次の構造の 1 つは、read(2) によって、または 0 コピーバッファを通して返さ
     れた各パケットの先頭に追加されます:

     struct bpf_xhdr {
             struct bpf_ts   bh_tstamp;     /* タイムスタンプ */
             uint32_t        bh_caplen;     /* キャプチャされた部分の長さ */
             uint32_t        bh_datalen;    /* パケットのオリジナルの長さ */
             u_short         bh_hdrlen;     /* bpf ヘッダの長さ (この構造体
                                              + 境界調整パディング) */
     };

     struct bpf_hdr {
             struct timeval  bh_tstamp;     /* タイムスタンプ */
             uint32_t        bh_caplen;     /* キャプチャされた部分の長さ */
             uint32_t        bh_datalen;    /* パケットのオリジナルの長さ */
             u_short         bh_hdrlen;     /* bpf ヘッダの長さ (この構造体
                                              + 境界調整パディング) */
     };

     ホスト順に格納された値のフィールドは、次の通りです:

     bh_tstamp   パケットがパケットフィルタによって処理された時刻。
     bh_caplen   パケットのキャプチャされている部分の長さ。これは、フィルタに
                 よって指定された切り詰められた量の最小限とパケットの長さで
                 す。
     bh_datalen  通信する配線から離れたパケットの長さ。この値は、フィルタに
                 よって指定された切り詰められた量に依存しません。
     bh_hdrlen   sizeof(struct bpf_xhdr) または sizeof(struct bpf_hdr) と等し
                 くないかもしれない、bpf ヘッダの長さ。

     bh_hdrlen フィールドは、ヘッダとリンクレベルプロトコルの間のパディングと
     なるように存在しています。ここでの目的は、パケットデータ構造の適切な境界
     調整を保証することです。それは、境界調整に注意を要するアーキテクチャで必
     要であり、他の多くのアーキテクチャで性能を向上させます。パケットフィルタ
     は、bpf_xhdr, bpf_hdr とネットワーク層のヘッダがワード境界になることを保
     証します。現在、bpf_hdr は、タイムスタンプが後方互換性の理由のために
     BPF_T_MICROTIME, BPF_T_MICROTIME_FAST, BPF_T_MICROTIME_MONOTONIC,
     BPF_T_MICROTIME_MONOTONIC_FAST または BPF_T_NONE に設定されるとき、使用さ
     れます。そうでなければ、bpf_xhdr が使用されます。しかしながら、bpf_hdr
     は、近い将来、廃止される可能性があります。境界調整が制限されたマシンのリ
     ンク層プロトコルのフィールドにアクセスするとき、適切な注意を払わなければ
     なりません。(これは、イーサネットに関する問題ではありません。なぜなら、タ
     イプフィールドは、偶数オフセットに当たる short であり、アドレスは、おそら
     くバイト単位でアクセスされるからです)。

     さらに、個々のパケットは、それぞれワード境界で始まるようにパディングされ
     ます。これは、アプリケーションがパケットから次のパケットをどのように取得
     するかに関する何らかの知識があることを必要とします。マクロ BPF_WORDALIGN
     は、この処理過程を容易にするために <net/bpf.h> で定義されます。その引数
     は、最も近いワード境界値 (ここで、ワードは、BPF_ALIGNMENT バイト幅) に切
     り上げられます。

     例えば `p' がパケットの始まりを指すなら、次の式は、ポインタを次のパケット
     へ進めます:
           p = (char *)p + BPF_WORDALIGN(p->bh_hdrlen + p->bh_caplen)

     境界調整の機構が適切に動作するためには read(2) に渡されるバッファは、それ
     自体がワード境界になければなりません。malloc(3) 関数は、常に境界調整され
     たバッファを返します。

フィルタマシン
     フィルタプログラムは、すべての分岐が前方に方向づけられた return 命令で終
     わる、命令の配列です。各命令は、アキュムレータ、インデックスレジスタ、一
     時メモリ記憶、および内在するプログラムカウンタから成る疑似マシン状態で何
     らかの動作を実行します。

     次の構造体は、命令形式を定義します:

     struct bpf_insn {
             u_short code;
             u_char  jt;
             u_char  jf;
             u_long k;
     };

     k フィールドは、さまざまな命令でさまざまな方法で使用され、jt と jf フィー
     ルドは、分岐命令によってオフセットとして使用されます。オペコードは、準階
     層的な方法でコード化されます。次の 8 つのクラスの命令があります: BPF_LD,
     BPF_LDX, BPF_ST, BPF_STX, BPF_ALU, BPF_JMP, BPF_RET と BPF_MISC です。他
     の様々なモードと操作ビットは、実際の命令を与えるためにクラスに論理和 (or)
     されます。クラスとモードは、<net/bpf.h> で定義されています。

     以下は、定義されたそれぞれの bpf 命令のセマンティクス (意味) です。便宜的
     に A は、アキュムレータ、X は、インデックスレジスタ、P[] は、パケットデー
     タ、M[] は、一時メモリ記憶であるとします。P[i:n] は、パケット中のバイトオ
     フセット ``i'' のデータを示し、ワード (n=4)、符号無しハーフワード (n=2)
     または符号無しバイト (n=1) と解釈されます。M[i] は、ワード単位でのみアド
     レス指定される一時メモリ記憶で i 番目のワードを示します。メモリ記憶は、0
     から BPF_MEMWORDS - 1 までインデックス付けされます。k, jt と jf は、命令
     定義の中で対応するフィールドです。``len'' は、パケットの長さを参照しま
     す。

     BPF_LD    これらの命令は、値をアキュムレータにコピーします。ソースオペラ
               ンドのタイプは、``アドレッシングモード'' によって指定され、定数
               (BPF_IMM), 固定オフセットのパケットデータ (BPF_ABS), 可変オフ
               セットのパケットデータ (BPF_IND), パケットの長さ (BPF_LEN), ま
               たは一時メモリ記憶内のワード (BPF_MEM) になり得ます。BPF_IND と
               BPF_ABS に対しては、データサイズは、ワード (BPF_W), ハーフワー
               ド (BPF_H) またはバイト (BPF_B) を指定しなければなりません。
               BPF_LD 命令として認識されるすべてのセマンティクス (意味) は、次
               の通りです。

               BPF_LD+BPF_W+BPF_ABS    A <- P[k:4]
               BPF_LD+BPF_H+BPF_ABS    A <- P[k:2]
               BPF_LD+BPF_B+BPF_ABS    A <- P[k:1]
               BPF_LD+BPF_W+BPF_IND    A <- P[X+k:4]
               BPF_LD+BPF_H+BPF_IND    A <- P[X+k:2]
               BPF_LD+BPF_B+BPF_IND    A <- P[X+k:1]
               BPF_LD+BPF_W+BPF_LEN    A <- len
               BPF_LD+BPF_IMM          A <- k
               BPF_LD+BPF_MEM          A <- M[k]

     BPF_LDX   これらの命令は、値をインデックスレジスタにロードします。このア
               ドレッシングモードは、アキュムレータのものをロードするよりもよ
               り制限されていますが、効率的に IP ヘッダ長をロードするための
               ハッキングである、BPF_MSH, を含んでいることに注意してください。

               BPF_LDX+BPF_W+BPF_IMM   X <- k
               BPF_LDX+BPF_W+BPF_MEM   X <- M[k]
               BPF_LDX+BPF_W+BPF_LEN   X <- len
               BPF_LDX+BPF_B+BPF_MSH   X <- 4*(P[k:1]&0xf)

     BPF_ST    この命令は、アキュムレータを一時メモリに格納します。宛先の可能
               性が 1 つしかないので、アドレッシングモードを必要としません。

               BPF_ST                  M[k] <- A

     BPF_STX   この命令は、インデックスレジスタを一時メモリ記憶に格納します。

               BPF_STX                 M[k] <- X

     BPF_ALU   alu 命令は、アキュムレータとインデックスレジスタまたは定数の間
               の操作を実行し、アキュムレータに結果を格納します。バイナリ操作
               のためには、ソースモードは、(BPF_K または BPF_X) が必要です。

               BPF_ALU+BPF_ADD+BPF_K   A <- A + k
               BPF_ALU+BPF_SUB+BPF_K   A <- A - k
               BPF_ALU+BPF_MUL+BPF_K   A <- A * k
               BPF_ALU+BPF_DIV+BPF_K   A <- A / k
               BPF_ALU+BPF_MOD+BPF_K   A <- A % k
               BPF_ALU+BPF_AND+BPF_K   A <- A & k
               BPF_ALU+BPF_OR+BPF_K    A <- A | k
               BPF_ALU+BPF_XOR+BPF_K   A <- A ^ k
               BPF_ALU+BPF_LSH+BPF_K   A <- A << k
               BPF_ALU+BPF_RSH+BPF_K   A <- A >> k
               BPF_ALU+BPF_ADD+BPF_X   A <- A + X
               BPF_ALU+BPF_SUB+BPF_X   A <- A - X
               BPF_ALU+BPF_MUL+BPF_X   A <- A * X
               BPF_ALU+BPF_DIV+BPF_X   A <- A / X
               BPF_ALU+BPF_MOD+BPF_X   A <- A % X
               BPF_ALU+BPF_AND+BPF_X   A <- A & X
               BPF_ALU+BPF_OR+BPF_X    A <- A | X
               BPF_ALU+BPF_XOR+BPF_X   A <- A ^ X
               BPF_ALU+BPF_LSH+BPF_X   A <- A << X
               BPF_ALU+BPF_RSH+BPF_X   A <- A >> X
               BPF_ALU+BPF_NEG         A <- -A

     BPF_JMP   ジャンプ命令は、制御の流れを変更します。条件付きのジャンプは、
               アキュムレータと定数 (BPF_K) またはインデックスレジスタ (BPF_X)
               を比較します。結果が真 (または非 0) であるなら、真の分岐が解釈
               され、そうでなければ偽の分岐が解釈されます。ジャンプオフセット
               は、8 ビットでコード化されるので、最長のジャンプは、256 命令で
               す。しかしながら、(BPF_JA) オペコードは、任意の距離がある行き先
               を許す、オフセットとして 32 ビットの k フィールドを使用して常に
               ジャンプします。すべての条件文は、慣習として符号無しの比較を使
               用します。

               BPF_JMP+BPF_JA          pc += k
               BPF_JMP+BPF_JGT+BPF_K   pc += (A > k) ? jt : jf
               BPF_JMP+BPF_JGE+BPF_K   pc += (A >= k) ? jt : jf
               BPF_JMP+BPF_JEQ+BPF_K   pc += (A == k) ? jt : jf
               BPF_JMP+BPF_JSET+BPF_K  pc += (A & k) ? jt : jf
               BPF_JMP+BPF_JGT+BPF_X   pc += (A > X) ? jt : jf
               BPF_JMP+BPF_JGE+BPF_X   pc += (A >= X) ? jt : jf
               BPF_JMP+BPF_JEQ+BPF_X   pc += (A == X) ? jt : jf
               BPF_JMP+BPF_JSET+BPF_X  pc += (A & X) ? jt : jf

     BPF_RET   リターン命令は、フィルタプログラムを終了し、受信するパケットの
               量を指定します (すなわち、それらは、切り詰め量を返します)。0 の
               返り値は、パケットが無視されるべきであることを示しています。返
               り値は、定数 (BPF_K) またはアキュムレータ (BPF_A) のいずれかで
               す。

               BPF_RET+BPF_A           A バイト受信
               BPF_RET+BPF_K           k バイト受信

     BPF_MISC  その他のカテゴリは、上記のクラスに適合しないもの、および追加す
               る必要がある新しい命令のために作成されました。現在、これらは、
               インデックスレジスタをアキュムレータにコピーするまたはその逆を
               行うレジスタ転送命令です。

               BPF_MISC+BPF_TAX        X <- A
               BPF_MISC+BPF_TXA        A <- X

     bpf インタフェースは、配列の初期化を容易にするために次のマクロを提供して
     います: BPF_STMT(opcode, operand) と BPF_JUMP(opcode, operand,
     true_offset, false_offset) です。

SYSCTL 変数
     sysctl(8) 変数の 1 組は、bpf サブシステムの振る舞いを制御します:

     net.bpf.optimize_writers: 0
             様々なプログラムは、生のパケット (cdpd、lldpd、dhcpd、dhcp 中継な
             どは、そのようなプログラムのよい例です) を送信するために (しかし
             受信ではなく) BPF を使用します。それらは、それらに送信されるため
             の着信パケットを必要としません、プログラムが pcap_set_filter() に
             よって明示的に読み込みフィルタを指定するまで、新しい BPF ユーザを
             書き込み専用のインタフェースリストにアタッチすることで、このオプ
             ションを調整します。これは、高速インタフェースのためのあらゆる性
             能劣化を排除します。

     net.bpf.stats:
             一般的な統計を検索するためのバイナリインタフェース。

     net.bpf.zerocopy_enable: 0
             0 のコピーがネットの BPF リーダで使用されることを可能にします。注
             意して使用してください。

     net.bpf.maxinsns: 512
             BPF プログラムが含むことができる指示の最大数。あらゆるフィルタの
             ための指示の概数を決定するために tcpdump(1) -d オプションを使用し
             ます。

     net.bpf.maxbufsize: 524288
             パケットのバッファのために割り付ける最大のバッファサイズ。

     net.bpf.bufsize: 4096
             パケットのバッファに割り付けるデフォルトのバッファサイズ。

使用例
     次のフィルタは、Reverse ARP デーモンから取得されます。それは、Reverse ARP
     要求のみを受信します。

     struct bpf_insn insns[] = {
             BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
             BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETHERTYPE_REVARP, 0, 3),
             BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20),
             BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, REVARP_REQUEST, 0, 1),
             BPF_STMT(BPF_RET+BPF_K, sizeof(struct ether_arp) +
                      sizeof(struct ether_header)),
             BPF_STMT(BPF_RET+BPF_K, 0),
     };

     このフィルタは、ホスト 128.3.112.15 と 128.3.112.35 の間の IP パケットだ
     けを受け付けます。

     struct bpf_insn insns[] = {
             BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
             BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETHERTYPE_IP, 0, 8),
             BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
             BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
             BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
             BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4),
             BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3),
             BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
             BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1),
             BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
             BPF_STMT(BPF_RET+BPF_K, 0),
     };

     最後に、このフィルタは、TCP finger パケットだけを返します。私たちは、TCP
     ヘッダに達するために IP ヘッダを解析しなければなりません。BPF_JSET 命令
     は、IP フラグメントオフセットが 0 であることをチェックし、それで、私たち
     は、TCP ヘッダがあることを確信します。

     struct bpf_insn insns[] = {
             BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
             BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETHERTYPE_IP, 0, 10),
             BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 23),
             BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_TCP, 0, 8),
             BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20),
             BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 0x1fff, 6, 0),
             BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 14),
             BPF_STMT(BPF_LD+BPF_H+BPF_IND, 14),
             BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 2, 0),
             BPF_STMT(BPF_LD+BPF_H+BPF_IND, 16),
             BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 0, 1),
             BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
             BPF_STMT(BPF_RET+BPF_K, 0),
     };

関連項目
     tcpdump(1), ioctl(2), kqueue(2), poll(2), select(2), byteorder(3),
     ng_bpf(4), bpf(9)

     McCanne, S.  and Jacobson V., An efficient, extensible, and portable
     network monitor.

歴史
     Enet パケットフィルタは、1980 年に Carnegie-Mellon 大学で Mike Accetta と
     Rick Rashid によって作成されました。Jeffrey Mogul は、Stanford でコードを
     BSD に移植して、1983 年以降開発を続けました。それ以来、それは、DEC の
     Ultrix Packet Filter、SunOS 4.1 の STREAMS NIT モジュール、そして BPF へ
     と発展しています。

作者
     Lawrence Berkeley 研究所の Steven McCanne は、1990 年夏に BPF を実装しま
     した。デザインの多くは、Van Jacobson のおかげです。

     0 コピーバッファのサポートは、Seccuris Inc. と契約して Robert N. M.
     Watson によって追加されました。

バグ
     読み込みバッファは、(BIOCGBLEN ioctl によって返される) 固定サイズでなけれ
     ばなりません。

     無差別モードを要求しないファイルは、同じハードウェアインタフェースでこの
     モードを要求する別のファイルの副作用として受信パケットを無差別に受信する
     かもしれません。これは、オーバヘッドのある追加処理でカーネルで修正するこ
     とができるかもしれません。しかしながら、私たちは、すべてのファイルがイン
     タフェースが無差別であると仮定しなければならないようなモデルを好みます。
     そして、そうだとしたら必要に応じて、外部のパケットを拒否するためにフィル
     タを利用しなければなりません。

     可変長ヘッダがあるデータリンクプロトコルは、現在サポートされていません。

     SEESENT, DIRECTION と FEEDBACK の設定は、ソフトウェアループバックとポイン
     トツーポイントインタフェースよりむしろハードウェアループバックがあるそれ
     らを含んで、いくつかのインタフェースタイプで正しく動作しないことが観測さ
     れました。それらは、広範囲のイーサネットスタイルインタフェースで正しく機
     能するように思われます。

FreeBSD 12.2                   October 21, 2016                   FreeBSD 12.2

Table of Contents

FreeBSD マニュアル検索