ONC+ 開発ガイド

付録 E portmap ユーティリティ

Solaris 環境の旧バージョンのユーティリティである portmap ユーティリティの代わりに rpcbind ユーティリティを使用します。この章は、portmap ユーティリティの話題からポートとネットワークアドレスの解決方法の変遷を理解していただくためのものです。

Solaris の RPC ベースのサービスでは、システム登録サービスとしては portmap を使用していました。portmap は、ポート (論理通信チャネル) と、そこに登録されたサービスとの対応テーブルを管理します。portmap は、サーバーがサポートしている RPC プログラムに対する TCP/IP または UDP/IP のポート番号をクライアントが調べるための標準的な方法を提供します。

システム登録の概要

クライアントプログラムがネットワーク上の分散サービスを利用するには、サーバープログラムのネットワークアドレスを知る必要があります。ネットワークトランスポート (プロトコル) サービスはこのような機能を提供しません。ネットワーク上のプロセス間メッセージを伝送するだけです。つまり、メッセージはトランスポート固有のネットワークアドレスに送信されます。ネットワークアドレスとは論理通信チャネルのことで、プロセスは特定のネットワークアドレスを監視することにより、ネットワークからのメッセージを受信します。

プロセスがどのようにネットワークアドレスを監視するかは、オペレーティングシステムごとに異なりますが、どのオペレーティングシステムでも、メッセージの到着に同期してプロセスがアクティビティを起こすような機能があります。メッセージは受信側プロセスに対してネットワーク上に送信されるのではなく、特定のネットワークアドレスに対して送信され、そこを監視していた受信側プロセスがそのメッセージを取り出します。ネットワークアドレスが重要なのは、受信側のオペレーティングシステムの方針に依存しない方法で、メッセージの宛先を指定できるからです。TI-RPC はトランスポート独立ですので、ネットワークアドレスの実際の構造については関知しません。その代わりに、TI-RPC は汎用アドレスを使用します。汎用アドレスは NULL で終わる文字列で指定します。汎用アドレスは、各トランスポートプロバイダに固有のルーチンにより、ローカルトランスポートアドレスに変換されます。

rpcbind プロトコルでは、サーバーがサポートする任意の遠隔プログラムのネットワークアドレスをクライアントから調べるための標準の方法を提供します。rpcbind はどのトランスポートにも実現できるので、全クライアント、全サーバー、全ネットワークに適用できるような 1 つの問題解決方法を提供します。

portmap プロトコル

portmap プログラムは、RPC プログラムとバージョン番号を、トランスポート固有のポート番号にマップします。portmap プログラムは、遠隔プログラムの動的結合を可能にします。

図 E-1 典型的な Portmap シーケンス (TCP/IP トランスポートのみ)

Graphic

図 E-1 は、次の処理を示しています。

  1. サーバーが portmap に登録する

  2. クライアントは、サーバーのポートを portmap から得る

  3. クライアントが、サーバーを呼び出す

予約ポート番号は少ないのに対して、遠隔プログラム数は非常に多くなる可能性があります。したがって、よく知られたポートでポートマッパを実行しておけば、その他の遠隔プログラムのポート番号はポートマッパに問い合わせることによって得られます。図 E-1 では a111bc はポート番号を表しています。111 はポートマッパに割り当てられたポート番号です。

ポートマッパはブロードキャスト RPC にも役立ちます。特定の RPC プログラムは、マシンが異なると通常別のポート番号に結合されるので、直接これらすべてのプログラムにブロードキャストする方法はありません。これに対して、ポートマッパは固定のポート番号を持っています。そこで、特定のプログラムにブロードキャストするには、クライアントはブロードキャストアドレスにあるポートマッパにメッセージを送信します。各ポートマッパは、ブロードキャストを受けて、クライアントが指定しているローカルサービスを呼び出します。portmap はローカルサービスからの応答を取り出すと、それをクライアントに送信します。portmap プロトコル仕様は、例 E-1 に示します。


例 E-1 portmap プロトコル仕様 (RPC 言語で記述)

const PMAP_PORT = 111;       /* ポートマッパのポート番号 */
 /*
  * (プログラム、バージョン、プロトコル) とポート番号のマッピング
  */
 struct pmap {
 	rpcprog_t prog;
 	rpcvers_t vers;
 	rpcprot_t prot;
 	rpcport_t port;
 };
 /*
  * prot フィールドに指定できる値
  */
 const IPPROTO_TCP = 6; /* TCP/IP のプロトコル番号 */
 const IPPROTO_UDP = 17; /* UDP/IP のプロトコル番号 */
 /*
  * マッピングリスト
  */
 struct pmaplist {
 	pmap map;
 	pmaplist *next;
 };
 /*
  * callit への引数
  */
 struct call_args {
  	rpcprog_t prog;
 rpcvers_t vers;
 rpcproc_t proc;
 	opaque args<>;
 };
 /*
 * callit からの戻り値
 */
 struct call_result {
 	rpcport_t port;
 	opaque res<>;
 };
 /*
 * ポートマッパの手続き
 */
 program PMAP_PROG {
 	version PMAP_VERS {
 		void
 		PMAPPROC_NULL(void) = 0;
 		bool
 		PMAPPROC_SET(pmap) = 1;
 		bool
 		PMAPPROC_UNSET(pmap) = 2;
 		unsigned int
 		PMAPPROC_GETPORT(pmap) = 3;
 		pmaplist
 		PMAPPROC_DUMP(void) = 4;
 		call_result
  	PMAPPROC_CALLIT(call_args) = 5;
 	} = 2;
 } = 100000;

portmap の操作

portmap が現在サポートしているプロトコルは 2 つ (TCP/IPUDP/IP) です。portmap にアクセスするには、どちらかのプロトコルで割り当てられたポート番号 111 (SUNRPC (5)) と通信します。ポートマッパの各手続きを次に説明します。

PMAPPROC_NULL

この手続きは何もしない手続きです。習慣的に、どのプロトコルでも手続き 0 は引数も戻り値もない手続きにします。

PMAPPROC_SET

プログラムは、マシン上で最初に使用可能になるとローカルのポートマッププログラムに自分自身を登録します。プログラムは、プログラム番号 prog、バージョン番号 vers、トランスポートプロトコル番号 prot、サービス要求を受信するポート port を引き渡します。この手続きは、指定したポートに既にマッピングが存在していて結合されていれば、マッピングの設定を拒絶します。マッピングが存在していてポートが未結合の場合は、ポートを登録解除し、要求されたマッピングを設定します。マッピングが正しく設定されれば TRUE、設定されなければ FALSE を返します。rpc_soc(3NSL) のマニュアルページの pmap_set() 関数も参照してください。

PMAPPROC_UNSET

プログラムが使用不可能になれば、同一マシン上のポートマッパプログラムで自身の登録を解除しなければなりません。そのとき渡す引数と戻り値は、PMAPPROC_SET と同じです。引数のうち、プロトコルとポート番号のフィールドは無視されます。rpc_soc(3NSL) のマニュアルページの pmap_unset() 関数も参照してください。

PMAPPROC_GETPORT

プログラム番号 prog、バージョン番号 vers、トランスポートプロトコル番号 prot、をこの手続きに引き渡すと、そのプログラムが呼び出し要求を待っているポート番号が返されます。ポート番号 0 が返された場合は、そのプログラムが登録されていないことを示します。引数の port フィールドは無視されます。rpc_soc(3NSL) のマニュアルページの pmap_getport() 関数も参照してください。

PMAPPROC_DUMP

この手続きは、ポートマッパのデータベースの全エントリをリストします。この手続きへの引数はなく、返されるのは、プログラム、バージョン、プロトコル、ポート番号のリストです。rpc_soc(3NSL) のマニュアルページの pmap_getmaps() 関数も参照してください。

PMAPPROC_CALLIT

この手続きを使用すると、呼び出し側がポートマッパと同一マシン上の遠隔手続きのポート番号を知らなくても、その遠隔手続きを呼び出すことができます。この手続きは、よく知られているポートマッパのポートを通して、任意の遠隔プログラムへのブロードキャストを可能にするためのものです。引数の progversprocargs はそれぞれプログラム番号、バージョン番号、手続き番号、遠隔手続きへの引数です。rpc_soc(3NSL) のマニュアルページの pmap_rmtcall() 関数も参照してください。

この手続きは正常終了したときだけ応答を返し、異常終了したときは応答を返しません。また、遠隔プログラムのポート番号と、遠隔手続きからの戻り値を返します。

ポートマッパが遠隔プログラムとの通信に使用できるのは UDP/IP だけです。

参考文献

  1. 『Implementing Remote Procedure Calls』 Birrell, Andrew D.、Nelson, B ruce Jay 共著、XEROX 社 CSL-83-7、1983 年 10 月

  2. 『VMTP: Versatile Message Transaction Protocol, Preliminary Version 0.3』Cheriton, D.著、Stanford 大学、1987 年 1 月

  3. 『Transmission Control Protocol - DARPA Internet Program Protocol Spec ification, RFC 793』 Postel, J. 著、Information Sciences Institute、1981 年 9 月

  4. 『User Datagram Protocol, RFC 768』 Postel, J. 著、Information Sciences Institute、1980 年 8 月

  5. 『Assigned Numbers, RFC 923』Reynolds, J. & Postel, J.著、Information Sciences Institute、1984 年 10 月