现在的位置: 首页 > 综合 > 正文

关于 TUN/TAP 设备

2013年07月22日 ⁄ 综合 ⁄ 共 1851字 ⁄ 字号 评论关闭

长期以来对tun和tap这对兄弟分不太清,今天下定决心研究了一下代码,总算是搞明白了。

首先它们都是从/dev/net/tun里ioctl出来的虚拟设备,一个是通过IFF_TUN,另一个是 IFF_TAP。最好的例子莫过于vpnc里面的代码了。

C:

  1. int tun_open(char *dev, enum if_mode_enum
    mode)
  2. {
  3.         struct ifreq
    ifr;
  4.         int fd,
    err;
  5.  
  6.         if ((fd = open("/dev/net/tun",
    O_RDWR)) <0) {
  7.                 error(0,
    errno,
  8.                         "can't
    open /dev/net/tun, check that it is either device char 10 200 or (with DevFS) a symlink to ../misc/net/tun (not misc/net/tun)"
    );
  9.                 return -1;
  10.         }
  11.  
  12.         memset(&ifr, 0sizeof(ifr));
  13.         ifr.ifr_flags = ((mode == IF_MODE_TUN) ?
    IFF_TUN : IFF_TAP) |
    IFF_NO_PI;
  14.         if (*dev)
  15.                 strncpy(ifr.ifr_name,
    dev, IFNAMSIZ);
  16.  
  17.         if ((err = ioctl(fd,
    TUNSETIFF, (void *)&ifr)) <0) {
  18.                 close(fd);
  19.                 return err;
  20.         }
  21.         strcpy(dev,
    ifr.ifr_name);
  22.         return fd;
  23. }

用的ioctl的命令都是同一个TUNSETIFF。

虽然是出自一个娘,但它们仍然有大的不同。tun是点对点的设备,而tap是一个普通的以太网卡设备。也就是说,tun设备其实完全不需要有物理地址的!它收到和发出的包不需要arp,也不需要有数据链路层的头!而tap设备则是有完整的物理地址和完整的以太网帧。

用一个实际的例子来验证一下:

tap0    Link encap:Ethernet  HWaddr 0E:78:39:78:E7:A7
          inet addr:192.168.1.109  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::c78:39ff:fe78:e7a7/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:21 overruns:0 carrier:0
          collisions:0 txqueuelen:500
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

tun0    Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:X.X.X.X  P-t-P:X.X.X.X  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1412  Metric:1
          RX packets:6 errors:0 dropped:0 overruns:0 frame:0
          TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500
          RX bytes:690 (690.0 b)  TX bytes:402 (402.0 b)

% ethtool -i tun0
driver: tun
version: 1.6
firmware-version: N/A
bus-info: tun
% ethtool -i tap0
driver: tun
version: 1.6
firmware-version: N/A
bus-info: tap



继续回来看代码。还是vpnc的代码 tunip.c,看它发送的时候做了什么处理:

C:

抱歉!评论已关闭.