tun ドライバは pty ドライバと同様に、2 つのインタフェースを提供します: ドライバが シミュレートしている通常の機能のようなインタフェース (これは tun の場合にはネットワークインタフェースであり、 pty の場合には端末です) および、キャラクタ型特殊デバイス ``制御'' インタフェースです。
ネットワークインタフェースには tun 0 tun 1 等のように名前が付けられます。これは pseudo-device 行で指定された count の数だけあります。各インタフェースはネットワークインタフェースの 通常の ioctl(2) ( SIOCSIFADDR や SIOCSIFNETMASK 等) をサポートしているので、他のインタフェースと同様に ifconfig(8) で使うことができます。このインタフェースは起動時には POINTOPOINT インタフェースですが、変更することができます。後述する制御デバイスの 説明を参照してください。システムがパケットをネットワークインタフェース に送ることになった時、そのパケットを制御デバイスから読むことができます Po これは ``input'' としてここに現われます Pc 。 パケットを制御デバイスに書き込むと、ネットワークインタフェースには入力 パケットが生成されます。この動作は、 (存在しない) ハードウェアがパケットを受け取ったかのように行われます。
トンネルデバイス (通常は /dev/tun N ) は排他的にオープンされるデバイス Po 既にオープンされている場合にはオープンできません Pc であり、スーパユーザしか利用できないように制限されています。 インタフェースが ``ready'' 状態 (制御デバイスがオープンされており、インタフェースのアドレスが設定 されている状態) でなければ、 Fn read システムコールはエラー (Er EHOSTDOWN ) を返します。 インタフェースが ready 状態になった時、パケットが読み込み可能であれば Fn read はパケットを返します。読み込み可能でなければ、パケットが読み込めるまで ブロックするか Er EWOULDBLOCK を返します。どちらの動作になるのかは、非ブロッキング I/O モードが有効 にされているかどうかで決まります。 Fn read に渡されるバッファに許されているよりもパケットが長い場合には、超過分の データは黙って捨てられます。
オプション指定により、パケットがネットワークインタフェースの出力ルーチン (`tunoutput ' ) に与えられる際に、パケットの前に終点アドレスを付けるようにすることがで きます。 終点アドレスのフォーマットは、構造体 `sockaddr ' です。前に付いたアドレスの実際の長さは、構造体のメンバ `sa_len ' に格納されます。パケットのデータはこの直後に続けて置かれます。 write(2) システムコールの呼び出しによりパケットをインタフェースに渡して、 仮想インタフェースがパケットを ``受信'' した状態にします。 Fn write システムコール 1 回の呼び出しで、ちょうど 1 つのパケットを与えます。 パケット長は Fn write に与えられたデータの量から決められます。 書き込みはブロックされません。パケットが一時的な理由 (例: バッファに利用できる容量が無い) で受け取られなかった場合には、パケットは黙って捨てられます。理由が 一時的なものでなかった場合 (例: パケットが大きすぎる) には、エラーが返されます。 ``リンク層 (link-layer) モード'' が有効 (後述の TUNSLMODE を参照 ) ならば、実際のパケットデータの前には、構造体 `sockaddr ' がなければなりません。 現在のドライバは `sa_family ' フィールドしか調べません。 以下の ioctl(2) 呼び出しがサポートされています (定義されている場所は Aq net/if_tun.h : )
制御デバイスは読み込みに対する select(2) もサポートしています。書き込みに対する select は必ず成功するので意味 がありません。なぜなら、書き込みは必ず非ブロッキングだからです。
最後のデータデバイスを閉じた時、デフォルトではインタフェースが停止 します Po ``ifconfig tun n down '' が実行されたのと同様になります Pc 。 キューに入っているパケットは全て捨てられます (データデバイスがオープンされていない時にインタフェースが動作している 場合、出力パケットは蓄積されないで、常に捨てられます)。