QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 3752|回复: 3

universal tun/tap driver 写入问题

[复制链接]
发表于 2006-7-23 15:25:51 | 显示全部楼层 |阅读模式
打开tun设备;
配置tun(/sbin/ifconfig tun0 10.8.0.2 pointopoint 10.8.0.1 mtu 1500)
执行 ifconfig 显示配置后的网卡信息;
向tun写入一个ping包.

在RedHat下运行无事;在uClinux下运行,写IP包时程序死。程序与运行结果见下,谁能帮忙???

程序:
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdio.h>
#include <linux/if_tun.h>
#include <net/if.h>
#include <stdarg.h>

/* Path to ifconfig tool */
#define IFCONFIG_PATH "/sbin/ifconfig"

void set_nonblock (int fd);
int open_tun (const char *dev, char **actual);
int openvpn_snprintf(char *str, size_t size, const char *format, ...);

int
main (void)
{
        char *actualname = NULL;
        char command_line[256];
        char *ifconfig_local = "10.8.0.2";
        char *ifconfig_remote = "10.8.0.1";
        int tun_mtu = 1500;
                // 10.8.0.1 ping 10.8.0.2 的一个ping 包
        char packet[] = {0x45,0x00,0x00,0x3c,0x75,0xb5,0x00,0x00,0x80,0x01,
                0xb0,0xf9,0x0a,0x08,0x00,0x01,0x0a,0x08,0x00,0x02,
                0x08,0x00,0x1e,0x5c,0x03,0x00,0x2c,0x00,0x61,0x62,
                0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,
                0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,
                0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69};
        const int packetlen = sizeof(packet)/sizeof(char);
        int tuntapfd;
        int i;

        tuntapfd = open_tun ("tun", &actualname);
        openvpn_snprintf (command_line, sizeof (command_line),
                          IFCONFIG_PATH " %s %s pointopoint %s mtu %d",
                          actualname,
                          ifconfig_local,
                          ifconfig_remote,
                          tun_mtu
                          );
        printf ("%s\n", command_line);
        system (command_line);  //执行command
        system ("ifconfig");
        for (i=0; i<packetlen; i++)
        {
                printf ("0x%.2x,", packet);
        }
        printf ("\n");
        write (tuntapfd, packet, packetlen); //向tun写入ping包
        free (actualname);
        return 0;
}

int open_tun (const char *dev, char **actual)
{
  struct ifreq ifr;
  int fd;

  char *device = "/dev/tun"; //uClinux下tun设备的路径
  //char *device = "/dev/net/tun"; //RedHat下tun设备的路径
  int size;

  if ((fd = open (device, O_RDWR)) < 0) //创建描述符
  {
    printf ("Cannot open TUN/TAP dev %s\n", device);
    exit();
  }
  memset (&ifr, 0, sizeof (ifr));
  ifr.ifr_flags = IFF_NO_PI;
  if (!strncmp (dev, "tun", 3)) {
      ifr.ifr_flags |= IFF_TUN;
  }
  else if (!strncmp (dev, "tap", 3)) {
      ifr.ifr_flags |= IFF_TAP;
  }
  else {
    printf ("I don't recognize device %s as a TUN or TAP device\n",dev);
    exit();
  }
  if (strlen (dev) > 3) //unit number specified?
    strncpy (ifr.ifr_name, dev, IFNAMSIZ);
  if (ioctl (fd, TUNSETIFF, (void *) &ifr) < 0) //打开虚拟网卡
  {
    printf ("Cannot ioctl TUNSETIFF %s\n", dev);
    exit();
  }
  set_nonblock (fd);
  printf ("TUN/TAP device %s opened\n", ifr.ifr_name);
  size = strlen(ifr.ifr_name)+1;
  *actual = (char *) malloc (size);
  memcpy (*actual, ifr.ifr_name, size);
  return fd;
}

/* Set a file descriptor to non-blocking */
void
set_nonblock (int fd)
{
  if (fcntl (fd, F_SETFL, O_NONBLOCK) < 0)
    printf ("Set file descriptor to non-blocking mode failed\n");
}

/*
* This is necessary due to certain buggy implementations of snprintf,
* that don't guarantee null termination for size > 0.
*/
int openvpn_snprintf(char *str, size_t size, const char *format, ...)
{
  va_list arglist;
  int ret = 0;
  if (size > 0)
    {
      va_start (arglist, format);
      ret = vsnprintf (str, size, format, arglist);
      va_end (arglist);
      str[size - 1] = 0;
    }
  return ret;
}

RedHat下运行结果:
TUN/TAP device tun0 opened
/sbin/ifconfig tun0 10.8.0.2 pointopoint 10.8.0.1 mtu 1500
eth0      Link encap:Ethernet  HWaddr 00:0C:6E:B8:14:1C  
          inet addr:192.168.0.1  Bcast:192.168.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:5751317 errors:0 dropped:0 overruns:0 frame:0
          TX packets:192457 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100
          RX bytes:2313894496 (2206.7 Mb)  TX bytes:82363908 (78.5 Mb)
          Interrupt:10

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:11332180 errors:0 dropped:0 overruns:0 frame:0
          TX packets:11332180 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:775516557 (739.5 Mb)  TX bytes:775516557 (739.5 Mb)

tun0      Link encapoint-to-Point Protocol  
          inet addr:10.8.0.2  P-t-P:10.8.0.1  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:10
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

0x45,0x00,0x00,0x3c,0x75,0xffffffb5,0x00,0x00,0xffffff80,0x01,0xffffffb0,
0xfffffff9,0x0a,0x08,0x00,0x01,0x0a,0x08,0x00,0x02,0x08,0x00,0x1e,
0x5c,0x03,0x00,0x2c,0x00,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,
0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,
0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,

uClinux下运行结果:
TUN/TAP device tun0 opened
/sbin/ifconfig tun0 10.8.0.2 pointopoint 10.8.0.1 mtu 1500
eth0      Link encap:Ethernet  HWaddr 00:40:95:36:35:34  
          inet addr:192.168.0.5  Bcast:192.168.0.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:438 errors:0 dropped:0 overruns:0 frame:0
          TX packets:90 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          Interrupt:17

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:12 errors:0 dropped:0 overruns:0 frame:0
          TX packets:12 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0

tun0      Link encap:UNSPEC  HWaddr 62-00-AC-DE-62-00-00-00-00-00-00-00-00-00-00-00  
          inet addr:10.8.0.2  P-t-P:10.8.0.1  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:10

0x45,0x00,0x00,0x3c,0x75,0xb5,0x00,0x00,0x80,0x01,0xb0,0xf9,0x0a,
0x08,0x00,0x01,0x0a,0x08,0x00,0x02,0x08,0x00,0x1e,0x5c,0x03,0x00,
0x2c,0x00,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,
0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,
0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
Unhandled fault: alignment exception (13) at 0x00000001
fault-common.c(97): start_code=0x610040, start_stack=0x61ff90)
Internal error: Oops: 0
CPU: 0
pc : [<000a9240>]    lr : [<0078e662>]    Not tainted
sp : 00759e58  ip : 0078e662  fp : 00759e88
r10: 002741a0  r9 : 00000a71  r8 : 00759ed8
r7 : 0029b880  r6 : 002d8440  r5 : 002d8440  r4 : 00000005
r3 : 00000045  r2 : 0000003c  r1 : 00000014  r0 : 00000005
Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  Segment kernel
Control: 0
Process uctun (pid: 24, stackpage=00759000)
Stack:
00759e40:                   0078e662 000a9240  20000013 ffffffff 00759e84 00759e68
00759e60: 0007b644 0007b074 00000010 002d8440  00000000 00000008 00000000 00759ea4
00759e80: 00759e8c 00098da8 000a90e4 002e782c  002741cc 002741ac 00759ed4 00759ea8
00759ea0: 00098eb4 00098b48 00000040 00274290  002741cc 002741a0 002741bc 00000a71
00759ec0: 60000013 00284f14 00759f00 00759ed8  00099034 00098e1c 0000012c 00274090
00759ee0: 00000001 fffffffb 00284b60 00000000  00274080 00759f2c 00759f04 0001ffc0
00759f00: 00098fac 002d8440 002e7800 0000003c  0000003c 0078e662 00000004 00759f6c
00759f20: 00759f3c 00759f30 00020078 0001ff18  00759f68 00759f40 00090730 00020074
00759f40: 00080000 0000003c 000113a0 ffffffea  00000000 0061fe10 006165c4 00759f80
00759f60: 00759f6c 0009077c 000905b4 0061fe4c  00000000 00759fac 00759f84 00030f18
00759f80: 00090768 000152b0 000150f8 00000000  00000000 0061ffa4 00758000 00014b00
00759fa0: 00000000 00759fb0 00014960 00030e4c  00000000 00015194 00000003 0061fe10
00759fc0: 0000003c 0061fe10 00000000 00000000  0061ffa4 00000001 0061ff9c 00000000
00759fe0: 006165c4 0061fdf4 0061fdf8 0061fde4  006101c4 0061259c 60000010 00000003
Backtrace:
Function entered at [<000a90d4>] from [<00098da8>]
r7 = 00000000  r6 = 00000008  r5 = 00000000  r4 = 002D8440
Function entered at [<00098b38>] from [<00098eb4>]
r6 = 002741AC  r5 = 002741CC  r4 = 002E782C
Function entered at [<00098e0c>] from [<00099034>]
Function entered at [<00098f9c>] from [<0001ffc0>]
Function entered at [<0001ff08>] from [<00020078>]
Function entered at [<00020064>] from [<00090730>]
Function entered at [<000905a4>] from [<0009077c>]
Function entered at [<00090758>] from [<00030f18>]
Function entered at [<00030e3c>] from [<00014960>]
r8 = 00014B00  r7 = 00758000  r6 = 0061FFA4  r5 = 00000000
r4 = 00000000
Code: e203400f e1a00004 (e49c2004) e49c1004 e2400005
Kernel panic: Aiee, killing interrupt handler

In interrupt handler - not syncing


运行结果不同之处:
1.  tun 网卡信息
Redhat
tun0      Link encapoint-to-Point Protocol  
uClinux
tun0      Link encap:UNSPEC  HWaddr 62-00-AC-DE-62-00-00-00-00-00-00-00-00-00-00-00  
2. 打印输出的IP包
RedHat下,以1开头的字节加上了ffff.
3. RedHat下未死,uClinux下死。

这是为什么????
 楼主| 发表于 2006-7-24 09:25:47 | 显示全部楼层

有人在uClinux下用过universal tun/tap

没有人在uClinux下用过universal tun/tap driver吗?
回复

使用道具 举报

发表于 2006-7-27 20:08:08 | 显示全部楼层
没有用过,不太清楚
回复

使用道具 举报

 楼主| 发表于 2006-8-18 08:37:58 | 显示全部楼层

问题解决

从网上搜到一篇文章,http://lkml.org/lkml/2005/3/18/146,照此修改tun.c, 问题解决。内容如下:

Hi!

This patch fixes an alignment-problem in tun_get_user: Only
ethernet-frames need to be headed by 2 bytes (due to their size of 14
bytes), IP-frames should not be touched. The patch changes
tun_get_user to reserve 2 bytes of the skb for TUN_TAP_DEVs and 0
bytes otherwise.

Ciao,
Sven

--- linux-2.6.11.2/drivers/net/tun.c        2005-03-09 09:11:32.000000000 +0100
+++ mylinux-2.6.11.2/drivers/net/tun.c        2005-03-18 18:19:02.906871952 +0100
@@ -226,7 +226,7 @@ static __inline__ ssize_t tun_get_user(s
{
        struct tun_pi pi = { 0, __constant_htons(ETH_P_IP) };
        struct sk_buff *skb;
-        size_t len = count;
+        size_t len = count, align = 0;

        if (!(tun->flags & TUN_NO_PI)) {
                if ((len -= sizeof(pi)) > len)
@@ -235,13 +235,17 @@ static __inline__ ssize_t tun_get_user(s
                if(memcpy_fromiovec((void *)&pi, iv, sizeof(pi)))
                        return -EFAULT;
        }
+
+        if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV)
+                align = NET_IP_ALIGN;
  
-        if (!(skb = alloc_skb(len + 2, GFP_KERNEL))) {
+        if (!(skb = alloc_skb(len + align, GFP_KERNEL))) {
                tun->stats.rx_dropped++;
                return -ENOMEM;
        }

-        skb_reserve(skb, 2);
+        if (align)
+                skb_reserve(skb, align);
        if (memcpy_fromiovec(skb_put(skb, len), iv, len))
                return -EFAULT;

-
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-4-23 19:00 , Processed in 0.102689 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表