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设备无法使用