2004年1月12日月曜日

Debian GNU/Linux, PPxP によるインターネット接続 (ISDN)

IRC依存症発症(PPxPによるイソターネットの設定)

今までやる気のないdebian導入記や日本語環境構築記を読んでくださった方、どうもありがとう。 実はここからが本題。PPxPの導入、インターネット接続編である。 PPxPはモデムやTAと繋いでPPP通信するのに必要なソフトである。(以下文中で「モデム」とTAを同一に呼んでいる) まあとりあえず、PPxPのダウンロードはこちらへ。実はPPxPの他にもuserlinkモジュールというのも必要なので、上記のPPxPの公式ホームページにてuserlinkも手にいれよう。
筆者の場合は、カーネルの再構築を一度やってからインストールを行った。(再構築の必要はないのだが、/usr/src/kernel-source-2.2.17がなかった)
apt-get install でppxp関連のファイル(ppxp, ppxp-x11, ppxp-tcltk)をインストール(と設定)し、userlink-sourceも同様にインストールした。(以下略)

PPxPを動かす。インストール方法は省略。 Debianゆえに、dpkgとか使って楽させてもらったし、おそらく一般的なインストール方法は公式ホームページを参照にしたもらった方がいいはず。 なので、筆者の使用しているTA、NECのAtermITX80Dでどうやって繋いだかを報告。 ちなみに、回線はISDNである。
まずはppxpを起動してみる。すると

SysIfOpen:No such device

というエラーを出力してうまく起動しないことがある。 こう言うときは

# depmod -a
# modprobe userlink

を実行してからだとppxpがちゃんと起動する。 しかし、これだと、rebootをして、またppxpを起動する際にも同じエラーが出るので上記コマンドをまた(ルートで)実行しなければならない。
だるい、これは。
なので、/etc/modulesというファイルにuserlinkを加えると、ブートした後始めてppxpを動かすたびに上記2つのコマンドを打つ手間が省ける。 それは筆者の環境が悪いのか? よくわからないが同じ症状(?)で面倒だと思う方はお試しあれ。

$ more /etc/modules
# /etc/modules: kernel modules to load at boot time.
#
# This file should contain the names of kernel modules that are
# to be loaded at boot time, one per line.  Comments begin with
# a #, and everything on the line after them are ignored.
nfs
nfsd
smbfs
vfat
autofs
ipv6
serial
userlink    #ADDED

まず、一般的に「外付モデム」はLinuxで使える可能性がとても高いと言われている。 なぜなのかはわからん。 どうやら外付ではない、パソの中にすっぽり入ってしまうようなモデムの中にはWINMODEMと風刺されるような、Windowsとしか会話のできないモデムが多いといわれている。 もちろんドライバなんて公開してくれないから、そういうモデムをLinuxで使うことはほぼ不可能に近いらしい。
お宅のモデム、大丈夫?(何
そういうわけで、筆者の家のTAを見てみる。 よかった、外付だ。廊下にそいつは転がっていた。

モデムとの会話方法は、言わずと知れた今はなきヘイズ社のATコマンドがある。 ほとんどのコマンドがATから始まるからATコマンドなどと呼ばれるらしい。 そのまんまだな。 まあいい。 NECのAtermITX80DについてきたドライバCD-ROMの中に入っているATコマンドの資料(pdfファイル)を引っ張りだしてみることにする。 なんだかんだいって、製品独自のATコマンドというのもいっぱいあるものだ。
じゃあまずは、ATコマンドでモデムと会話をしてみよう!
なにやらkermitとかcuというモノを使ってもモデムと会話ができるのだが、実はppxpだけでも十分モデムとお話ができるのである。 terminalモードである。 Windowsの「ハイパーターミナル」みたいなものだ。

$ ppxp serial
ppxp>set line /dev/ttyS0
ppxp>terminal
AT
OK
ATI4
AtermIT NEC Corporation
term>disconnect
ppxp>bye
$ 

ちなみに、/dev/ttyS0は1つめのシリアルポートである。いわゆるCOM1。 /dev/ttyS1ならCOM2に相当する。 この場合、COM1にモデムが繋がっているという事を前提とする。
terminalと打つと、ターミナルモードに突入する。 この状態でATと打つと、モデムからOKと返事が返ってきている。 AtermITX80Dでは、ATI4と打つと、AtermIT NEC Corporationとかいう返事を返してくれるらしい。
このterminalモードから抜けるには、CTRL-\ のあとに、大文字のCを打つ。
普通はこのように、簡単にモデムとお話ができるものなのだ。

拒絶。 terminalモードに突入しても筆者の場合、ATと打ってもモデムからの返事はなく、ただIgnore until "AT"という結果が表示されるだけ。
そしてこの異常事態の原因として怪しいと睨んだのがsetserialであった。 我がパソのシリアルポートが安物で自ずからUART(Universal Asynchronous Receiver Transmitter=マザーやモデムカードにのっているシリアル用のチップ)の型名を名乗れないのではないか。 と意味不明な心配をしてみる。 (実はsetserial -g /dev/ttyS0などでもちゃんとUARTを名乗っていた。)
このsetserialというのはシリアルポートのI/Oアドレスのポートのハードウェアに設定されている割り込み(IRQ)、使用しているUARTの種類などのデバイスドライバのソフトウェアに伝えられるようにするプログラム、だという。 なにがなにやら、である。 IRQは言わずと知れた「割り込み順位」を決めるやつでBIOSなんかでもよく設定ができたりする。 時計やキーボードが割り込み順位が高いという。 なんとなく分からないでもない、割り込み。 CPUに対する割り込み。 /proc/interruptsというファイルを覗いてみると、どのデバイスにいくつのIRQの値が設定されているかとか、どれだけの割り込みが発生しているかが分かってちょっと面白いだろう。

$ more /proc/interrupts 
           CPU0       
  0:    2203691          XT-PIC  timer
  1:      65870          XT-PIC  keyboard
  2:          0          XT-PIC  cascade
  3:          6          XT-PIC  serial
  4:     181534          XT-PIC  serial
 12:     297114          XT-PIC  PS/2 Mouse
 13:          1          XT-PIC  fpu
 14:     161631          XT-PIC  ide0
NMI:          0
ERR:          0

左はじの数値がIRQの値。 その右隣は割り込み発生回数。見ての通りtimerがとても多い。 一般的なIRQの割り当ては次のようなものらしい。

0:タイマチャネルor割り込みなし
1:キーボード
2:コントローラ2へのカスケード
3:シリアルポート2
4:シリアルポート1
5:パラレルポート2、サウンドカード
6:FDD
7:パラレルポート1
8:リアルタイムクロック
9:IRQ2にリダイレクト(IRQ2に同じ)
10〜12:割り当てなし
13:数値コプロセッサ
14:HDコントローラ1
15:HDコントローラ2

このうち、2、3、4、5、7、10〜12、15は自由に使えるもの

このIRQとI/Oアドレスをあわせてリソースという。 I/Oアドレスは/proc/ioportsというファイル内を覗くとその割り当てがわかる。

$ more /proc/ioports 
0000-001f : dma1
0020-003f : pic1
0040-005f : timer
0060-006f : keyboard
0080-008f : dma page reg
00a0-00bf : pic2
00c0-00df : dma2
00f0-00ff : fpu
01f0-01f7 : ide0
02f8-02ff : serial(set)
03c0-03df : vga+
03f6-03f6 : ide0
03f8-03ff : serial(set)
d000-d007 : ide0
d008-d00f : ide1

たとえば、次のように/dev/ttyS0がどのようなリソースを持っているのかがわかる。

$ setserial -g /dev/ttyS0
/dev/ttyS0, UART: 16550A, Port: 0x03f8, IRQ: 4

ただし、このようなIRQとシリアルポートとの問題が発生するのは、シリアルポートが4つも5つもあるようなそういう環境に多いという。 当時筆者のマシンには2つのシリアルポートしか存在しなかった。 なので、このような問題が発生するとは思えなかったが、とりあえず起動メッセージにあるシリアルポートに関するメッセージを取り出して読んだりしていたものだ。
dmesgというコマンドがあるが、これは実際の起動時の全てのメッセージを出力してくれるとは限らない。 あまり信用ならないコマンドであると言う。 なので、やはり生の起動メッセージを見たいものだ。 そのためには、最初のBIOSのメッセージをPAUSE(BREAK)キーで止めたり、SHIFT+PAGEUPなどでどんどん画面に流れて行く起動メッセージを逆流して見てみたりしよう。 シリアルポートに関する出力は2箇所あるはずだ。 最初はハードウェアによるシリアルポートの設定メッセージ、次はソフトウェアによる(setserialによる)設定メッセージになる。 これらのIRQ値に相違があると、動作が遅くなったり、動作していないように見えたりすると言う。 もちろんシリアルポートをたかだか2個しか持っていないようなパソにはあまり関係のないことだったのかも知れないが、筆者は一生懸命/etc/serial.confを書き換え、起動時に実行されるsetserialのための設定を換えたりいろいろやった。 それでも出るIgnore until "AT"というエラーメッセージは消えず、モデムと全く通信できないことを示唆していた。このときせっせと見ていたsetserial関連、シリアルポート全般に関する資料

そして次に筆者が注目したのはモデム初期化のATコマンドであった。 ppxpでは最初にモデムを使う前に初期化をする。 どういう風に初期化するかというと

  • エコーバックしない
  • リザルトコードを返す
  • リザルトコードを文字で返す
  • CD信号を上げたままにしない
  • DTR信号を無視しない
  • ハードフロー制御(RS-CSフロー制御)をする

という風に初期化するのがポイントなんだそうだ。
ここで気になるのが○○信号というものだ。

モデムが通信をする流れ。www.netlaputa.ne.jp/~hijk/study/nw/glossary.htmを勝手に参照

Carrier Detect(CD信号)

データチャネル受信キャリア検出、相手側のモデム(今回はISPのモデム)からキャリアを検出するとCDランプが点灯する。

  1. 端末、モデムの電源をONにすると、まずER信号をONにし、DR信号をONにして信号を待つ
  2. 送信データが発生すると、端末はRS信号をONにする。モデムはこれを受けて最初のキャリアとしてトレーニング信号を送信する。
  3. 受信側モデムはトレーニング信号を受けると自動等化器の調整を始める。V.29ではこの調整時間を253ミリ秒としている。
  4. 調整後、送信側モデムはCS信号をONにして、それ以降のデータを送信データSD(Send Data)とみなし、変調してアナログ回線に送出する。
  5. 調整後受信側モデムはCD信号をONにして、RD(Receive Data)のデータ受信線から送られてくるデータを受信データとして認識する。

Clear to Send(CS信号)

送信可、トレーニング信号送信後一定時間(253ミリ秒)でONとなる。 それ以降のデータは送信データとみなして送出される。

Data set Ready(DR信号)

端末、モデムの電源投入後、ER信号のONにひき続いて、データ受信準備可能状態としてONになる。

ER信号

データ端末レディ信号

Receive Data

受信側モデムはトレーニング信号を受け、等化器を調整すると、CD信号をONにして、以降はRD信号線から送られて来るデータを受信データとして処理する。

Request to Send(RS信号)

送信要求

そういうわけでだいたいわかった○○信号。 しかしその日、とうとうあることにきづいたのだった。
例えば、パソとパソを直接シリアルポートで繋ぐ(ゲームボーイ同士を通信対戦で繋ぐように)場合、使用するRS232Cケーブルはクロスケーブルでなければならない。 ところが、モデムとパソを繋ぐときは、ストレートケーブルを使わなければならない。 電極をケーブル(メス−メス ケーブル)の片方のはしの3と書かれた穴に刺す。 ケーブルのもう片方のはしの2と書かれた穴にも電極を刺して、通電させてみよう。 見事電流が流れれば、それはクロスケーブル、パソとモデムを繋ぐのには使えない!
筆者はとうとうケーブルに疑問を抱いた。 小さな疑問、まさかこのケーブルがクロスケーブルだった、なんてオチはないだろう、そう思っていた。
上記の2の穴と3の穴とを通電させると、繋いでいた豆電球にパッと明りがともったのだった。

犯人が発覚し、筆者は電器屋ですぐにストレートケーブルを買ってきた。 いそいそとストレートケーブルでモデムとパソを繋ぎ、ppxpのterminalモードに突入。
するとそこにはIgnore until "AT"のエラーはなく、普通にモデムとの楽しい会話がスタートしたのだった! PPxPの公式ホームページの掲示板に筆者と同様の症状(Ignore until "AT")に悩んでいた人が数名いた。

汝、ケーブルを疑うべし!

以上、モデムと会話をするという目標を達したのであった。

つかおう、ITMUX機能。
AtermITX80Dの特徴的機能、それはITMUX機能だ。 簡単に言えば、一度に同じISP相手ならば2台のパソが同時にインターネットができるというルータみたいな機能。 家にパソがゴロゴロしているような人にはとうてい物足りない機能だが、筆者レベルのユーザにはちょうどよい機能だ。 案の定普通に繋いでいたら同居人に「俺のパソがネットに繋げないことがある」と苦情を言われた。 あたりまえだ、こっちはppxpで回線を一人占めしてるんだから、、、、。(ぉ
そんなわけで、ITMUX機能を使おう。 これはAtermの説明書にある通り、ISPにダイヤルする際に、電話番号の後ろにPAという2文字を無造作にくっつけるだけ。 ISPのアクセスポイントの電話番号が123-4567なら、ppxpの設定を123-4567PA/1(最後の/1は、1回ダイヤルするという意味です、よね?)のようにくっつける。 うむ、これだけか。

公開、現在使用しているInitialize文字列。
Initialize文字列を変えることにより、モデムの初期化ATコマンドを変えることができる。 筆者の使っているのはAtermITX80D、回線はISDNである。 2002年2月現在の初期化文字列は以下のようになっている。

ATH0E1Q0V1X3$N9=10$N1=1&D0&C1

ひょっとすると、自動切断タイマが働いている設定である。 (IRCにずっと繋いでいると、鯖からちょくちょくPINGが飛んでくるためか、ちょくちょく通信しているように察知されるらしく、安心して(?)自動切断タイマONにしている) とりあえず、Atermの中には、「エコーオンが他のモデムと逆(E1とE0)」という噂がある。(笑) Atermユーザはお気を付けて。 ちなみに、筆者はとても面倒臭がりなので、/etc/ppxp/modem/aterm のファイルを直接編集してしまった。 場所的にもわかるとおり、rootにならないと編集できないであろうに、、、、。

ATコマンドおまけ。
AT\SというATコマンドで、モデムのステータスを見ることができる。 当初これでネット切断中にモデムのステータスをみてみたところ、ER、CD、DR、RS、CS信号がすべてONになっていて驚いたことがあった。 このとき、相手(=ISP)から切断された場合、PPxPがそれに気づかずずっと繋いでいるフリをし続けていた。 つまり、チャットから落ちたことがわからないのである。 これでは困る。
CD信号というのは、上記に説明した通り、相手モデムと繋いでいる間だけ検出されるものだ。 もちろん、Initialize文字列を急いで修正したのは言うまでもない。(AT&C1)