Как взаимодействовать с Linux-драйвером tun - PullRequest
15 голосов
/ 17 июня 2009

Мне трудно разобраться в этой проблеме - я пытаюсь написать программу, которая будет взаимодействовать с драйвером туннеля 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 )

возвращает -1: приложение работает от имени пользователя root и все еще не может открыть это туннельное устройство. Можно открыть /dev/net/tun, однако это не создает нового устройства /dev/tunX для использования вместо него.

Итак, в заключение - как можно написать приложение, которое хочет использовать драйвер туннеля Linux? Любая идея будет принята с благодарностью.

Спасибо; ~ Роберт

Ответы [ 3 ]

14 голосов
/ 17 июня 2009

Чтение /usr/src/linux/Documentation/networking/tuntap.txt.

Вы должны open устройство /dev/net/tun. Последующее ioctl на открытом fd создаст сетевой интерфейс tun0 (или как вы хотите его назвать) Сетевые интерфейсы Linux не соответствуют ни одному устройству /dev/*.

12 голосов
/ 02 марта 2016

Нет файлов устройств /dev/tunX. Вместо этого вы открываете /dev/net/tun и настраиваете его через ioctl(), чтобы «указать» на tun0. Чтобы показать основную процедуру, я создам интерфейс TUN с помощью инструмента командной строки ip tun tap, а затем покажу код C для чтения с этого устройства TUN. Итак, чтобы создать интерфейс 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. Для чтения / записи пакетов на этот интерфейс из программы пространства пользователя вам нужно взаимодействовать с файлом устройства /dev/net/tun, используя ioctl(). Вот пример, который будет читать пакеты, поступающие на интерфейс 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;
}
2 голосов
/ 30 мая 2012

Я наткнулся на хороший вводный урок об этом

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

Поставляется с архивом исходного кода.

Это был тот же набор результатов Google, что и этот вопрос. :-)

...