1. 我的应用目标:

   为了把MPE封装的数据重新转化为网络UDP流,实现应用只要通过Socket接口即可实现数据接收和分析。

 

前言:

   为了实现这个功能,我在网络上搜索了相关信息,都没有具体的实现过程和应用,主要找到理论性的介绍tun/tap驱动的原理,而且很难让人理解它的功能。对于做实际开发的人员来说更需要的是一个实际实现的样例,这样更能说明问题,切实的解决应用实现问题。

 

2. tun/tap设备功能说明: 

 

    我这里着重说明Tun设备,当发的是广播或组播时,数据直接可以从虚拟网卡接收。

 

    虽然我在上图示例性的写上了10.10.10.2的ip地址,但其实不是使用ifconfig配置,就算你配置了也是无法实际使用的,而是使用route add 10.10.10.2 dev tun0配置的路由。

 

3. 下面举个实际的例子,详细的说明一下上述原理。

      Ping示例:该示例我是网上搜索到的,它主要功能是创建Tun0设备,然后一直读/dev/net/tun设备,并把read到的数据修改后write回去。运行该程序,配置上述所得route命令,然后运行ping 10.10.10.2。就可以发现示例不停的收到数据并写数据,而且ping也能正常的收到回馈。这样就形成了一个 tun设备read、write与socket收发的转化。

 

    ping   首先发送一个icmp包,该包的IP源地址是 192.168.203.132,目的地址是10.10.10.2,这样tun的read接口就可以读到一个IP包(45 00 开头),然后把IP包的源和目的ip进行交换后,write出去。这样就可以从真实网卡接收到icmp反馈的包。

 

综合测试代码附件地址:

 

4. 接着讲一下我的实际操作:

    --测试系统 ubuntu 8.10,默认已经安装了tun/tap

    --eth0配置:192.168.203.132,为什么用这么奇怪的ip?(呵呵vmware,nat配置后自动获取的)

    --附件中有三个测试程序、一个配置脚本及测试数据

    --tuntap.c 就是上述ping示例的代码,我做了改进,可以从文件读IP包write到tun设备。

    --udprecv.c是udp接收程序,也可以接收组播数据

    --sockraw.c是sock raw接收,可以接收icmp包,当然也可以接收原生udp包

 

    1). 进入目录make 生成测试程序

=测试1=============================

    2). 开启一个终端 sudo ./tuntap ping tun   (ping测试,创建tun设备)

    3). 再开启一个终端 sudo sh netconfig.sh   (网络设置)

    4). ping 10.10.10.2

    5). 查看两个窗口的信息

==============================

 

 

=测试2  UDP==========================

    2). 开启一个终端 sudo ./tuntap 10.10.10.2-192.168.203.132-20000.udp tun   (读对应数据,创建tun设备)

    3). 再开启一个终端 sudo sh netconfig.sh   (网络设置)

    4). ./udprecv 20000

    5). 查看窗口的信息,可以看到wwwww的打印信息

==============================

 

=测试3 ICMP==========================

    2). 开启一个终端 sudo ./tuntap 10.10.10.2-192.168.203.132.icmp tun   (读对应数据,创建tun设备)

    3). 再开启一个终端 sudo sh netconfig.sh   (网络设置)

    4). sudo ./sockraw icmp

    5). 查看窗口的信息,可以看到乱码及123456 的打印因为是raw接口会接收到包头,有一些不可打印字符

        你可以重定向到文件中,然后查看文件内容

==============================

 

5. 测试数据包源及目标地址的修改

     修改前请先查看一下IP包及UDP包的结构

00000000h: 45 00 00 60 73 46 00 00 80 11 27 0E 0A 0A 0A 02; E..`sF..€.'.....

00000010h: C0 A8 CB 84 EA 60 4E 20 00 4C D1 1F 77 77 77 77 ; 括藙阘N .L?wwww

00000020h: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 ; wwwwwwwwwwwwwwww

00000030h: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 ; wwwwwwwwwwwwwwww

00000040h: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 ; wwwwwwwwwwwwwwww

00000050h: 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 77 ; wwwwwwwwwwwwwwww

 

27 0E 是IP包有累加和

0A 0A 0A 02 源地址10.10.10.2

C0 A8 CB 84 目标地址192.168.203.132

 

修改了ip地址后,累加和会发生变化,需要重新计算,tuntap中已经包含了该代码,

修改完ip,请先把累加和清零

然后运行 sudo ./tuntap 10.10.10.2-192.168.203.132-20000.udp tun  

会打印ip head checksum=abcd (不到四位前面补零)

然后以cdab的顺序填入,重新运行,看到 checksum=0即可成功发送

 

 6. 对于组播的补充

     最近又确认了一下,可以接收组播包了,需要增加路由设置

     route add -net 224.0.0.0 netmask 224.0.0.0 dev tun0

 

7. 嵌入式平台和ubuntu上的对比测试的补充

    嵌入式系统,uclinux 2.4.26 arm7,编译时只要选择了tun/tap设备就可以了。

    有一个很奇怪的现象,相同的代码编译到两个平台运行,主要是组播的测试:

 

    嵌入式: tun设备无法使用

    ubuntu:tap设备无法使用

 

8. tun和tap的区别

   原理是一致的,主要就是Write的内容有所区别,但接收完全保持不变,

   tap设备基于以太层,所有包头包括以太帧,就在ip包前面加上14字节,目的mac+源mac+“0800”

   在嵌入式平台进行的组播测试中,发现Write的内容中两个mac地址和源ip地址可以不管,

   可以在任何网络上使用抓包软件保存的组播包不经任何修改就可以Write到tap设备使用了。

   所以虚拟网卡的ip地址也可以不用设置。只要执行

   ifconfig tap0 0.0.0.0 up

   route add -net 224.0.0.0 netmask 224.0.0.0 dev tun0

   上述两句后网络就配置完成了。

 

欢迎各位朋友沟通商讨问题,

 我的遗留问题

    嵌入式: tun设备无法使用

    ubuntu:tap设备无法使用