[Armadillo:04619] Re: TUN/TAPのインストール方法をお教えください。

joshua45 email@hidden
2009年 9月 28日 (月) 16:26:43 JST


お世話になっております。
On 2009/09/28, at 12:24, Yasushi SHOJI wrote:

> いくつか質問させてください。
>
> At Sat, 26 Sep 2009 15:55:39 +0900,
> joshua45 wrote:
>>
>> まず、どうもディバイス名はtun0ではなくtunl0となる
>> ようです。これでifconfig は出来る状態になりました。
>> これは、mknod等をしなくても可能です。
>
> - mknod等に、open(2)は含まれます?

明示的にmknodする方法では、
これはコマンドラインから打ちました。シェルのコマンドです。
      mkdir /dev/net
      mknod /dev/net/tun c 10 200

という具合です。udevを利用する場合は、例のファイルに前 
メールのように記述したということです。

> - device node は、/dev以下ですか、それとも /dev/ 
> net以下ですか?
> - device driverを load しなくても device nodeは 
> 存在しますか?
>

ディバイスを一時的にロードしないようにするのはどうしたら良い 
でしょうか。
予想としてはロードしなくても、上記の処理をすれば、ディバイス 
ノードは存在しているのではないかと思われます。

>> 1. なにもしないでTUNを使ったアプリケーションをどうささ
>> せた場合
>>
>> open("/dev/net/tun",O_RDWR);
>> で、
>> No such file or directory ...
>> となります。
>
> 「なにも」というのは、
>
>  - mknod?
>  - insmod?

これは、ディバイスをインストールしただけでその他の作業はしな 
い、という状態です。mknod,insmodもudevの設定もし 
ない状態で、
デバイスのロード後、
Cのプログラムでopen("/dev....");だけを行うということです。


>
>> 2. 手動で/dev/net/tunを作る方法
>> ドキュメンテーションにある通り手動で、
>> mknod /dev/net/tun c 10 100
>> を行ってみましたところ、openは成功しますが、その後の
>> ioctlでInvalid argument になります。x86 linux上で
>> はうまくいっているコードなので、ioctlの引数がarm 
>> と他の
>> linuxで異なるとかあるのかどうか....。
>
> /dev/net/tunl0 にすると正しく動くが、上記の方法では
> 動かないということですか?

open("/dev/net/tunl0"...)ははねられています。あ、でも、
open("/dev/net/tunl",....)は確かめていません。これはやる価値 
があるかもしれません。

>
>> 3. udevを使う方法
>> 以前のyashiさんのメールに従って、udevに/dev/
>> net(ディレクトリ)と/dev/net/tun を追加しました。
>>
>> /dev/net           d      755    0     0     -       -       -
>> -     -
>> /dev/net/tun       c      755    0     0     10      200     -
>> -     -
>>
>> これでカーネルとromfsを再ロードしました。なぜかカーネルと
>> romfsのセットを2セットロードするとちゃんと見えるようになりまし
>> た....。
>>
>> これでアプリケーションを動かすとopenのところで、
>> No such device
>> というエラーが出ます。No such file or directory とはな
>> らないのは、/dev/net/tunが一応デバイスとして登録されて
>> いるということなのか?
>
> どこかで、ENOENTではなく ENODEVが戻っているとい 
> うことなのですが‥。
>

open("/dev/net/tun",...)で戻ってきていることは確かめています。

> mknod(1)しても udevが mknod(2)をしても挙動が異 
> なることは無いはずです。

そう思うんですが.....。

> ifconfigが成功する場合と、しない上記の3つの方法では、 
> 名前が tunlとなる
> こと以外、違いはありませんか?

いや、いずれもifconfig tunl0 は成功します。また、いずれ 
も、ifconfig tun0 は成功しません。

まずはちょっと、
open("/dev/net/tunl",....)
これを確かめてみます。

森 ひろひさ


==============================
参考までに使っているアプリケーションのコードです。基本的にTUN/TAP 
のホームページからとってきた物なので、GPLでしょう。

これを、
tun_open_common("tunl0",1)
で呼び出しています。
最初にopen("/dev/net/tun")が呼び出されエラーがでる 
と、open("/dev/tunl0")が呼び出されるようになっています 
が、多分これはエラーになるでしょう。
どこでエラーになったかは、その都度fprintfが入っているの 
でこれでわかるようになっています。


/*
     VTun - Virtual Tunnel over TCP/IP network.

     Copyright (C) 1998-2000  Maxim Krasnyansky <email@hidden>

     VTun has been derived from VPPP package by Maxim Krasnyansky.

     This program is free software; you can redistribute it and/or  
modify
     it under the terms of the GNU General Public License as published  
by
     the Free Software Foundation; either version 2 of the License, or
     (at your option) any later version.

     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
*/

/*
  * $Id: tun_dev.c,v 1.4 2006/12/11 10:45:35 mtbishop Exp $
  */


#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include <errno.h>

#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/if.h>

#include "vtun.h"
#include "lib.h"

/*
  * Allocate TUN device, returns opened fd.
  * Stores dev name in the first arg(must be large enough).
  */
static int tun_open_common0(char *dev, int istun)
{
   char tunname[14];
   int i, fd, err;

   if( *dev ) {
     sprintf(tunname, "/dev/%s", dev);
     return open(tunname, O_RDWR);
   }

   sprintf(tunname, "/dev/%s", istun ? "tun" : "tap");
   err = 0;
   for(i=0; i < 255; i++){
     sprintf(tunname + 8, "%d", i);
     /* Open device */
     if( (fd=open(tunname, O_RDWR)) > 0 ) {
       strcpy(dev, tunname + 5);
       return fd;
     }
     else if (errno != ENOENT)
       err = errno;
     else if (i)/* don't try all 256 devices */
       break;
   }
   if (err)
     errno = err;
   return -1;
}

#ifdef LINUX
#include <linux/if_tun.h>
#endif
#ifdef LINUX_ARM
#include </usr/include/linux/if_tun.h>
#endif

#ifndef OTUNSETNOCSUM
/* pre 2.4.6 compatibility */
#define OTUNSETNOCSUM  (('T'<< 8) | 200)
#define OTUNSETDEBUG   (('T'<< 8) | 201)
#define OTUNSETIFF     (('T'<< 8) | 202)
#define OTUNSETPERSIST (('T'<< 8) | 203)
#define OTUNSETOWNER   (('T'<< 8) | 204)
#endif

static int tun_open_common(char *dev, int istun)
{
   struct ifreq ifr;
   int fd;

   if ((fd = open("/dev/net/tun", O_RDWR)) < 0) {
     fprintf(stderr,"tun_open_common err\n");
     perror("open common");
     return tun_open_common0(dev, istun);
   }

   memset(&ifr, 0, sizeof(ifr));
   ifr.ifr_flags = (istun ? IFF_TUN : IFF_TAP) | IFF_NO_PI;
   if (*dev)
     strncpy(ifr.ifr_name, dev, IFNAMSIZ);

   if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
     if (errno == EBADFD) {
       /* Try old ioctl */
       if (ioctl(fd, OTUNSETIFF, (void *) &ifr) < 0)
	goto failed;
     } else
       goto failed;
   }

   strcpy(dev, ifr.ifr_name);
   return fd;

  failed:
   close(fd);
   return -1;
}


int tun_open(char *dev) { return tun_open_common(dev, 1); }
int tap_open(char *dev) { return tun_open_common(dev, 0); }

int tun_close(int fd, char *dev) { return close(fd); }
int tap_close(int fd, char *dev) { return close(fd); }

/* Read/write frames from TUN device */
int tun_write(int fd, char *buf, int len) { return write(fd, buf,  
len); }
int tap_write(int fd, char *buf, int len) { return write(fd, buf,  
len); }

int tun_read(int fd, char *buf, int len) { return read(fd, buf, len); }
int tap_read(int fd, char *buf, int len) { return read(fd, buf, len); }


-------------- next part --------------
HTMLの添付ファイルを保管しました...
URL: <http://lists.atmark-techno.com/pipermail/armadillo/attachments/20090928/b11bfec7/attachment.html>


armadillo メーリングリストの案内