PF(4) | FreeBSD Kernel Interfaces Manual | PF(4) |
名称
pf — パケットフィルタ書式
device pfoptions PF_DEFAULT_TO_DROP
解説
パケットフィルタリングは、カーネルで行われます。疑似デバイス /dev/pf は、ユーザランドプロセスで ioctl(2) インタフェースを通るパケットフィルタの振る舞いを制御できるようにします。フィルタを有効にして無効にする、ルールセットのロード、個別の規則か状態テーブルエントリの追加と削除、統計値の検索するコマンドがあります。最も一般的に使用される関数は、 pfctl(8) によってカバーされています。一つの ioctl(2) 呼び出し以上に影響を及ぼすルールセットをロードするような操作は、複数の並列操作の発生を防ぐ、いわゆる チケット を必要とします。
(アドレスとポートのような) パケットデータを参照する ioctl(2) パラメータ構造のフィールドは、一般的にネットワークバイト順が期待されます。
規則とアドレステーブルは、いわゆる anchor (アンカ) に含まれています。 ioctl(2) 要求をサービスするとき、引数構造体のアンカフィールドが空であるなら、カーネルは、作動中にデフォルトのアンカ (すなわち、メインルールセット) を使用します。アンカは、名前によって指定され、ファイルシステム階層構造がどのように配置されているかと同様に、‘/’文字で分離された構成要素で、入れ子にされるかもしれません。アンカパスの最終的な構成要素は、操作が実行されるアンカです。
SYSCTL 変数とローダ調整変数
次の loader(8) 調整変数が利用可能です。- net.pf.states_hashsize
- 状態を格納するハッシュテーブルのサイズ。 2 のべき乗であるべきです。デフォルト値は、32768 です。
- net.pf.source_nodes_hashsize
- ソースノードを格納するハッシュテーブルのサイズ。 2 のべき乗であるべきです。デフォルト値は、8192 です。
一致する名前がある読み込み専用の sysctl(8) 変数は、実行時に現在の値を得るために提供されています。
カーネルオプション
カーネル設定ファイルの次のオプションは、 pf 操作と関連しています:
- PF_DEFAULT_TO_DROP
- デフォルトでデフォルトポリシをドロップ (drop) に変更します
IOCTL インタフェース
pf は、< net/pfvar.h>を通して利用可能な、次の ioctl(2) コマンドをサポートします:- DIOCSTART
- パケットフィルタを開始する。
- DIOCSTOP
- パケットフィルタを停止する。
- DIOCSTARTALTQ
- ALTQ バンド (帯域) 幅制御システムを開始する ( altq(9) 参照)。
- DIOCSTOPALTQ
- ALTQ バンド (帯域) 幅制御システムを停止する。
- DIOCBEGINADDRS struct pfioc_pooladdr *pp
-
struct pfioc_pooladdr { u_int32_t action; u_int32_t ticket; u_int32_t nr; u_int32_t r_num; u_int8_t r_action; u_int8_t r_last; u_int8_t af; char anchor[MAXPATHLEN]; struct pf_pooladdr addr; };
バッファアドレスプールをクリアし、その後の DIOCADDADDR, DIOCADDRULE と DIOCCHANGERULE DIOCADDADDR、呼び出しのための ticket を取得します。
- DIOCADDADDR struct pfioc_pooladdr *pp
-
次の DIOCADDRULE または DIOCCHANGERULE 呼び出しに使用されるバッファアドレスプールにプールアドレス addr を追加します。他のすべての構造体のメンバは、無視されます。
- DIOCADDRULE struct pfioc_rule *pr
-
struct pfioc_rule { u_int32_t action; u_int32_t ticket; u_int32_t pool_ticket; u_int32_t nr; char anchor[MAXPATHLEN]; char anchor_call[MAXPATHLEN]; struct pf_rule rule; };
不活発なルールセットの終りに rule を追加します。この呼び出しは、以前の DIOCXBEGIN 呼び出しで取得された ticket と DIOCBEGINADDRS 呼び出しで取得された pool_ticket を必要とします。また、プールアドレスが必要であるなら、 DIOCADDADDR を呼び出さなければなりません。オプションの anchor 名は、規則を追加する anchor (アンカ) を示します。 nr と action は、無視されます。
- DIOCADDALTQ struct pfioc_altq *pa
-
ALTQ 制御規則またはキューを追加します。
struct pfioc_altq { u_int32_t action; u_int32_t ticket; u_int32_t nr; struct pf_altq altq; };
- DIOCGETRULES struct pfioc_rule *pr
- その後の DIOCGETRULE 呼び出しのための ticket と、アクティブなルールセット中の規則の番号 nr を取得します。
- DIOCGETRULE struct pfioc_rule *pr
- 以前の DIOCGETRULES 呼び出しで得られた ticket を使用して、その番号 nr によって rule を取得します。 action が PF_GET_CLR_CNTR に設定されるなら、要求された規則で規則毎の統計値は、クリアされます。
- DIOCGETADDRS struct pfioc_pooladdr *pp
- 以前の DIOCGETADDR 呼び出しのための ticket と、 r_action, r_num と anchor で指定された規則中のプールアドレスの番号 nr を取得します。
- DIOCGETADDR struct pfioc_pooladdr *pp
- 以前の DIOCGETADDRS 呼び出しで得られた ticket を使用して、 r_action, r_num と anchor で指定された規則からその番号 nr によってプールアドレス addr を取得します。
- DIOCGETALTQS struct pfioc_altq *pa
- 以前の DIOCGETALTQ のための ticket と、アクティブリスト中のキューの番号 nr を取得します。
- DIOCGETALTQ struct pfioc_altq *pa
- 以前の DIOCGETALTQS 呼び出しで得られた ticket を使用して、その番号 nr によってキュー制御規則 altq を取得します。
- DIOCGETQSTATS struct pfioc_qstats *pq
-
キューおける統計値を取得します。
struct pfioc_qstats { u_int32_t ticket; u_int32_t nr; void *buf; int nbytes; u_int8_t scheduler; };
この呼び出しは、 nr によって指定されたキューのための長さ nbytes の統計値 buf のバッファへのポインタに書き込みます。
- DIOCGETRULESETS struct pfioc_ruleset *pr
-
struct pfioc_ruleset { u_int32_t nr; char path[MAXPATHLEN]; char name[PF_ANCHOR_NAME_SIZE]; };
その後の DIOCGETRULESET 呼び出しでの使用のために path によって指定されたアンカに直接アタッチされたルールセット (すなわち、アンカ) の番号 nr を取得します。入れ子にされたアンカは、それらが与えられたアンカに直接アタッチされないので、含まれません。与えられたアンカが存在しないなら、この ioctl は、 EINVAL を返します。
- DIOCGETRULESET struct pfioc_ruleset *pr
- 与えられたアンカ path から、その番号 nr によってルールセット (すなわち、アンカ) name と、以前の DIOCGETRULESETS 呼び出しで得ることができる最大数を取得します。この ioctl は、与えられたアンカが存在しないなら、 EINVAL を返すか、または別のプロセスが同時にルールセットを更新するなら、 EBUSY を返します。
- DIOCADDSTATE struct pfioc_state *ps
-
状態エントリを追加します。
struct pfioc_state { struct pfsync_state state; };
- DIOCGETSTATE struct pfioc_state *ps
- 状態テーブルから state 構造体の id と creatorid フィールドによって特定されるエントリを抽出します。
- DIOCKILLSTATES struct pfioc_state_kill *psk
-
状態テーブルから一致するエントリを削除します。
psk_killed 中の kill された状態の数を返します。
struct pfioc_state_kill { struct pf_state_cmp psk_pfcmp; sa_family_t psk_af; int psk_proto; struct pf_rule_addr psk_src; struct pf_rule_addr psk_dst; char psk_ifname[IFNAMSIZ]; char psk_label[PF_RULE_LABEL_SIZE]; u_int psk_killed; };
- DIOCCLRSTATES struct pfioc_state_kill *psk
- すべての状態をクリアします。それは、 DIOCKILLSTATES のように動作しますが、 pfioc_state_kill 構造体の psk_af, psk_proto, psk_src と psk_dst フィールドを無視します。
- DIOCSETSTATUSIF struct pfioc_if *pi
-
統計値が累算されるインタフェースを指定します。
struct pfioc_if { char ifname[IFNAMSIZ]; };
- DIOCGETSTATUS struct pf_status *s
-
内部のパケットフィルタの統計値を取得します。
struct pf_status { u_int64_t counters[PFRES_MAX]; u_int64_t lcounters[LCNT_MAX]; u_int64_t fcounters[FCNT_MAX]; u_int64_t scounters[SCNT_MAX]; u_int64_t pcounters[2][2][3]; u_int64_t bcounters[2][2]; u_int32_t running; u_int32_t states; u_int32_t src_nodes; u_int32_t since; u_int32_t debug; u_int32_t hostid; char ifname[IFNAMSIZ]; u_int8_t pf_chksum[MD5_DIGEST_LENGTH]; };
- DIOCCLRSTATUS
- 内部のパケットフィルタの統計値をクリアします。
- DIOCNATLOOK struct pfioc_natlook *pnl
-
発信元 (始点) と宛先 (終点) とポートで状態テーブルエントリを検索します。
struct pfioc_natlook { struct pf_addr saddr; struct pf_addr daddr; struct pf_addr rsaddr; struct pf_addr rdaddr; u_int16_t sport; u_int16_t dport; u_int16_t rsport; u_int16_t rdport; sa_family_t af; u_int8_t proto; u_int8_t direction; };
- DIOCSETDEBUG u_int32_t *level
-
デバッグレベルを設定します。
enum { PF_DEBUG_NONE, PF_DEBUG_URGENT, PF_DEBUG_MISC, PF_DEBUG_NOISY };
- DIOCGETSTATES struct pfioc_states *ps
-
struct pfioc_states { int ps_len; union { caddr_t psu_buf; struct pf_state *psu_states; } ps_u; #define ps_buf ps_u.psu_buf #define ps_states ps_u.psu_states };
ps_len がエントリで 0 以外であるなら、このサイズに収まるできるだけ多くの状態は、供給されたバッファ ps_states にコピーされます。終了時に、 ps_len は、常にすべての状態テーブルエントリを保持するために必要な合計のサイズに設定されます (すなわち、それは、
sizeof(struct pf_state) * nr
に設定されます)。 - DIOCCHANGERULE struct pfioc_rule *pcr
-
rule.action によって指定された ruleset 中の
rule を追加するか、または削除します。
実行される操作のタイプは、次のいずれかで指定できる、 action 示されます:
enum { PF_CHANGE_NONE, PF_CHANGE_ADD_HEAD, PF_CHANGE_ADD_TAIL, PF_CHANGE_ADD_BEFORE, PF_CHANGE_ADD_AFTER, PF_CHANGE_REMOVE, PF_CHANGE_GET_TICKET };
ticket は、 PF_CHANGE_GET_TICKET 以外のすべての動作 (action) のために PF_CHANGE_GET_TICKET で得られる値を設定しなければなりません。 pool_ticket は、 PF_CHANGE_REMOVE と PF_CHANGE_GET_TICKET 以外のすべての動作 (action) のための DIOCBEGINADDRS 呼び出しで得られる値を設定しなければなりません。 anchor は、どのアンカの操作が適用されるかを示します。 nr は、 PF_CHANGE_ADD_BEFORE, PF_CHANGE_ADD_AFTER または PF_CHANGE_REMOVE 動作が適用されている規則番号を示します。
- DIOCCHANGEADDR struct pfioc_pooladdr *pca
- r_action, r_num と anchor によって指定された規則から、プールアドレス addr を追加するか、または削除します。
- DIOCSETTIMEOUT struct pfioc_tm *pt
-
struct pfioc_tm { int timeout; int seconds; };
timeout の状態タイムアウトを seconds に設定します。古い値は、 seconds に置かれます。 timeout に指定可能な値は、< net/pfvar.h>の PFTM_* 値を調べてください。
- DIOCGETTIMEOUT struct pfioc_tm *pt
- timeout の状態タイムアウトを取得します。値は、 seconds フィールドに置かれます。
- DIOCCLRRULECTRS
- 規則毎の統計値をクリアします。
- DIOCSETLIMIT struct pfioc_limit *pl
-
パケットフィルタで使用されるメモリプールにおけるハードの制限を設定します。
struct pfioc_limit { int index; unsigned limit; }; enum { PF_LIMIT_STATES, PF_LIMIT_SRC_NODES, PF_LIMIT_FRAGS, PF_LIMIT_TABLE_ENTRIES, PF_LIMIT_MAX };
- DIOCGETLIMIT struct pfioc_limit *pl
- index によって示されたメモリプールのためのハードの limit を取得します。
- DIOCRCLRTABLES struct pfioc_table *io
-
すべてのテーブルをクリアします。同じ構造体を使用する基数テーブルを操作するすべての ioctl は、以下に説明されます。
DIOCRCLRTABLES に関して、
pfrio_ndel は、終了時に削除されたテーブルの数を含んでいます。
struct pfioc_table { struct pfr_table pfrio_table; void *pfrio_buffer; int pfrio_esize; int pfrio_size; int pfrio_size2; int pfrio_nadd; int pfrio_ndel; int pfrio_nchange; int pfrio_flags; u_int32_t pfrio_ticket; }; #define pfrio_exists pfrio_nadd #define pfrio_nzero pfrio_nadd #define pfrio_nmatch pfrio_nadd #define pfrio_naddr pfrio_size2 #define pfrio_setflag pfrio_size2 #define pfrio_clrflag pfrio_nadd
- DIOCRADDTABLES struct pfioc_table *io
-
1 つ以上のテーブルを作成します。登録時に、
pfrio_buffer は、少なくとも
pfrio_size 要素を含む
struct pfr_table の配列を指さなければなりません。
pfrio_esize は、
struct pfr_table のサイズでなければなりません。終了時に、
pfrio_nadd は、事実上作成されたテーブルの数を含んでいます。
struct pfr_table { char pfrt_anchor[MAXPATHLEN]; char pfrt_name[PF_TABLE_NAME_SIZE]; u_int32_t pfrt_flags; u_int8_t pfrt_fback; };
- DIOCRDELTABLES struct pfioc_table *io
- 1 つ以上のテーブルを削除します。登録時に、 pfrio_buffer は、少なくとも pfrio_size 要素を含む struct pfr_table の配列を指さなければなりません。 pfrio_esize は、 struct pfr_table のサイズでなければなりません。終了時に、 pfrio_ndel は、事実上削除されたテーブルの数を含んでいます。
- DIOCRGETTABLES struct pfioc_table *io
- すべてのテーブルのリストを取得します。登録時に、 pfrio_buffer[pfrio_size] は、 pfr_table 構造体のための有効な書き込み可能なバッファを含んでいます。終了時に、 pfrio_size は、バッファの中に書き込まれたテーブルの数を含んでいます。バッファが小さ過ぎるなら、カーネルは、何も格納しませんが、エラーを除いて、単に必要なバッファサイズを返します。
- DIOCRGETTSTATS struct pfioc_table *io
-
この呼び出しは、
DIOCRGETTABLES に似ていますが、
pfr_tstats 構造体の配列を取得するために使用されます。
struct pfr_tstats { struct pfr_table pfrts_t; u_int64_t pfrts_packets [PFR_DIR_MAX][PFR_OP_TABLE_MAX]; u_int64_t pfrts_bytes [PFR_DIR_MAX][PFR_OP_TABLE_MAX]; u_int64_t pfrts_match; u_int64_t pfrts_nomatch; long pfrts_tzero; int pfrts_cnt; int pfrts_refcnt[PFR_REFCNT_MAX]; }; #define pfrts_name pfrts_t.pfrt_name #define pfrts_flags pfrts_t.pfrt_flags
- DIOCRCLRTSTATS struct pfioc_table *io
- 1 つ以上のテーブルの統計値をクリアします。登録時に、 pfrio_buffer は、少なくとも pfrio_size 要素を含む struct pfr_table の配列を指さなければなりません。 pfrio_esize は、 struct pfr_table のサイズでなければなりません。終了時に、 pfrio_nzero は、事実上クリアされたテーブルの数を含んでいます。
- DIOCRCLRADDRS struct pfioc_table *io
- テーブル中のすべてのアドレスをクリアします。登録時に、 pfrio_table は、クリアされるテーブルを含んでいます。終了時に、 pfrio_ndel は、削除されたアドレスの数を含んでいます。
- DIOCRADDADDRS struct pfioc_table *io
-
テーブルに 1 つ以上のアドレスを追加します。登録時に、
pfrio_table は、テーブル ID を含み、
pfrio_buffer は、テーブルに追加するために少なくとも
pfrio_size 要素を含む
struct pfr_addr の配列を指さなければなりません。
pfrio_esize は、
struct pfr_addr のサイズでなければなりません。終了時に、
pfrio_nadd は、事実上追加されたアドレスの数を含んでいます。
struct pfr_addr { union { struct in_addr _pfra_ip4addr; struct in6_addr _pfra_ip6addr; } pfra_u; u_int8_t pfra_af; u_int8_t pfra_net; u_int8_t pfra_not; u_int8_t pfra_fback; }; #define pfra_ip4addr pfra_u._pfra_ip4addr #define pfra_ip6addr pfra_u._pfra_ip6addr
- DIOCRDELADDRS struct pfioc_table *io
- テーブルから 1 つ以上のアドレスを削除します。登録時に、 pfrio_table は、テーブル ID を含み、 pfrio_buffer は、テーブルから削除するために少なくとも pfrio_size 要素を含む struct pfr_addr の配列を指さなければなりません。 pfrio_esize は、 struct pfr_addr のサイズでなければなりません。終了時に、 pfrio_ndel は、事実上削除されたアドレスの数を含んでいます。
- DIOCRSETADDRS struct pfioc_table *io
-
新しいアドレスリストによってテーブルの内容を置き換えます。これは、すべての構造メンバを使用する、最も複雑なコマンドです。
登録時に、 pfrio_table は、テーブル ID を含み、 pfrio_buffer は、テーブルの新しい内容となる少なくとも pfrio_size 要素を含む struct pfr_addr の配列を指さなければなりません。 pfrio_esize は、 struct pfr_addr のサイズでなければなりません。さらに、 pfrio_size2 が 0 でなければ、 pfrio_buffer[pfrio_size..pfrio_size2] は、カーネルが、置き換え操作の間に削除されたアドレスをコピーすることができように、書き込み可能なバッファでなければなりません。終了時に、 pfrio_ndel, pfrio_nadd と pfrio_nchange は、カーネルによって削除され、追加され、変更されたアドレスの数を含んでいます。 pfrio_size2 がエントリに設定されたなら、 pfrio_size2 は、まさに DIOCRGETADDRS のように使用されるバッファのサイズを指します。
- DIOCRGETADDRS struct pfioc_table *io
- テーブルのすべてのアドレスを取得します。登録時に、 pfrio_table は、テーブル ID を含み、 pfrio_buffer[pfrio_size] は、 pfr_addr 構造体のための有効な書き込み可能なバッファを含んでいます。終了時に、 pfrio_size は、バッファ中に書き込まれたアドレスの数を含んでいます。バッファが小さ過ぎたなら、カーネルは、何も格納しませんが、エラーリターンを除いて、単に必要なバッファサイズを返します。
- DIOCRGETASTATS struct pfioc_table *io
-
この呼び出しは、
DIOCRGETADDRS に似ていますが、
pfr_astats 構造体の配列を返します。
struct pfr_astats { struct pfr_addr pfras_a; u_int64_t pfras_packets [PFR_DIR_MAX][PFR_OP_ADDR_MAX]; u_int64_t pfras_bytes [PFR_DIR_MAX][PFR_OP_ADDR_MAX]; long pfras_tzero; };
- DIOCRCLRASTATS struct pfioc_table *io
- 1 つ以上のアドレスの統計値をクリアします。登録時に、 pfrio_table は、テーブル ID を含み、 pfrio_buffer は、テーブルからクリアされるために少なくとも pfrio_size 要素を含む struct pfr_addr の配列を指さなければなりません。 pfrio_esize は、 struct pfr_addr のサイズでなければなりません。終了時に、 pfrio_nzero は、事実上クリアされたアドレスの数を含んでいます。
- DIOCRTSTADDRS struct pfioc_table *io
- 与えられたアドレスがテーブルに一致するか、テストします。登録時に、 pfrio_table は、テーブル ID を含み、 pfrio_buffer は、それぞれがテーブルでマッチがないかテストされる、少なくとも pfrio_size 要素を含む struct pfr_addr の配列を指さなければなりません。 pfrio_esize は、 struct pfr_addr のサイズでなければなりません。終了時に、カーネルは、適切に pfra_fback メンバを設定することによって pfr_addr 配列を更新します。
- DIOCRSETTFLAGS struct pfioc_table *io
- テーブルの PFR_TFLAG_CONST または PFR_TFLAG_PERSIST フラグを変更します。登録時に、 pfrio_buffer は、少なくとも pfrio_size 要素を含む struct pfr_table の配列を指さなければなりません。 pfrio_esize は、 struct pfr_table のサイズでなければなりません。 pfrio_setflag は、追加するフラグを含まなければなりません、一方 pfrio_clrflag は、削除されるフラグを含まなければなりません。終了時に、 pfrio_nchange と pfrio_ndel は、カーネルによって変更されるか、または削除されたテーブルの数を含んでいます。はい、参照されないテーブルの PFR_TFLAG_PERSIST フラグを取り除かれるなら、テーブルは、削除することができます。
- DIOCRINADEFINE struct pfioc_table *io
- アクティブでない集合 (セット) でテーブルを定義します。登録時に、 pfrio_table は、テーブル ID を含み、 pfrio_buffer[pfrio_size] は、テーブルに置く pfr_addr 構造体の配列を含んでいます。また、有効なチケットは、 pfrio_ticket に供給しなければなりません。終了時に、 pfrio_nadd は、既にテーブルがアクティブでないリストで定義されているなら、0 を含み、新しいテーブルが作成してあるなら 1 を含んでいます。 pfrio_naddr は、事実上テーブルに置かれるアドレスの数を含んでいます。
- DIOCXBEGIN struct pfioc_trans *io
-
struct pfioc_trans { int size; /* 要素の数 */ int esize; /* 各要素のバイト単位のサイズ */ struct pfioc_trans_e { int rs_num; char anchor[MAXPATHLEN]; u_int32_t ticket; } *array; };
pfioc_trans_e 配列で指定されたすべてのアクティブでない ruleset をクリアします。各 ruleset に関しては、 DIOCXCOMMIT と DIOCXROLLBACK 呼び出しと同様に、その後の "add rule" ioctl のためにチケットが返されます。
rs_num によって識別されるルールセットのタイプは、次に含まれます:
- PF_RULESET_SCRUB
- scrub (延期する) (パケット正規化) 規則。
- PF_RULESET_FILTER
- フィルタ規則。
- PF_RULESET_NAT
- NAT (Network Address Translation) 規則。
- PF_RULESET_BINAT
- 双方向の NAT 規則。
- PF_RULESET_RDR
- リダイレクト規則。
- PF_RULESET_ALTQ
- ALTQ 制御規則。
- PF_RULESET_TABLE
- アドレステーブル。
- DIOCXCOMMIT struct pfioc_trans *io
- アクティブでない ruleset のベクトルをアクティブな ruleset に不可分に (atomically) 切り換えます。この呼び出しは、すべてのルールセットが失敗するか、または完全に成功するかのいずれかである、標準の二相コミットとして実装されます。この ioctl は、別のプロセスが同じルールセットのいくつかを同時に更新するなら、 EBUSY を返します。
- DIOCXROLLBACK struct pfioc_trans *io
- 最後の DIOCXBEGIN 以後にアクティブでない ruleset で起こるすべての変更を元に戻すことによって、カーネルをクリーンアップします。 DIOCXROLLBACK は、静かに、チケットが無効である ruleset を無視します。
- DIOCSETHOSTID u_int32_t *hostid
- どのホストが状態テーブルエントリを作成したか識別するために pfsync(4) によって使用される、ホスト ID を設定します。
- DIOCOSFPFLUSH
- パッシブ OS 指紋テーブルをフラッシュします。
- DIOCOSFPADD struct pf_osfp_ioctl *io
-
struct pf_osfp_ioctl { struct pf_osfp_entry { SLIST_ENTRY(pf_osfp_entry) fp_entry; pf_osfp_t fp_os; char fp_class_nm[PF_OSFP_LEN]; char fp_version_nm[PF_OSFP_LEN]; char fp_subtype_nm[PF_OSFP_LEN]; } fp_os; pf_tcpopts_t fp_tcpopts; u_int16_t fp_wsize; u_int16_t fp_psize; u_int16_t fp_mss; u_int16_t fp_flags; u_int8_t fp_optcnt; u_int8_t fp_wscale; u_int8_t fp_ttl; int fp_getnum; };
テーブルにパッシブ OS 指紋を追加します。 fp_os.fp_os にパックされた指紋を、 fp_os.fp_class_nm にクラス (Linux、Windows など) の名前を、 fp_os.fp_version_nm にバージョン (NT、95、98) の名前を、そして fp_os.fp_subtype_nm にサブタイブまたはパッチレベルの名前を設定します。メンバ fp_mss, fp_wsize, fp_psize, fp_ttl, fp_optcnt と fp_wscale は、それぞれ TCP MSS、TCP ウィンドウサイズ、IP の長さ、 IP TTL、TCP オプションの数と TCP SYN パケットの TCP ウィンドウのスケーリング定数が設定されます。
fp_flags メンバは、 PF_OSFP_* を定義している< net/pfvar.h>インクルードファイルに従って満たされます。 fp_tcpopts メンバは、パックされた TCP オプションを含みます。各オプションは、パックされた値の PF_OSFP_TCPOPT_BITS ビットを使用します。オプションは、 PF_OSFP_TCPOPT_NOP, PF_OSFP_TCPOPT_SACK, PF_OSFP_TCPOPT_WSCALE, PF_OSFP_TCPOPT_MSS または PF_OSFP_TCPOPT_TS のいずれかを含みます。
fp_getnum メンバは、この ioctl では使用されません。
構造体の使用していない領域は、適格な操作 memset で 0 にしなければなりません。 memset(3) を使用して書き込まれる前にすべての構造体を 0 にして、カーネルに送ります。
- DIOCOSFPGET struct pf_osfp_ioctl *io
- カーネルの指紋リストからパッシブ OS 指紋番号 fp_getnum を取得します。構造体のメンバの残りは、書き込まれた状態で戻ります。 ioctl が EBUSY を返すまで、 fp_getnum 番号を増加することを繰り返すことによって、全体のリストを取得できます。
- DIOCGETSRCNODES struct pfioc_src_nodes *psn
-
struct pfioc_src_nodes { int psn_len; union { caddr_t psu_buf; struct pf_src_node *psu_src_nodes; } psn_u; #define psn_buf psn_u.psu_buf #define psn_src_nodes psn_u.psu_src_nodes };
sticky address と source 追跡によってソースノード保管リストを取得します。 ioctl は、0 に設定された psn_len で一度呼び出されなければなりません。 ioctl がエラーなしで返るなら、 psn_len は、テーブルに保持されているすべての pf_src_node 構造体を保持するために要求されるバッファのサイズに設定されます。次に、このサイズのバッファが割り付けられるべきで、このバッファへのポインタは、 psn_buf に置かれます。そして、実際のソースノードデータでこのバッファを満たすために再び ioctl を呼び出さなければなりません。その呼び出しの後に、 psn_len は、実際に使用されたバッファの長さに設定されます。
- DIOCCLRSRCNODES
- ソース追跡ノードのツリーをクリアします。
- DIOCIGETIFACES struct pfioc_iface *io
-
pf に知られているインタフェースとインタフェースドライバのリストを取得します。インタフェースを操作するすべての ioctl は、以下に記述された同じ構造を使用します:
struct pfioc_iface { char pfiio_name[IFNAMSIZ]; void *pfiio_buffer; int pfiio_esize; int pfiio_size; int pfiio_nzero; int pfiio_flags; };
空でなければ、 pfiio_name は、特定のインタフェースまたはドライバの検索を制限するために使用することができます。 pfiio_buffer[pfiio_size] は、データを返すためのユーザによって供給されたバッファです。登録時に、 pfiio_size は、バッファに適合することができる pfi_kif エントリの数を含みます。カーネルは、返さなければならないエントリの実際の数でこの値を置き換えます。 pfiio_esize は、
sizeof(struct pfi_kif)
に設定されるべきです。以下に記述された pfi_kif 構造体にデータは、返されます:
struct pfi_kif { RB_ENTRY(pfi_kif) pfik_tree; char pfik_name[IFNAMSIZ]; u_int64_t pfik_packets[2][2][2]; u_int64_t pfik_bytes[2][2][2]; u_int32_t pfik_tzero; int pfik_flags; struct pf_state_tree_lan_ext pfik_lan_ext; struct pf_state_tree_ext_gwy pfik_ext_gwy; TAILQ_ENTRY(pfi_kif) pfik_w_states; void *pfik_ah_cookie; struct ifnet *pfik_ifp; struct ifg_group *pfik_group; int pfik_states; int pfik_rules; TAILQ_HEAD(, pfi_dynaddr) pfik_dynaddrs; };
- DIOCSETIFFLAG struct pfioc_iface *io
-
pf の内部のインタフェース記述のユーザ設定可能なフラグ (以下に説明される) を設定します。フィルタリングプロセスは、
DIOCIGETIFACES に対するものと同じです。
#define PFI_IFLAG_SKIP 0x0100 /* インタフェースのスキップフィルタリング */
- DIOCCLRIFFLAG struct pfioc_iface *io
- 上記の DIOCSETIFFLAG として動作しますが、フラグをクリアします。
- DIOCKILLSRCNODES struct pfioc_iface *io
- 明示的にソースの追跡ノードを削除します。
関連ファイル
- /dev/pf
- パケットフィルタリングデバイス
使用例
次の例は、NAT 接続の内部のホスト/ポートを見つけためにどのように DIOCNATLOOK コマンドを使用するかを示しています。
#include <sys/types.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <sys/fcntl.h> #include <net/if.h> #include <netinet/in.h> #include <net/pfvar.h> #include <err.h> #include <stdio.h> #include <stdlib.h> u_int32_t read_address(const char *s) { int a, b, c, d; sscanf(s, "%i.%i.%i.%i", &a, &b, &c, &d); return htonl(a << 24 | b << 16 | c << 8 | d); } void print_address(u_int32_t a) { a = ntohl(a); printf("%d.%d.%d.%d", a >> 24 & 255, a >> 16 & 255, a >> 8 & 255, a & 255); } int main(int argc, char *argv[]) { struct pfioc_natlook nl; int dev; if (argc != 5) { printf("%s <gwy addr> <gwy port> <ext addr> <ext port>\n", argv[0]); return 1; } dev = open("/dev/pf", O_RDWR); if (dev == -1) err(1, "open(\"/dev/pf\") failed"); memset(&nl, 0, sizeof(struct pfioc_natlook)); nl.saddr.v4.s_addr = read_address(argv[1]); nl.sport = htons(atoi(argv[2])); nl.daddr.v4.s_addr = read_address(argv[3]); nl.dport = htons(atoi(argv[4])); nl.af = AF_INET; nl.proto = IPPROTO_TCP; nl.direction = PF_IN; if (ioctl(dev, DIOCNATLOOK, &nl)) err(1, "DIOCNATLOOK"); printf("internal host "); print_address(nl.rsaddr.v4.s_addr); printf(":%u\n", ntohs(nl.rsport)); return 0; }
歴史
pf パケットフィルタリングメカニズムは、 OpenBSD 3.0 ではじめて登場し、次に、 FreeBSD 5.2 で登場しました。この実装は、 OpenBSD 4.5 に由来します。それは、マルチスレッド化された FreeBSD カーネルで実行することができ、複数の CPU で性能を計ることができるように大幅に修正されました。
November 14, 2013 | FreeBSD |