TUN(4)

名称
tun - トンネルソフトウェアネットワークデバイス

書式
pseudo-device tun [count]

解説
tun インタフェースはソフトウェアループバック機構であり、大雑把に説明すると pty(4) のネットワークインタフェース版のようなものです。つまり tun は、 pty ドライバが端末に対して行なうことを、ネットワークインタフェースに対して 行います。

tun ドライバは pty ドライバと同様に、2 つのインタフェースを提供します: ドライバが シミュレートしている通常の機能のようなインタフェース (これは tun の場合にはネットワークインタフェースであり、 pty の場合には端末です) および、キャラクタ型特殊デバイス “制御” インタフェースです。

ネットワークインタフェースには tun0, tun1 等のように名前が付けられます。これは pseudo-device 行で指定された count の数だけあります。各インタフェースはネットワークインタフェースの 通常の ioctl(2) ( SIOCSIFADDR や SIOCSIFNETMASK 等) をサポートしているので、他のインタフェースと同様に ifconfig(8) で使うことができます。このインタフェースは起動時には POINTOPOINT インタフェースですが、変更することができます。後述する制御デバイスの 説明を参照してください。システムがパケットをネットワークインタフェース に送ることになった時、そのパケットを制御デバイスから読むことができます ( これは “input” としてここに現われます) 。 パケットを制御デバイスに書き込むと、ネットワークインタフェースには入力 パケットが生成されます。この動作は、 (存在しない) ハードウェアがパケットを受け取ったかのように行われます。

トンネルデバイス (通常は /dev/tunN ) は排他的にオープンされるデバイス ( 既にオープンされている場合にはオープンできません) であり、スーパユーザしか利用できないように制限されています。 インタフェースが “ready” 状態 (制御デバイスがオープンされており、インタフェースのアドレスが設定 されている状態) でなければ、 read() システムコールはエラー (EHOSTDOWN) を返します。 インタフェースが ready 状態になった時、パケットが読み込み可能であれば read() はパケットを返します。読み込み可能でなければ、パケットが読み込めるまで ブロックするか EWOULDBLOCK を返します。どちらの動作になるのかは、非ブロッキング I/O モードが有効 にされているかどうかで決まります。 read() に渡されるバッファに許されているよりもパケットが長い場合には、超過分の データは黙って捨てられます。

オプション指定により、パケットがネットワークインタフェースの出力ルーチン (‘tunoutput’) に与えられる際に、パケットの前に終点アドレスを付けるようにすることがで きます。 終点アドレスのフォーマットは、構造体 ‘sockaddr’ です。前に付いたアドレスの実際の長さは、構造体のメンバ ‘sa_len’ に格納されます。パケットのデータはこの直後に続けて置かれます。 write(2) システムコールの呼び出しによりパケットをインタフェースに渡して、 仮想インタフェースがパケットを “受信” した状態にします。 write() システムコール 1 回の呼び出しで、ちょうど 1 つのパケットを与えます。 パケット長は write() に与えられたデータの量から決められます。 書き込みはブロックされません。パケットが一時的な理由 (例: バッファに利用できる容量が無い) で受け取られなかった場合には、パケットは黙って捨てられます。理由が 一時的なものでなかった場合 (例: パケットが大きすぎる) には、エラーが返されます。 “リンク層 (link-layer) モード” が有効 (後述の TUNSLMODE を参照) ならば、実際のパケットデータの前には、構造体 ‘sockaddr’ がなければなりません。 現在のドライバは ‘sa_family’ フィールドしか調べません。 以下の ioctl(2) 呼び出しがサポートされています (定義されている場所は <net/if_tun.h>):

TUNSDEBUG
    引数は int へのポインタでなければなりません。 これは内部的なデバッグ用変数をその値に設定します。この変数が制御するも のは (もしあったとしても) ここでは説明しません。ソースコードを読んでくだ さい。

TUNGDEBUG
    引数は int へのポインタでなければなりません。 これは、内部的なデバッグ用変数の値を引数が示す場所に格納します。

TUNSIFMODE
    引数は int へのポインタでなければなりません。 この値は IFF_POINTOPOINT または IFF_BROADCAST でなければなりません。 対応する tunn インタフェースのタイプが与えられたタイプに設定されます。上記以外の値が 指定された場合には、エラー EINVAL が発生します。この時にはインタフェースは停止 (down) していなければ なりません。動作していれば、エラー EBUSY が起こります。

TUNSLMODE
    引数は int へのポインタでなければなりません。 0 でない値を指定すると、 “リンク層” モードが有効になります。このモードでは、トンネルデバイスから読み込んだ パケットの前にネットワーク終点アドレスが追加されます。

FIONBIO
    読み込み時の非ブロッキング I/O の有効・無効を設定します。引数 int の値が 0 かどうかによって、無効か有効かが決まります (書き込みは必ず非ブロッキングです) 。

FIOASYNC
    読み込み時の非同期 I/O ( つまり、データが読み込み可能な時に SIGIO が生成されるかどうか) の有効・無効を設定します。引数 int の値が 0 かどうかによって、無効か有効かが決まります。

FIONREAD
    パケットが読み込みキューに入っている場合、最初のパケットのサイズを引数 int に格納します。それ以外の場合には 0 を格納します。

TIOCSPGRP
    非同期 I/O が有効になっている場合に、 SIGIO シグナルを受け取るプロセスグループとして引数 int の値を設定します。

TIOCGPGRP
    SIGIO シグナルに対するプロセスグループの値を取得し、この値を引数 int に格納します。

制御デバイスは読み込みに対する select(2) もサポートしています。書き込みに対する select は必ず成功するので意味 がありません。なぜなら、書き込みは必ず非ブロッキングだからです。

最後のデータデバイスを閉じた時、デフォルトではインタフェースが停止 します ( “ifconfig tunn down” が実行されたのと同様になります) 。 キューに入っているパケットは全て捨てられます (データデバイスがオープンされていない時にインタフェースが動作している 場合、出力パケットは蓄積されないで、常に捨てられます)。

関連項目
inet(4), intro(4)

バグ
現在は IP 専用です。

作者
このマニュアルページは NetBSD から取得しました。