こんにちは。すっかりごぶたさのTEAです。現在製作中のDOS用PPPについて説明します。
PPPというのはみなさんご存じでしょうが、Point-to-Point Protocolの略で、パソコンからモデムでネットサーフィンするときに使います。ぼくは普段はNIFTY SERVEを使っていますが、料金が非常に高かったのです(注:12月からは月15時間まで2000円になるのでそんなには高くない)。そこで、安いインターネット接続プロバイダを探しているのですが、どこもPPPが使えないと繋げません。
WindowsやUNIXではちゃんとPPPが使えるので問題はないのですが、僕の場合はメール読みとitalkだけで十分なので、それだけのためにメモリを食うWindowsを入れたくありません。というわけで9801のDOSからPPPでtelnetを動かしたいなと思ったのです。
ちなみにDOSでもDOS/Vならば EtherPPP や dosppp というソフトがあり、ちゃんとDOSからPPPできます。本当はDOS/Vを買ってしまうのが一番いいのでしょう。
PPPを作ろうと思ったのはずいぶん昔なのですが、よくわからないのでやっていませんでした。でもZZZというプロバイダがあって、そこがダイアルQ2を使って1分3円ということをやっていたので、試しに普通の通信ソフトでアクセスしてみました。すると
login:zzz
Password:
PPP session from (203.138.254.226) to 203.138.254.231 beginning....
~ }#!}!}!} }4}"}&} } } } }%}&
こんなかんじでした。これを見て、なんか作れそうだなと思いました。適当ですね。
「DOS用PPPを作ろう!」と思ったのですが、よく考えたらいろいろ作らないといけないんですね。少なくとも
を作らないといけないですね。なんか不毛だ。本当なら汎用のドライバにするべきなんだろうけど、まずはitalkができるようにしようと思ってやっています。というわけで、italkをするのに最低限必要なことを説明します。
telnetで文字列を送る場合、まずその文字列の前にTCPのヘッダをつけます。次にその前にIPのヘッダをつけ、さらにPPPのヘッダを付けて、エスケープ文字を入れてモデムに送ります。反対に、モデムから何か送られてきたら、PPPのヘッダを取り、エスケープ文字を取り、TCP/IPのヘッダをとると文字列が得られます。
モデムとのデータのやりとりは、DOS標準の関数を使います。C言語ではstdauxですかね。なお、この部分は竹島くんのAUXTERMを参考にさせて頂きました。
PPPのデータは 0x7e で始まり 0x7e で終わります。データ中に 0x7e が入っている場合は、エスケープ文字 0x7d と 0x7e 0x20 = 0x5e のニ文字になります。また、エラーチェックのために16bitのCRCがついているので、送るときは CRCを計算しなければなりません。
PPPで相手とデータをやりとりするには、決めなければならないことがあります。これはLCP (Link Control Protocol) で決めます。ここでは、PPPヘッダの圧縮や、制御コードの送りかたを決めます。相手がヘッダの圧縮を使いたいと言ってきた場合、こちらでそれが実装されていればACKを返します。実装されていない場合はそれはできないと断ります。こちらと相手が共に相手の要求をのむまで妥協しながら繰り返します。
なお、LCPのあとにPAPやCHAPでパスワードを聞かれるかもしれません。
IPの場合も、IPCP (Internet Protocol Control Protocol) を使って決めることがあります。IPヘッダの圧縮と、こちらのIPアドレスです。相手のIPアドレスは送られてきたものを使います。こちらのIPアドレスは0.0.0.0を使うと相手に伝えると、それは拒否されてこのアドレスを使いなさいと言ってくるので、それを使いますよと返事すればいいです。
これが済めば、IPのやりとりが出来るようになります。
TCPのコネクションを張るには、TCPヘッダのSYNフラグを立てて、こちらからのデータの順序番号を送ります。すると、相手からはSYNに対するACKと、相手からのデータの順序番号が送られてきます。これにACKを返せばいいです。
あとはTCPのヘッダをつけてデータを送るだけです。IPのヘッダに自分と繋げたいところのIPアドレスを書き、TCPのヘッダに相手のポート番号 (telnetなら23、italkなら12345) を書きます。なお、IPアドレスが分からない場合は、どこかのDNSに聞く必要があります。
TCPはヘッダとデータに対してチェックサムを計算する必要があります。サムと言ってもアムロのだんなではありません。このときに、疑似ヘッダと言う、TCPのヘッダには含まれないIPアドレスを入れたヘッダを作り、これを含めてチェックサムを計算します。ただし疑似ヘッダは実際には送られません。また、データが奇数長の場合は最後に 00 があるものとして計算します。
なぜだか理由は分かりませんが、IPCPがすんだあとにすぐにTCPのパケットを送ってもだめでした。そこで少しwaitを入れています。なんか間違ってるのかな。
また、italkの場合はこれでいいのですが、telnetでは最初に相手から FF FD 18 が送られてくるので、こちらは FF FC 18 を送らないといけないそうです(Applauseくんありがとう)。
やることはたくさんあります。
そのうちやるかもしれません。(ぉ
感想などは、sada@is.s.u-tokyo.ac.jp までお願いします。
ホームページは http://naomi.is.s.u-tokyo.ac.jp/~sada/ です。
[1] 西田 竹志: TCP/IP, (株)ソフト・リサーチ・センター
[2] RFC Index Search Form, http://www.nexor.com/public/rfc/index/rfc.html