LIBALIAS(3)

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

書式
<sys/types.h> <netinet/in.h> <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_addr と local_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 の設定により、望まれるサービスにのみ負荷共有を限定可能です。

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

まず、 link が PacketAliasRedirectPort() または 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] データの転送先の host と portnum を指定します。 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 返されてくると、この関数が、 残っているフラグメントのポインタを保存するために使用できます。

引数 ptr は malloc(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 のサポートを追加しました。

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

-split 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 動的リンクの生成
エイリアシングリンクに加え、 パケットエイリアシング機構を持つ 内部データテーブルに格納できるアドレス対応表があります。

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

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

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

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