質問

この問題を理解するのに苦労しています。Linuxトンネルドライバーと対話するプログラムを作成しようとしています。非常に基本的なレベルでは、ネットワークトンネルを介してデータを転送できるアプリケーションを作成するだけです。ただし、これを達成するためにトンネルドライバーを適切にセットアップする方法については完全に迷っています。

Ubuntu 9.04で開発しており、トンネルドライバーカーネルモジュールをロードしています。

デバイス / dev / net / tun は存在しますが、 / dev / tunX デバイスはありません。 ifconfig を使用してこれらのデバイスを作成できません。たとえば、 / sbin / ifconfig tun0 up を実行すると、次のエラーが発生します。

  

tun0:インターフェイスフラグの取得中にエラーが発生しました:そのようなデバイスはありません。

/ dev / net / tun デバイスを確認しようとすると、次のエラーが表示されます。

  

cat:/ dev / net / tun:不良状態のファイル記述子。

小さなプログラム、基本的には簡単なプログラムを介して / dev / tunX を開こうとする

tun_fd = open( "/dev/tun0", O_RDWR )

returns -1:アプリケーションはルートとして実行されており、このトンネルデバイスを開くことができません。 / dev / net / tun を開くことは可能ですが、代わりに使用する新しい / dev / tunX デバイスを生成するようには見えません。

では、要約すると、Linuxトンネルドライバーの使用を希望するアプリケーションをどのように作成しますか?洞察は大歓迎です。

ありがとう。 〜ロバート

役に立ちましたか?

解決

/usr/src/linux/Documentation/networking/tuntap.txt

/ dev / net / tun デバイスを open することになっています。開いているfdでの後続の ioctl は、 tun0 (または任意の名前)ネットワークインターフェイスを作成します。 Linuxのネットワークインターフェイスは、 / dev / * デバイスに対応していません。

他のヒント

/ dev / tunX デバイスファイルはありません。代わりに、 / dev / net / tun を開き、 ioctl()で" point"に設定します。 tun0 へ。基本的な手順を示すために、コマンドラインツール ip tun tap を使用してTUNインターフェイスを作成し、そのTUNデバイスから読み取るCコードを表示します。コマンドラインを使用してtunインターフェイスを作成するには、次のようにします。

sudo ip tuntap add mode tun dev tun0
ip addr add 10.0.0.0/24 dev tun0  # give it an ip
ip link set dev tun0 up  # bring the if up
ip route get 10.0.0.2  # check that packets to 10.0.0.x are going through tun0
ping 10.0.0.2  # leave this running in another shell to be able to see the effect of the next example

これで tun0 が作成されました。ユーザーインターフェイスプログラムからこのインターフェイスにパケットを読み書きするには、 ioctl()を使用して / dev / net / tun デバイスファイルと対話する必要があります。 tun0 インターフェースに到着したパケットを読み取り、サイズを出力する例を次に示します。

#include <fcntl.h>  /* O_RDWR */
#include <string.h> /* memset(), memcpy() */
#include <stdio.h> /* perror(), printf(), fprintf() */
#include <stdlib.h> /* exit(), malloc(), free() */
#include <sys/ioctl.h> /* ioctl() */

/* includes for struct ifreq, etc */
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/if.h>
#include <linux/if_tun.h>

int tun_open(char *devname)
{
  struct ifreq ifr;
  int fd, err;

  if ( (fd = open("/dev/net/tun", O_RDWR)) == -1 ) {
       perror("open /dev/net/tun");exit(1);
  }
  memset(&ifr, 0, sizeof(ifr));
  ifr.ifr_flags = IFF_TUN;
  strncpy(ifr.ifr_name, devname, IFNAMSIZ); // devname = "tun0" or "tun1", etc 

  /* ioctl will use ifr.if_name as the name of TUN 
   * interface to open: "tun0", etc. */
  if ( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) == -1 ) {
    perror("ioctl TUNSETIFF");close(fd);exit(1);
  }

  /* After the ioctl call the fd is "connected" to tun device specified
   * by devname ("tun0", "tun1", etc)*/

  return fd;
}


int main(int argc, char *argv[])
{
  int fd, nbytes;
  char buf[1600];

  fd = tun_open("tun0"); /* devname = ifr.if_name = "tun0" */
  printf("Device tun0 opened\n");
  while(1) {
    nbytes = read(fd, buf, sizeof(buf));
    printf("Read %d bytes from tun0\n", nbytes);
  }
  return 0;
}

このことについて素晴らしい入門チュートリアルを見つけました

http://backreference.org/2010/03/26/tuntap -interface-tutorial /

ソースtarballが付属しています。

この質問と同じGoogle結果セットに含まれていました。 :-)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top