ユニバーサル TUN/TAP デバイスドライバ
Copyright (C) 1999-2000 Maxim Krasnyansky <max_mk@yahoo.com>

  Linux, Solaris 対応ドライバ
  Copyright (C) 1999-2000 Maxim Krasnyansky <max_mk@yahoo.com>

  FreeBSD 対応 TAP ドライバ
  Copyright (c) 1999-2000 Maksim Yevmenkin <m_evmenkin@yahoo.com>

  この文書は 2002 年に Florian Thiel <florian.thiel@gmx.net> によって
  改訂されました。

1. 解説

  TUN/TAP デバイスドライバは、パケットを送受信するインタフェースを
  ユーザ空間のプログラムに提供します。
  このデバイスは単純な Point-to-Point デバイスや、イーサネットデバイス
　のようなものとみなせます。ただし、物理メディアからではなくユーザ空間の
　プログラムからパケットを受信し、物理メディアにではなくユーザ空間の
　プログラムにパケットを送信します。

  このドライバを使うためには、プログラムは /dev/net/tun をオープンし、
  適切な ioctl() を発行してカーネルにネットワークデバイスを登録
  しなくてはなりません。
  ネットワークデバイスは、選択されたオプションに応じて tunXX もしくは
  tapXX として現れます。
  プログラムがそのファイルディスクリプタをクローズすると、
  ネットワークデバイスおよびそのデバイスと通信しているすべてのルート
  (route) が消滅します。

  選択されたデバイスのタイプに応じて、ユーザ空間のプログラムが
  読み書きする対象は、IP パケット (tun デバイスの場合) もしくは
  イーサネットフレーム (tap デバイスの場合) のいずれかになります。
  ioctl() に与えたフラグによって、どちらになるかかが決まります。

  http://vtun.sourceforge.net/tun にあるパッケージには、tun デバイスと
  tap デバイスの使い方を示すふたつの簡単なプログラム例が
  同梱されています。
  どちらのプログラムも、ふたつのネットワークインタフェース間の橋
  (ブリッジ) のように動作します。
  br_select.c - select システムコールをベースにしたブリッジ
  br_sigio.c  - async io と SIGIO シグナルをベースにしたブリッジ
  でも、ベストの実例は VTun http://vtun.sourceforge.net です :))  

2. 設定

  デバイスノードを作成する:
     mkdir /dev/net (まだ /dev/net が存在しない場合)
     mknod /dev/net/tun c 10 200

  パーミッションを設定する
     たとえばこのデバイスへのアクセスを root に限りたければ:
     chmod 0700 /dev/net/tun
     ネットワークデバイスをアサインする権利を一般ユーザに与えるのは
     いい考えでは「ありません」。ユーザが、ファイアウォールや
     管理者をだます目的で、にせのネットワークインタフェースを
     アサインできるようになってしまいます。      

  ドライバのモジュールを自動的にロードする場合
     お使いのカーネルで「カーネルモジュールローダ」−モジュールの
     自動ロードのサポート−が有効になっているのを確認してください。

     次の行を /etc/modules.conf に追加する:
	alias char-major-10-200 tun

     次のコマンドを実行する
        depmod -a 

  手動でロードする場合
     モジュールを手動でロードするには:
        modprobe tun

  後者の場合、必要となるたびに毎回モジュールをロードしなくてはなりません。
  前者の場合だと、/dev/net/tun がオープンされた時にモジュールは自動的に
  ロードされます。

3. プログラムのインタフェース

  3.1 ネットワークデバイスの割当て:

  char *dev は、使用するデバイスの名前に書式指定文字列をくっつけたものに
  すべきです (たとえば "tun%d")。でも、(わたしの知る限りでは) 妥当な
  ネットワークデバイスの名前ならなんでも使えます。
  この文字列へのポインタは、実際のデバイス名 (たとえば "tun0")
　によって上書きされることに注目してください。

  #include <linux/if.h>
  #include <linux/if_tun.h>

  int tun_alloc(char *dev)
  {
      struct ifreq ifr;
      int fd, err;

      if( (fd = open("/dev/net/tun", O_RDWR)) < 0 )
         return tun_alloc_old(dev);

      memset(&ifr, 0, sizeof(ifr));

      /* フラグ: IFF_TUN   - TUN デバイス (イーサネットのヘッダなし) 
       *         IFF_TAP   - TAP デバイス
       *
       *         IFF_NO_PI - パケットの情報を提供しない
       */

      ifr.ifr_flags = IFF_TUN; 
      if( *dev )
         strncpy(ifr.ifr_name, dev, IFNAMSIZ);

      if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
         close(fd);
         return err;
      }
      strcpy(dev, ifr.ifr_name);
      return fd;
  }              

  3.2 フレームのフォーマット:

  フラグ IFF_NO_PI がセットされていない場合、
  それぞれのフレームのフォーマットは:
    フラグ     [2 バイト]
    プロトコル [2 バイト]
    生のプロトコル (IP, IPv6, など) のフレーム

ユニバーサル TUN/TAP デバイスドライバについてよくある質問

1. TUN/TAP ドライバはどのプラットフォームをサポートしていますか?
今のところ、ドライバは 3 種類の Unix 系 OS に向けて書かれています。
   Linux kernels 2.2.x, 2.4.x
   FreeBSD 3.x, 4.x, 5.x
   Solaris 2.6, 7.0, 8.0

2. TUN/TAP ドライバはどんな用途に使うのですか?
上記の通り、TUN/TAP ドライバの主な用途はトンネリングです。
VTun (http://vtun.sourceforge.net) で用いられています。

TUN/TAP を使うもうひとつの興味深いアプリケーションは、pipsecd です
(http://perso.enst.fr/~beyssac/pipsec/)。
(FreeS/WAN とは違い) 完全なカーネルレベルのルーティングを使うことができる
ユーザ空間での IPSec の実装です。

3. 仮想ネットワークデバイスは実際どのように動作するのですか?
仮想ネットワークデバイスは単純な Point-to-Point デバイスや、
イーサネットデバイスのようなものとみなせます。
ただし、物理メディアからではなくユーザ空間のプログラムから
パケットを受信し、物理メディアにではなくユーザ空間のプログラムに
パケットを送信します。

仮に tap0 に IPX を設定したとすると、その後はカーネルが tap0 に
IPX パケットを送信するたびに、そのパケットはアプリケーション
(たとえば VTun) に渡されます。アプリケーションはパケットを
暗号化・圧縮し、TCP や UDP 経由で通信先に送信します。
通信先で動作しているアプリケーションは、受信したデータを
伸長・復号化して、得られたパケットを TAP デバイスに書きこみます。
するとカーネルはそのパケットをあたかも実際の物理デバイスから
来たものと同様に処理するのです。

4. TUN ドライバと TAP ドライバの違いはなんですか?
TUN は IP フレームに対して動作します。TAP はイーサネットフレームに
対して動作します。

言いかえると、tun を使用しているなら IP パケットしか読み書きできないし、
tap を使用しているならイーサネットフレームしか読み書きできない
ということです。

5. BPF と TUN/TAP ドライバの違いはなんですか?
BPF は先進的なパケットフィルタです。すでに存在している
ネットワークインタフェースに結びつけることができます。
BPF は仮想ネットワークインタフェースを提供しません。
TUN/TAP ドライバは仮想ネットワークインタフェースを提供しますし、
この仮想ネットワークインタフェースに BPF を結びつけることも
可能です。

6. TAP ドライバはカーネルのイーサネットブリッジングをサポート
していますか?
はい。Linux と FreeBSD 用のドライバはイーサネットブリッジングを
サポートしています。

日本語訳: 小林 雅典 <zap03216@nifty.ne.jp> (2003/01/24)

校正: 中野 武雄 <nakano@apm.seikei.ac.jp>
      山下 義之 <dica@eurus.dti.ne.jp>
