スポンサーリンク

LIBALIAS(3) FreeBSD ライブラリ関数マニュアル LIBALIAS(3)

名称

libalias − マスカレードおよびネットワークアドレス変換用パケットエイリアシ ングライブラリ

書式

#include <sys/types.h>
#include <netinet/in.h>
#include <alias.h>

関数のプロトタイプは、このテキストの本文で紹介します。

解説

libalias ライブラリは、IP パケットのエイリアスおよびエイリアス解除用の関 数群であり、マスカレードおよびネットワークアドレス変換 (NAT) を目的として います。

導入

このライブラリは、IP のローカルネットワークアドレスの変換および変換処理サ ポート用にデザインされた関数です。ローカルネットワークの未登録の IP アド レスから発信するパケットは、アクセス可能な IP アドレスから来たかのように 見せかけることができます。外から入ってくるパケットに対しては、ローカル ネットワーク上の正しいマシンに送られるようエイリアス解除されます。

パケットエイリアシングエンジンには、ある程度の柔軟性が組み込まれていま す。もっとも簡単な操作では、ローカルネットワークアドレスとパケットエイリ アスホストとの間で多対 1 対応付けが行なわれます。これは仮装 IP として知ら れていることです。更に、ローカルアドレスとパブリックアドレスの間での 1 対 1 対応付けも実装することが可能で、静的 NAT として知られています。これらの 間には、異なるプライベートアドレスのグループをそれぞれ異なるパブリックア ドレスにリンクさせることができ、その中にははっきりした多対 1 対応もいくつ か見られます。更に、パブリックアドレスおよびポートは固定的にプライベート アドレスおよびポートにリダイレクトさせることができます。

パケットエイリアシングエンジンは、カーネル外部のユーザ空間で作用するよう に設計されており、そのためプライベートなカーネルデータ構造へのアクセスは 不要です。ただし、ソースコードはカーネル環境に組み込むことができます。

初期化と制御

2 つの特殊な関数、 PacketAliasInit() および PacketAliasSetAddress() は、 パケット操作が完了する前に呼ぶ必要があります。また、パケットエイリアシン グエンジンの操作モードに対し PacketAliasSetMode() 呼び出しによりカスタマ イズできます。

void PacketAliasInit(void)

この関数には引数がなく、また戻り値もありません。内部データ構造の初 期化に使用されます。以下に示すモードビットは PacketAliasInit() の呼 び出し後、必ずセットされます。これらのモードビットの意味について は、後述の PacketAliasSetMode() を参照してください。

PKT_ALIAS_SAME_PORTS
PKT_ALIAS_USE_SOCKETS
PKT_ALIAS_RESET_ON_ADDR_CHANGE

この関数はパケットエイリアスエンジンに対し、常時同一の初期状態を返 します。 PacketAliasSetAddress() 呼び出しは、これに続いて行ないま す。また、前述したデフォルトモードビットを変更する場合は PacketAliasSetMode() を呼び出します。

この関数呼び出しは、パケット操作の前にプログラム開始段階で実行する 必要があります。

void PacketAliasUninit(void)

この関数には引数も戻り値もなく、内部データ構造に設定された値をクリ アする場合に使用されます。

この関数はプログラムでエイリアスエンジンの使用を停止させる場合に呼 び出す必要があります。それにより、ファイアウォールに空いた隙間を塞 ぐことになります。以前との互換性や特別なセキュリティを備えるため に、本関数を PacketAliasInit() が atexit(3) チェーンに付加していま す。何度呼び出しても問題はありません。

void PacketAliasSetAddress(struct in_addr addr)

この関数は、ローカル領域のネットワーク外へパケットが発信する先の ソースアドレスをセットします。 PacketAliasRedirectAddr() により生成 された静的アドレス対応により上書きされない限り、発信パケットはすべ てこのアドレスに再対応付けされます。

PKT_ALIAS_RESET_ON_ADDR_CHANGE モードビット (デフォルト操作モード) が設定されている場合、内部的なエイリアスリンクテーブルは、エイリア スアドレスが変更されるたび、リセットされます。これは一連のダイアル アップ操作の中で IP アドレス状態に関わらず、 ppp(8) のようなインタ フェースに便利です。

PKT_ALIAS_RESET_ON_ADDR_CHANGE モードビットが 0 にセットされていた 場合、この関数は、パケット間のエイリアスの動的変更に使用できます ( オーバヘッドの少ない呼び出しです)。

パケット操作の前にこの関数を呼び出す必要があります。

unsigned int PacketAliasSetMode(unsigned int flags, unsigned int mask)

この関数は、 flags 値に従ってモードビットの設定やクリアを行ないま す。 mask により示されたビットだけが対象となります。以下に示すモー ドビットは ⟨alias.h⟩ で定義されています。

             PKT_ALIAS_LOG

/var/log/alias.log ファイルへのロギングを可能にします。ログ ファイルには、エイリアス・リンクの作成、削除のたびに icmp、tcp、udp へのリンク回数が記録されます。ログファイルが tail(1) により継続的に見ることができれば、主としてデバッグ 用として有効です。

PKT_ALIAS_DENY_INCOMING
このモードビットが設定されていると、 TCP 接続や UDP トラン ザクションに関連する外部から着信するあらゆるパケットは、呼 び出しプログラムで無視 ( PacketAliasIn() であれば PKT_ALIAS_IGNORED を返す) するための印が付けられます。パ ケットのエイリアスホストやローカルネットワークから発生した 接続やトランザクションに対するレスポンスに対する影響はあり ません。このモードビットは片方向のファイアウォールを実装す る時に有効です。

PKT_ALIAS_SAME_PORTS
このモードビットが設定されていると、パケットエイリアスエン ジンは実際のローカルポート番号をそのままエイリアスポート番 号にしようとします。このことは (proto, alias addr, alias port, remote addr, remote port) の 5 つのパラメータのペアが 一意であれば可能です。競合が起きる場合は、このビットが設定 されていてもエイリアスポート番号には別の番号が選択されま す。

PKT_ALIAS_USE_SOCKETS
このビットは、エイリアスホストがパケット移送時のようにネッ トワーク上にトラフィックを発生させる場合必ず設定します。パ ケットエイリアスホストが不明なホストアドレスや不明のポート 番号 (例えば、FTP データ接続時) からの接続を待っている時 は、このモードビットは、ポートの競合が起きないようにプレー スホルダとしてソケットの割り当てを定義します。接続が確立さ れると、通常は 1 分ほどでソケットは閉じられます。

PKT_ALIAS_UNREGISTERED_ONLY
このビットが設定されていると、未登録のアドレス空間から生じ た以外のローカルネットワーク上のトラフィックが無視されま す。標準クラス A, B および C の未登録アドレスは次の通りで す。

10.0.0.0 -> 10.255.255.255 (Class A subnet)
172.16.0.0 -> 172.31.255.255 (Class B subnets)
192.168.0.0 -> 192.168.255.255 (Class C subnets)
このオプションは、パケットエイリアスホストが別々のインタ フェースに登録済みおよび未登録サブネットがある場合に有効で す。登録済みサブネットは完全に外部と接続しているので、パ ケットエイリアスエンジンによりパケットを送り出す必要はあり ません。

             PKT_ALIAS_RESET_ON_ADDR_CHANGE

このモードビットが設定されており、 PacketAliasSetAddress() がエイリアスアドレス変更のために呼ばれるケースでは、パケッ トエイリアスエンジンの内部リンクテーブル内容がクリアされま す。この操作モードは、ダイアルアップ間でのインタフェースア ドレスを変更したり、変更せずにおく ppp(8) リンクの場合に有 効です。このモードビットが設定されていない場合、リンクテー ブルはアドレスが変更されてもリセットされません。

PKT_ALIAS_PUNCH_FW
このオプションにより、 libalias は、 FTP/IRC DCC 接続に対す る ipfirewall(4) ベースのファイアウォールの ‘隙間’ を作るこ とになります。開けられた隙間は IP アドレスやポートと結び付 いており、別の接続に使用することはできません。隙間はそれを 使用している接続が消滅すれば除去されます。 libalias を使用 しているプログラムを強制的に終了させる (例えば kill -9) 仕 組みは、フラグの状態により、隙間に割り当てられた全ファイア ウォール領域をクリアすることで実現されています。このことは また PacketAliasSetFWBase() に対する初期呼び出しでも起こり ます。この呼び出しはフラグの設定の前に行なう必要がありま す。

PKT_ALIAS_REVERSE
本オプションは、ライブラリが内向きパケットと外向きパケット を扱う方法を反転させます。これにより、外部インタフェースの 代りに内部インタフェースを通過するパケットを食わせることが できます。

PKT_ALIAS_PROXY_ONLY
本オプションは、ライブラリが透過プロキシルールのみに従うよ う指示します。通常のパケットエイリアスは実行されません。詳 細は後述の PacketAliasProxyRule() を参照してください。

void PacketAliasSetFWBase(unsigned int base, unsigned int num)

ファイアウォールに ( PKT_ALIAS_PUNCH_FW フラグにより) ファイア ウォールの隙間に対する領域を割り当てます。領域は全初期化ルールに従 いクリアされます。

パケット操作

パケット処理関数は、着信 (リモート -> ローカル) および発信 (ローカル -> リモート) パケットの修正に使用されます。ネットワークインタフェース経由で のパケットの送受信は、呼び出し側プログラムが行ないます。

PacketAliasInit() および PacketAliasSetAddress() とともに、 PacketAliasIn() と PacketAliasOut() の 2 つのパケット処理ルーチンが基本的 な、見かけの IP 実装に必要な最小機能として用意されています。

int PacketAliasIn(char *buffer, int maxpacketsize)

リモートのマシンからローカルネットワークへの着信パケットはこの関数 によりエイリアス解除されます。 IP パケットは引数 buffer で指定され ます。 maxpacketsize はパケットを含むデータ構造の長さを示しており、 実際のパケット長より大きくとる必要があります。

戻りコード :

             PKT_ALIAS_OK

パケットエイリアシング処理は成功しました。

PKT_ALIAS_IGNORED
パケットは無視され、エイリアスは解除されませんでした。これ は、プロトコルが認識されないとき、 ICMP のメッセージタイプ は処理されていないか、あるいは新たな接続についての入力パ ケットが無視されたときに発生します ( PacketAliasSetMode() が PKT_ALIAS_DENY_INCOMING を設定した場合)。

PKT_ALIAS_UNRESOLVED_FRAGMENT
ヘッダフラグメントが未送信のためフラグメントが解消されない ときにこのコードが返されてきます。この場合、フラグメントは ヘッダフラグメントが見つかるまで PacketAliasSaveFragment() により保存しておく必要があります。

PKT_ALIAS_FOUND_HEADER_FRAGMENT
パケットエイリアシング処理は成功し、ヘッダフラグメントも見 つかりました。これは解消されていないフラグメントを、 PacketAliasGetFragment() により探し、 PacketAliasFragmentIn() を使ってエイリアス解除する時のシグ ナルとなります。

PKT_ALIAS_ERROR
パケットエイリアシングエンジン内で発生した内部エラー。

int PacketAliasOut(char *buffer, int maxpacketsize)

ローカルネットワークからリモートのマシンへ発信するパケットは、この 関数によりエイリアスされます。 IP パケットは引数 buffer で指定さ れ、 maxpacketsize はパケットが取りうる最大長を示します。 IP 表現形 式プロトコルは、アドレスと、修正され、またパケット長の変更にからむ 一連のデータ内のポート情報を設定します。プロトコルのよく知られた事 例としては、 FTP と IRC DDC があります。

戻りコード :

             PKT_ALIAS_OK

パケットエイリアシング処理は成功しました。

PKT_ALIAS_IGNORED
パケットは無視され、エイリアス解除はされませんでした。これ はプロトコルが認識されないときか、あるいは ICMP メッセージ タイプが処理されないときに発生します。

PKT_ALIAS_ERROR
パケットエイリアシング内で発生した内部エラー。

ポートとアドレスのリダイレクション

このセクションで解説している関数は、ローカルネットワーク上のマシンにおい て、外部ネットワークから新たな着信に対するアクセスをある程度可能にしま す。個々のポートは、再対応付けや固定的なネットワークアドレスの変換を定義 することができます。

struct alias_link *

                           PacketAliasRedirectPort(struct in_addr local_addr,u_short local_port, struct in_addr remote_addr, u_short remote_port,struct in_addr alias_addr, u_short alias_port, u_char proto)

この関数は、所定のリモートアドレスやポートからエイリアスアドレスや ポートへのトラフィックを、指定されたローカルアドレスやポートへのリ ダイレクトを定義します。パラメータ proto は IPPROTO_TCP か IPPROTO_UDP のどちらかに該当し、 ⟨netinet/in.h⟩ で定義されます。

local_addr あるいは alias_addr が 0 ならば、パケットエイリアシング アドレスは PacketAliasSetAddress() で設定されたものを使用します。 PacketAliasRedirectPort() が PacketAliasSetAddress() 呼び出し語にア ドレス変更のために呼び出されても、 0 リファレンスがこの変更を記録し ます。

負荷共有用にリンクが更に設定されると、 local_addrlocal_port は 無視され、サーバプールから動的に選択されます。これは PacketAliasAddServer() で後述されています。

remote_addr が 0 の場合、パケットをリモートアドレスからリダイレクト します。同様に、 remote_port が 0 の場合、リモートのポート番号から 発生したパケットをリダイレクトします。通常、リモートポート定義は 0 ですが、ファイアウォールに対しては 0 でないリモートアドレスが有効な 場合があります。 PacketAliasRedirectPort() 呼び出しにより、アドレス とポート定義が重複した場合、最新の呼び出しが優先されます。

この関数は次いで PacketAliasRedirectDelete() で使用するポインタを返 します。 NULL が返された場合、関数呼び出しは正常に終了していませ ん。

あらゆるポートアドレスは、ネットワークアドレスのバイトオーダ表記に 従っています。これらのパラメータは htons(3) を使用して、内部的な数 値形式からネットワークバイトオーダ表記に変換する必要があります。ア ドレスもまた同様にネットワークバイトオーダ形式であり、 struct in_addr データ型で暗黙に定義されます。

struct alias_link *

                           PacketAliasRedirectAddr(struct in_addr local_addr,struct in_addr alias_addr)

この関数は、 alias_addr への全着信トラフィックを local_addr にリダ イレクトします。同様に、 local_addr からの全発信トラフィックは alias_addr にエイリアスされます。

local_addr または alias_addr が 0 の場合、 PacketAliasSetAddress() により設定されたパケットエイリアシングアドレスが使用されます。 PacketAliasSetAddress() が PacketAliasRedirectAddr() の呼び出し後に アドレス変更のために呼び出されても、 0 リファレンスがこの変更を記録 します。

負荷共有用にリンクが更に設定されると、 local_addr は無視され、サー バプールから動的に選択されます。これは PacketAliasAddServer() で後 述されています。

PacketAliasRedirectAddr() に対する一連の呼び出しが同一のエイリアシ ングアドレスを使用している場合、このエイリアシングアドレスへの新た な全着信トラフィックは、最後の関数呼び出しで作られたローカルアドレ スへリダイレクトされます。いくつかの関数呼び出しで指定されたローカ ルマシンからの新たな全トラフィックは、同一のアドレスにリダイレクト されます。

                 PacketAliasRedirectAddr(inet_aton("192.168.0.2"),
                                         inet_aton("141.221.254.101"));
                 PacketAliasRedirectAddr(inet_aton("192.168.0.3"),
                                         inet_aton("141.221.254.101"));
                 PacketAliasRedirectAddr(inet_aton("192.168.0.4"),
                                         inet_aton("141.221.254.101"));

192.168.0.2, 192.168.0.3 および 192.168.0.4 から、 telnet(1)ftp(1) などでの発信接続は 141.221.254.101 からでてきたかのようにみ えます。 141.221.254.101 への着信接続は 192.168.0.4 にリダイレクト されます。

PacketAliasRedirectPort() に対する呼び出しより PacketAliasRedirectAddr() で指定されたアドレス対応が必ず優先されま す。

この関数は、 PacketAliasRedirectDelete() が使用するポインタを返しま す。 NULL が返される場合、関数呼び出しは正常に終了していません。

int

           PacketAliasAddServer(struct alias_link *link, struct in_addr addr,u_short port)

本関数は、 link を、IP Network Address Translation (RFC 2391, LSNAT) を使用した負荷共有用に設定します。 LSNAT は次のように動作し ます。クライアントが、サーバ仮想アドレスを使用してサーバへアクセス を試みます。 LSNAT ルータが、サーバプール中の 1 個のホストに対し、 要求を透過的にリダイレクトします。ホスト選択には、実時間負荷共有ア ルゴリズムを使用します。複数のセッションが同一のクライアントから開 始されるかもしれません。各セッションは、その時々のサーバプールホス ト間の負荷バランスによって、異なるホストに向けられる可能性がありま す。数個の固有のサービスに対して負荷共有が望まれる場合、 LSNAT の設 定により、望まれるサービスにのみ負荷共有を限定可能です。

現在のところ、最も単純な選択アルゴリズムのみが実装されています。こ の方法は、ラウンドロビンによる選択のみであり、ホストの負荷を考慮し ないものです。

まず、 linkPacketAliasRedirectPort() または PacketAliasRedirectAddr() により作成されます。次に PacketAliasAddServer() が複数回呼ばれ、 link のサーバプールにエント リが追加されます。

PacketAliasRedirectAddr() で作成されたリンクに対し、 port 引数は無 視されいかなる値、例えば htons(~0) を持ちえます。

本関数は、成功時には 0 を返し、失敗時には -1 を返します。

void PacketAliasRedirectDelete(struct alias_link *ptr)

この関数は、 PacketAliasRedirectPort() あるいは PacketAliasRedirectAddr() が設定した特定の静的リダイレクトルールを 削除します。パラメータ ptr は、いずれかのリダイレクション関数から返 されてくるポインタです。正しくないポインタが PacketAliasRedirectDelete() に渡されると、プログラムはクラッシュす るか、予期せぬ動作結果となります。そのためにこの関数の使用に際して は注意が必要です。

int PacketAliasProxyRule(const char *cmd)

渡された cmd 文字列は、1 個以上の、語の組からなります。各組の最初の 語はトークンであり、次の語はそのトークンに適用される値です。トーク ンと引数の型は次の通りです:

             type encode_ip_hdr | encode_tcp_stream | no_encode

透過プロキシのサポートのために、新規終点サーバに元のアドレ スとポートの情報をなんらかの方法で渡す必要があります。 encode_ip_hdr が指定された場合、追加の IP オプションとして 元のアドレスとポートが渡されます。 encode_tcp_stream が指定 された場合、TCP ストリーム中の最初のデータ片の中に ‘‘DEST IP port’’ という書式で、元のアドレスとポートが渡されます。

port portnum
終点ポートが portnum のパケットのみがプロキシの対象となりま す。

server host
[:portnum]
データの転送先の hostportnum を指定します。 host は、DNS ホスト名ではなく IP アドレスであることが必要です。 portnum が指定されないと、終点ポート番号は変更されません。

server の指定は、 delete コマンドが使用されない限り、必須で す。

rule index
通常、各 PacketAliasProxyRule() 呼び出しは、ルールの線型リ ストの先頭に次のルールを挿入します。 index が指定された場 合、低いインデックスの全ルールがチェックされた後に、新規 ルールがチェックされます。ルールを指定しない PacketAliasProxyRule() 呼び出しは、ルールにルール 0 を割り 当てます。

delete index
本トークンと引数は、他のトークンと組み合わせて使用してはな りません。本トークンを使用すると、指定した index の既存の ルールが削除されます。

proto tcp | udp
指定すると、指定したプロトコルタイプのパケットのみがマッチ します。

src IP
[/bits]
指定すると、指定した IP に始点アドレスがマッチするパケット のみがマッチします。 bits も指定すると、 IP アドレスの最初 の bits ビットのみがネットワーク指定として使用され、その ネットワークからの全 IP アドレスがマッチします。

dst IP
[/bits]
指定すると、指定した IP に終点アドレスがマッチするパケット のみがマッチします。 bits も指定すると、 IP アドレスの最初 の bits ビットのみがネットワーク指定として使用され、その ネットワークからの全 IP アドレスがマッチします。

本関数は、通常、ある主のインターネットアクセスを禁止されている内部 マシンに対し、外向き接続をリダイレクトするか、またはある種の外部マ シンへのアクセスを制限します。

struct alias_link *

                           PacketAliasRedirectProto(struct in_addr local_addr,struct in_addr remote_addr, struct in_addr alias_addr, u_char proto)

本関数は、指定したリモートアドレスからエイリアスアドレスへのプロト コル番号 proto の全パケットが、指定したローカルアドレスへリダイレク トすることを指定します。

local_addr または alias_addr が 0 の場合、で確立したパケットエイリ アスアドレスが使用されることを指定します。 PacketAliasSetAddress() が PacketAliasRedirectProto() の呼び出し後にアドレス変更のために呼 び出されても、 0 リファレンスがこの変更を記録します。

remote_addr が 0 の場合、全リモートホストからのパケットをリダイレク トすることを指定します。非 0 のリモートアドレスは、ファイアウォール 用途に有用な場合があります。

2 個の PacketAliasRedirectProto() 呼び出しが、アドレス指定において 重なる場合、最新の呼び出しが優先します。

本関数は、後に PacketAliasRedirectDelete() に使用可能なポインタを返 します。 NULL が返される場合、関数呼び出しは正常に終了していませ ん。

フラグメント操作

このセクションの関数は着信フラグメント操作で使用されます。

発信フラグメントは、 PacketAliasRedirectAddr() で設定した適用可能な対応付 によるアドレス変更により、または PacketAliasSetAddress() で設定したエイリ アシングアドレスの省略時値により、 PacketAlaisOut() 内で処理されます。

着信フラグメントは 2 通りの方法で処理されます。フラグメント化された IP パ ケットのヘッダが既に分かっている場合は、一連のフラグメントはヘッダフラッ グメントと同じ方式で再対応付けされます。フラグメントはヘッダが到着する前 に保存され、ヘッダフラグメントが消滅した段階で取り出されます。

int PacketAliasSaveFragment(char *ptr)

PacketAliasIn() から PKT_ALIAS_UNRESOLVED_FRAGMENT 返されてくると、 この関数が、残っているフラグメントのポインタを保存するために使用で きます。

引数 ptrmalloc(3) で割り当てられたメモリブロックを指すことが暗 黙のうちに仮定されています。フラグメントが解決されない場合、パケッ トエイリアシングエンジンはタイムアウト時間経過後、自動的にメモリを 解放します [実質的には、この関数は、メモリ解放のコールバック関数が 引数として渡されるように修正しておく必要があります]。

この関数は、正常実行の場合 PKT_ALIAS_OK を返し、エラーの場合 PKT_ALIAS_ERROR を返します。

char * PacketAliasGetFragment(char *buffer)

この関数は、 PacketAliasSaveFragment() で保管されたフラグメントポイ ンタの再取り出しができます。 buffer で示す IP ヘッダフラグメント は、 PacketAliasIn() がを返したときに指定されるヘッダフラグメントで す。フラグメントのポインタが再取り出しされると、呼び出しプログラム によりフラグメントに動的に割り当てられていたメモリが解放されます。

フラグメントがなくなるで PacketAliasGetFragment() を続けて呼ぶこと ができます。処理するフラグメントがなくなると NULL が返されてきま す。

void PacketAliasFragmentIn(char *header, char *fragment)

PacketAliasGetFragment() によりフラグメントの再取得を行なうとき、 PacketAliasFragmentIn() 呼び出しを実行してフラグメントのエイリアス を解除できます。引数 header は、テンプレートとして使われているヘッ ダフラグメントのポインタです。引数 fragment はエイリアス解除するパ ケットのポインタです。

その他の関数

void PacketAliasSetTarget(struct in_addr addr)

既存のエイリアスリンクと関連のない外からの着信パケットがホストマシ ンに到着すると、それは PacketAliasSetTarget() 呼び出しにより指定さ れるアドレスへ送られます。

この関数が INADDR_NONE アドレスを引数として呼ばれた場合、外からのあ らゆる新規着信パケットは PacketAliasSetAddress() で設定されるアドレ スへ行きます。

この関数が INADDR_ANY アドレスを引数として呼ばれた場合、外からのあ らゆる新規着信パケットはパケット中で指定されるアドレスへ行きます。 外部のマシンが内部のマシンへ直接ルーティング可能な場合、外部のマシ ンが直接内部のマシンと話すことを可能とします。

int PacketAliasCheckNewLink(void)

新規のエイリアシングリンクが生成されると、この関数は 0 以外の値を返 します。外からの着信トラフィックが順次異なるサーバへ送られるという 状況下で、この関数を PacketAliasSetTarget() 呼び出しをデフォルトの 目的アドレスを変更のため実行するときのトリガにできます。

u_short PacketAliasInternetChecksum(u_short *buffer, int nbytes)

これはよそでは使うことがありませんが、便利なユーティリティ関数で す。インターネットチェックサムを計算します。チェックサムは、IP およ びプロトコル (TCP, UDP, ICMP) 固有のヘッダのどちらでも使われていま す。

引数 buffer はチェックサムを取るデータブロックを指しています。また nbytes はバイト数を与えます。 16 ビットのチェックサムフィールドは チェックサム計算の前に 0 クリアされます。

チェックサムはチェックサム自身を含めたデータブロックの操作により検 証することができます。チェックサムが正しければ、 PacketAliasInternetChecksum() は 0 を返します。

int PacketUnaliasOut(char *buffer, int maxpacketsize)

エイリアス処理済の外向きパケットは、プライベートアドレス/ポートの情 報を本関数によって復活されています。 buffer で指される IP パケット と maxpacketsize が、エラーチェックのために提供されています。本関数 は、エイリアス処理済パケットの元の IP ヘッダが必要となる更なる処理 (例えばロギング) に使用可能です。

バグ

PPTP エイリアスは、複数の内部クライアントが同一の外部サーバに同時に接続す ると動作しません。なぜなら、PPTP は 2 つの IP アドレス間に単一の TCP 制御 接続を必要とするからです。

作者

Charles Mott ⟨cm@linktel.net⟩, versions 1.0 - 1.8, 2.0 - 2.4。
Eivind Eklund ⟨eivind@FreeBSD.org⟩, versions 1.8b, 1.9 および 2.5。アーキ テクチャにおける数々の改善による貢献のほかに、 IRC DCC に関するサポートを 行ないました。ならびに FTP/IRC DCC のファイアウォールのバイパスです。
Erik Salander ⟨erik@whistle.com⟩ が PPTP と RTSP のサポートを追加しまし た。
Junichi Satoh ⟨junichi@junichi.org⟩ が RTSP/PNA のサポートを追加しまし た。

謝辞

以下、概略時代順に示すのは、有益なコメントやデバッグの手助けを提供してく れた人々の名前です。

Gary Roberts
Tom Torrance
Reto Burkhalter
Martin Renters
Brian Somers
Paul Traina
Ari Suutari
Dave Remien
J. Fortes
Andrzej Bialecki
Gordon Burditt

概念的な背景

この付録は、ソースコードの修正を検討している人や、パケットエイリアシング 関数を使用してやや難解なアプリケーションを作成する人を対象としています。

ここにはパケットエイリアシングエンジンの概念的なフレームワークが記述され ています。議論の中心は、ローカルマシンとエイリアスされた識別子およびリ モートマシン間の指定されたパケットトランザクションの関係を定義している " エイリアシング リンク" に考え方についてです。こうしたリンクがどのように発 生してまた消滅するかについて検討されています。

エイリアシングリンク

エイリアシング リンクは、 7 つの要素で記述できるという考え方があります:

      (ローカルアドレス、 ローカルポート番号、
      エイリアスアドレス、エイリアスポート番号、
      リモートアドレス、リモートポート、プロトコル)

外へ発信するパケットは、ローカルアドレスとローカルポート番号が、エイリア スアドレスとエイリアスポート番号で置き換えられます。外から着信するパケッ トは、逆のプロセスで処理されます。パケットエイリアシングエンジンは、エイ リアシングリンクの内部テーブルに対してパケットを対応させ、指定 IP パケッ トの修飾方法を決定しようとします。 IP ヘッダおよびプロトコルに依存する ヘッダのどちらも必要に応じて修正されます。エイリアシングリンクは、ネット ワークのトラフィックにより、必要に応じて生成、消滅が行なわれます。

プロトコルは、ある状況では TCP か UDP であり、または ICMP であってかまい ません (ICMP のある種のパケットタイプには、個々のパケットの処理方式を決め るポート番号と同様な働きをする、一連の id 番号にエイリアスすることができ るものがあります)。

それぞれのエイリアスリンクは次の 5 つの数値の組合せを持っていなければなり ません。すなわち、エイリアスアドレス / ポート、リモートアドレス / ポー ト、およびプロトコルです。このことによりローカルネットワーク上のいくつか のマシンは同じエイリアス IP アドレスを共有することが可能となります。競合 が起こるケースでは、エイリアシングポートが、一意性が保てるよう選択されま す。

静的および動的リンク

エイリアシングリンクには静的および動的なものがあります。静的リンクは無期 限に存続し、IP パケットの変換に関しては固定された規則を保持しています。動 的リンクは個別の TCP 接続や UDP トランザクションのエコーシーケンスに対し て生成されます。 TCP の場合は、関連するエイリアシングリンクを何時削除する べきかを知るために、接続を監視できます。 UDP トランザクション (および ICMP エコーとタイムスタンプ要求) は単純なタイムアウト規則で動いています。 一定の時間、動的リンクを張るアクティビティが無いときは、自動的に削除され ます。タイムアウト規則は適切なオープン / クローズを行なわない TCP 接続に も適用されます。

エイリアシングリンクの部分定義

エイリアシングリンクは部分的な定義が可能です。これはリモートアドレスおよ び (または) リモートポートが不明である場合に行ないます。この場合、不完全 な定義のパケットが見つかると、完全仕様の動的リンクが生成されます。元々の 部分定義のリンクが動的なものである場合、完全仕様のリンクが生成された後そ れは削除され、そうでない場合無期限に残ることになります。

たとえば、部分定義リンクは次の通りです。

      (192.168.0.4, 23, 204.228.203.215, 8066, 0, 0, tcp)

0 の値はリモートアドレスおよびポートの未定義部分を表しています。リンクが 静的なものであれば、外から着信してくる全トラフィックをアドレス 204.228.203.215 のポート 8066 から、ローカルネットワーク上の 192.168.0.4 のアドレスを持つマシンのポート 23 (telnet) へリダイレクトすることになりま す。

A.4 動的リンクの生成

エイリアシングリンクに加え、パケットエイリアシング機構を持つ内部データ テーブルに格納できるアドレス対応表があります。

      (ローカルアドレス、エイリアスアドレス)

アドレス対応表は動的リンク生成時に必要とされます。

ローカルネットワークから外へ発信するあらゆるパケットは、既存の完全定義さ れたリンクと一致していなければ、動的リンクを自動的に生成します。これは発 信するパケットに関し、アドレス対応があれば使用されるエイリアスアドレスを 決定します。対応が無ければ、デフォルトアドレスが通常エイリアシングホスト のアドレスですが、使用されます。必要であれば、デフォルトアドレスは個々の パケットが到着するたびに変更できます。

エイリアシングポート番号は、新たな動的リンクが既存のリンクと競合しないよ う決められます。デフォルト操作モードでは、パケットエイリアシングエンジン はローカルポート番号と同じ番号をエイリアシングポートとして設定しようとし ます。その結果競合すれば、ポート番号は一意なエイリアシングリンクとなるま で無作為に選択が行なわれます。予備の操作モードでは、エイリアシングポート の最初の選択は無作為に、またローカルポート番号と無関係に行なわれます。

FreeBSD 10.0 April 13, 2000 FreeBSD 10.0

スポンサーリンク