この章では,ifnet
STREAMS モジュールと,dlb
STREAMS 擬似ドライバの通信ブリッジについて説明します。
この章は,STREAMS とソケットの基本的な概念に習熟しており,第 4 章および第 5 章の内容を理解していることが前提となっています。
オペレーティング・システムのネットワーク・プログラミング環境は,ネットワーク・プログラミング用に,STREAMS およびソケットの両方のフレームワークをサポートしています。
ただし,この 2 つのフレームワーク間には,データ・リンク層における固有の通信パスはありません。
共存という用語は,ソケットと STREAMS のフレームワーク間で,データを交換できることを指します。
通信ブリッジという用語は,2 つのフレームワークがデータ・リンク層でデータを交換できるようにするソフトウェア
(ifnet
STREAMS モジュールまたは
dlb
STREAMS 擬似ドライバ) を指します。
ソケットおよび STREAMS に合わせて作成されたプログラムは,次の理由から相互通信をしなければなりません。
システムは,同一デバイス用に 2 つのドライバを持つことができない。
プログラムは,BSD プロトコル・スタックから STREAMS ベースのデバイス・ドライバにアクセスしなければならない場合がある。 また逆に,STREAMS ベースのプロトコル・スタックから,BSD デバイス・ドライバにアクセスしなければならない場合もある。
たとえば,システムで STREAMS デバイス・ドライバを実行しているとき,Tru64 UNIX にインプリメントされたソケット・ベースの TCP/IP をアプリケーションが使用している場合,ソケット・ベースのプロトコル・スタックと STREAMS デバイス・ドライバとの間でデータのやりとりに使用するパスが必要になります。
ifnet
STREAMS モジュールによって,TCP/IP を使用するアプリケーションは,STREAMS デバイス・ドライバとデータを交換できます。
ifnet
STREAMS モジュールについては,8.1 節で説明します。
逆に,システムに STREAMS プロトコル・スタックがインプリメントされていても,Tru64 UNIX にインプリメントされたBSDデバイス・ドライバを使用したい場合は,STREAMS プロトコル・スタックと BSD デバイス・ドライバとの間でデータのやりとりに使用するパスが必要になります。
dlb
STREAMS 擬似ドライバによって,STREAMS プロトコル・スタックは,データを BSD デバイス・ドライバに経路指定できます。
dlb
STREAMS 擬似ドライバについては,8.2 節で説明します。
8.1 STREAMS ドライバからソケット・プロトコル・スタックへのブリッジ
ifnet
STREAMS モジュールは,通信ブリッジです。
これによって,STREAMS ネットワーク・ドライバは,ソケット・ベースのネットワーク・プロトコルにアクセスできます。
ifnet
STREAMS モジュールは,他の STREAMS モジュールと同様に機能し,STREAMS デバイス・ドライバの上にあるストリーム上にプッシュされます。
一度,ストリーム上にプッシュされると,このモジュールは,STREAMS ドライバの DLPI インタフェースと BSD
ifnet
層との間で必要なすべての変換処理を行います。
ifnet
STREAMS モジュールは,標準の STREAMS インタフェースと,ifnet
層インタフェースの両方をエクスポートします。
また,STREAMSネットワーク・ドライバも,ifnet
STREAMS モジュールを使用している間は,STREAMS ベースのネットワーク・プロトコルの使用を継続することができます。
図 8-1
は,ifnet
STREAMS モジュールを強調表示して,ネットワーク・プログラミング環境における位置付けを示しています。
図 8-1: ifnet STREAMS モジュール
この項では,STREAMS ドライバを実行して
ifnet
STREAMS モジュールを使用するシステムを準備する方法について説明します。
注意
ifnet
STREAMS モジュールは,イーサネット STREAMS デバイス・ドライバだけをサポートします。
また,この項には,ifnet
STREAMS モジュールを正常に操作するために,STREAMS ドライバがサポートしなければならない DLPI プリミティブの一覧も記載します。
8.1.1.1 ifnet STREAMS モジュールの使用
デバイス・ドライバが,8.1.1.2 項に示すプリミティブをサポートする場合には,ifnet
STREAMS モジュールを使用するために,ドライバまたは STREAMS カーネル・コードのいずれもソース・コードを変更する必要はありません。
ifnet
STREAMS モジュールを使用するためには,STRIFNET および DLPI オプションをカーネル構成ファイルに追加し,ドライバに対して STREAMS をセットアップする必要があります。
STRIFNET および DLPI は,インストール時にシステムに組み込むことができます (オプションの構成については,『インストレーション・ガイド』を参照)。 オプションが構成されているかどうかは,次のコマンドで調べることができます。
# /usr/sbin/strsetup -c
ifnet
あるいは
dlb
が名前の欄に表示されれば,それらのオプションはカーネルに組み込まれています。
組み込まれていない場合は,doconfig
コマンドを使用してそれらを組み込む必要があります。
STRIFNET および DLPI をカーネルに組み込むには,次の手順に従います。
スーパユーザとしてログインする。
/usr/sbin/doconfig
コマンドを入力する。
構成ファイルをカスタマイズしている場合は
/usr/sbin/doconfig -c
コマンドを使用します。
詳細については,
doconfig
(8)
カーネル構成ファイルの名前を入力する。
この名前は,大文字のシステム名です。 通常,省略時の値が大カッコ ([]) の中に表示されます。 次に例を示します。
Enter a name for the kernel configuration file. [HOST1]: [RETURN]
システム構成ファイルを置き換えるかどうかのプロンプトに対して,y
を入力する。
A configuration file with the name 'HOST1' already exists. Do you want to replace it? (y/n) [n]: y Saving /sys/conf/HOST1 as /sys/conf/HOST1.bck *** KERNEL CONFIGURATION AND BUILD PROCEDURE ***
カーネルに組み込むオプションをメニューから選択する。
注意
STRIFNET および DLPI オプションは,メニューからは選択できません。 これらのオプションを組み込むには,以下の手順で構成ファイルを編集する必要があります。
カーネル構成ファイルのオプション・セクションに DLPI および STRIFNET を追加する。
カーネル構成ファイルを編集するかどうかを尋ねられたら,y
を入力する。
doconfig
コマンドでは,ed
エディタを使用して構成ファイルを編集できます。
ed
エディタの使用方法についての詳細は,
ed
(1)
次の例は,ed
編集セッションで,DLPI オプションおよび STRIFNET オプションを
host1
用のカーネル構成ファイルに追加する方法を示しています。
新しい行を追加する行番号は,カーネル構成ファイルによって異なる場合があります。
Do you want to edit the configuration file? (y/n) [n]: y Using ed to edit the configuration file. Press return when ready, or type 'quit' to skip the editing session: 2153 48a options DLPI options STRIFNET . 1,$w 2185 q *** PERFORMING KERNEL BUILD ***
新しいカーネルが構築された後,そのカーネルを,doconfig
が置いたディレクトリからルート・ディレクトリ (/
) に移動して,システムをリブートする。
リブートすると,strsetup -i
コマンドが自動的に実行され,新しい STREAMS モジュールに対してデバイス特殊ファイルが作成されます。
strsetup -c
コマンドを実行して,デバイスが正しく構成されたことを確認する。
次の例は,strsetup -c
コマンドからの出力を示しています。
# /usr/sbin/strsetup -c STREAMS Configuration Information...Thu Nov 9 08:38:17 1995 Name Type Major Module ID ---- ---- ----- --------- clone 32 0 dlb device 52 5010 dlpi device 53 800 kinfo device 54 5020 log device 55 44 nuls device 56 5001 echo device 57 5000 sad device 58 45 pipe device 59 5304 xtisoUDP device 60 5010 xtisoTCP device 61 5010 xtisoUDP+ device 62 5010 xtisoTCP+ device 63 5010 ptm device 64 7609 pts device 6 7608 bba device 65 24880 lat device 5 5 pppif module 6002 pppasync module 6000 pppcomp module 6001 bufcall module 0 ifnet module 5501 null module 5002 pass module 5003 errm module 5003 ptem module 5003 spass module 5007 rspass module 5008 pipemod module 5303 timod module 5006 tirdwr module 0 ldtty module 7701 Configured devices = 16, modules = 15
カーネルの再構成または
doconfig
コマンドについての詳細は,『システム管理ガイド』および
doconfig
(8)
ドライバ用にストリームをセットアップするには,次の手順に従ってください。
次のようなアプリケーション・プログラムを作成する。
/* * Application program to set up the "pifnet" streams for IP * and ARP. This must be run prior to ifconfig */ #include <stdio.h> #include <fcntl.h> #include <errno.h> #include <stropts.h> #include <sys/ioctl.h> #include <signal.h> #include "dlpihdr.h" #define IP_PROTOCOL 0x800 #define ARP_PROTOCOL 0x806 #define PIFNET_IOCTL_UNIT 1236 main(argc, argv) int argc; char *argv[]; { extern char *getenv(); char *p; short unit = 0; char devName[256]; if (argc != 3) usage(); strcpy(devName, argv[1]); unit = atoi(argv[2]); sigignore(SIGHUP); setupStream(devName, unit, IP_PROTOCOL); setupStream(devName, unit, ARP_PROTOCOL); /* * sleep forever to keep the Streams alive. */ if (fork()) /* detach */ exit(); pause(); } usage() { fprintf(stderr, "usage: pifnetd devname unit-number\n"); exit(1); } setupStream(devName, unit, serviceClass) char *devName; short unit; u_long serviceClass; { int fd, status; dl_bind_req_t bindreq; dl_bind_ack_t bindack; int flags; struct strioctl str; struct strbuf pstrbufctl, pstrbufdata, gstrbufctl, \ gstrbufdata; char ebuf[256]; /* * build the stream */ fd = open(devName, O_RDWR, 0); if (fd < 0) { sprintf(ebuf, " open '%s' failed", devName); perror(ebuf); exit(1); } if (ioctl(fd, I_PUSH, "ifnet") < 0) { sprintf(ebuf, " ioctl I_PUSH failed"); perror(ebuf); exit(1); } /* * tell pifnet the unit number for the device */ str.ic_cmd = PIFNET_IOCTL_UNIT; str.ic_timout = 15; str.ic_len = sizeof (short); str.ic_dp = (char *) &unit; status = ioctl(fd, I_STR, &str); if (status < 0) { sprintf(ebuf, " %s - ioctl"); perror(ebuf); exit(1); } /* * bind the stream to a protocol */ bindreq.dl_primitive = DL_BIND_REQ; bindreq.dl_sap = serviceClass; bindreq.dl_max_conind = 0; bindreq.dl_service_mode = DL_CLDLS; bindreq.dl_conn_mgmt = 0; bindreq.dl_xidtest_flg = 0; pstrbufctl.len = sizeof(dl_bind_req_t); pstrbufctl.buf = (void *)&bindreq; pstrbufdata.buf = (char *)0; pstrbufdata.len = -1; pstrbufdata.maxlen = 0; status = putmsg(fd, &pstrbufctl, (struct strbuf *)0, 0); if (status < 0) { perror("putmsg"); exit(1); } /* * Check requested binding */ gstrbufctl.buf = (char *)&bindack; gstrbufctl.maxlen = sizeof(dl_bind_ack_t); gstrbufctl.len = 0; status = getmsg(fd, &gstrbufctl, (struct strbuf *)0, &flags); if (status < 0) { perror("getmsg"); exit(1); } if (bindack.dl_primitive != DL_BIND_ACK) { errno = EPROTO; perror(" DL_BIND_ACK"); exit(1); } }
このアプリケーション例では,ドライバの名前は
/dev/streams/ln
です。
このアプリケーションは,2 つのストリームを作成します。
1 つはインターネット・プロトコル (IP) 用であり,もう 1 つはアドレス解決プロトコル (ARP) 用です。
ストリームをセットアップした後,このアプリケーションは,ストリームを保持しておくために,pause
コマンドを使用して,実行を継続しなければなりません。
ドライバがスタイル 2 のドライバの場合には,アプリケーション・プログラムに
DL_ATTACH_REQ
プリミティブを追加しなければなりません。
DL_ATTACH_REQ
プリミティブまたはスタイル 2 のドライバについての詳細は,/usr/share/doclib/dlpi/dlpi.ps
の DLPI 仕様を参照してください。
アプリケーションの実行可能ファイルを生成する。
エラーなしで実行できるまで,プログラムをコンパイル,リンク,およびデバッグします。
ユーザに都合のよいディレクトリに,実行可能プログラムを移動する。
実行可能プログラムは,どのディレクトリにもいれることができます。
このプログラムを呼び出す行を,/sbin/init.d/inet
ファイルに追加する。
このプログラムは,リブートするたびに手動で起動できます。
ただし,/sbin/init.d/inet
ファイルに 1 行追加して,システムのリブート時に自動的に実行させると非常に便利です。
この行は必ず,システムの
ifconfig
行より前に追加してください。
次の例では,システムがリブートするたびに,/sbin/init.d/inet
ファイルは,/etc
ディレクトリにある
run_ifnet
というプログラムを実行します。
.
.
.
# # Enable network # case $1 in echo "Configuring network" /sbin/hostname $HOSTNAME echo "hostname: \c" /sbin/hostname if [ "$NETDEV_0" != '' ]; then echo >/tmp/ifconfig_"$NETDEV_0".tmp # place command invoking executable BEFORE \ ifconfig lines /etc/run_ifnet /sbin/ifconfig $NETDEV_0 $IFCONFIG_0 > \ /tmp/ifconfig_"$NETDEV_0".tmp 2>&1 if [ $? != 0 ]; then ERROR=`cat /tmp/ifconfig_"$NETDEV_0".tmp` if [ "$ERROR" = "$ERRSTRING" ]; then /sbin/ifconfig $NETDEV_0 up else echo "$0: $ERROR" fi fi rm /tmp/ifconfig_"$NETDEV_0".tmp fi
.
.
.
システムをリブートする。
/usr/sbin/shutdown -r
コマンドを使用して,システムをシャットダウンし,自動的にリブートさせます。
次に例を示します。
# /usr/sbin/shutdown -r now
8.1.1.2 データ・リンク・プロバイダ・インタフェース・プリミティブ
STREAMS デバイス・ドライバは,スタイル 1 またはスタイル 2 のいずれの DLPI プロバイダでもかまいません。
これについては,/usr/share/doclib/dlpi/dlpi.ps
のデータ・リンク・プロバイダ・インタフェース仕様に説明があります。
この DLPI 仕様にオンラインでアクセスするには,OSFPGMRnnn
サブセットがインストールされていなければなりません。
このドライバでは,次の DLPI プリミティブをサポートしなければなりません。 これらのプリミティブとその使用方法についての詳細は,DLPI 仕様を参照してください。
DL_PHYS_ADDR_REQ/DL_PHYS_ADDR_ACK
DL_BIND_REQ/DL_BIND_ACK
DL_UNBIND_REQ
DL_UNITDATA_REQ/DL_UNITDATA_IND/DL_UDERROR_IND
DL_OK_ACK/DL_ERROR_ACK
8.2 BSD ドライバから STREAMS プロトコル・スタックへのブリッジ
dlb
STREAMS 擬似デバイス・ドライバによって,BSD スタイルのデバイス・ドライバと,STREAMS プロトコル・スタックをブリッジできます。
STREAMS 擬似デバイス・ドライバは,BSD ベースのドライバとの通信を必要としている,ストリーム内のストリーム・エンドです。
このオペレーティング・システムで提供されている STREAMS 擬似デバイス・ドライバには,2 つのインタフェースがあります。
1 つは,STREAMS プロトコル・スタックと通信する DLPI インタフェースのサブセットであり,もう 1 つは,ソケット・フレームワークの
ifnet
層インタフェースにアクセスするインタフェースです。
図 8-2
は,dlb
STREAMS 擬似ドライバを強調表示して,ネットワーク・プログラミング環境における位置付けを示しています。
8.2.1 サポートする DLPI プリミティブおよびメディア・タイプ
dlb
STREAMS 擬似ドライバは,次のコネクションレス・モードのプリミティブとメディア・タイプをサポートします。
これらのプリミティブ,およびその使用方法についての詳細は,/usr/share/doclib/dlpi/dlpi.ps
のデータ・リンク・プロバイダ・インタフェース仕様を参照してください。
DL_ATTACH_REQ/DL_DETACH_REQ/DL_OK_ACK
DL_BIND_REQ/DL_BIND_ACK/DL_UNBIND_REQ
DL_ENABMULTI_REQ/DL_DISABLMULTI_REQ
DL_PROMISCON_REQ/DL_PROMISCONOFF_REQ
DL_PHYS_ADDR_REQ/DL_PHYS_ADDR_ACK
DL_SET_PHYS_ADDR_REQ
DL_UNITDATA_REQ/DL_UNITDATA_IND
DL_SUBS_BIND_REQ/DL_SUBS_BIND_ACK
DL_SUBS_UNBIND_REQ/DL_SUBS_UNBIND_ACK
イーサネット・バス (DL_ETHER
) は,STREAMS 擬似ドライバがサポートするメディア・タイプです。
8.2.2 STREAMS 擬似ドライバの使用
dlb
STREAMS 擬似ドライバを使用するには,DLPI オプションをカーネルに組み込まなければなりません。
DLPI オプションは,インストレーション時にシステムに組み込まれている場合もあります。
DLPI オプションが組み込まれているかどうかを調べるには,次のコマンドを実行します。
# /usr/sbin/strsetup -c
名前の欄に
dlb
が表示されれば,このオプションはカーネルに組み込まれています。
表示されない場合は,doconfig
コマンドで追加する必要があります。
doconfig
コマンドを使用してカーネルを再構成する方法については,8.1.1.1 項を参照してください。
カーネルの再構成の方法,および
doconfig
コマンドについての詳細は,『システム管理ガイド』および
doconfig
(8)