这两天折腾 tun,之前完全没接触驱动这么底层的东西,全靠 GlacJAY 大大的这篇文章入门了。
一句话,参照此 gist,同时将TUNSETIFF = 0x400454ca
改为TUNSETIFF = -2147199798
即可。
那篇文章的代码在 Windows 和 Ubuntu 下都正常运行,但今天在路由器上运行时却报错了:
Traceback (most recent call last): …… File "/root/movpn/tun.py", line 218, in _open_tun fcntl.ioctl(tun, TUNSETIFF, ifr) IOError: [Errno 81] File descriptor in bad state
因为 vtun 运行正常,所以 tun 本身应该是没问题的。又测试了一下,这个错误在 ioctl 的request
不正确时出现。遂铺天盖地地寻找此值,发现不少相同遭遇,如这里,还有这,但没找到解决方案。
先去解了 ioctl,得知第二个参数是由好几个部分组成的,从 if_tun.h 找到了 ioctl.h,最后卡在一点C语言也不会,琢磨半天也没弄明白 TUNSETIFF 取值多少..
无奈,只好试着自己写段代码把 TUNSETIFF 打出来了..
之前只听说过 交叉编译 这个词,现在就要动手了好鸡冻,好在 OpenWrt 的相关资料很丰富:参照 wiki 以及 这篇帖子 外加一晚上时间终于完成了。
找了一个 C Hello Word 改了一下:
#include #include <linux/if_tun.h> #include <sys/ioctl.h> main() { printf("TUNSETNOCSUM = %d\n", TUNSETNOCSUM); printf("TUNSETDEBUG = %d\n", TUNSETDEBUG); printf("TUNSETIFF = %d\n", TUNSETIFF); printf("TUNSETPERSIST = %d\n", TUNSETPERSIST); printf("TUNSETOWNER = %d\n", TUNSETOWNER); printf("TUNSETLINK = %d\n", TUNSETLINK); printf("TUNSETGROUP = %d\n", TUNSETGROUP); } |
交叉编译:
xx@xx:~/openwrt/staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2$ \ bin/mips-openwrt-linux-gcc test.c |
上传路由器,执行:
TUNSETNOCSUM = -2147199800 TUNSETDEBUG = -2147199799 TUNSETIFF = -2147199798 TUNSETPERSIST = -2147199797 TUNSETOWNER = -2147199796 TUNSETLINK = -2147199795 TUNSETGROUP = -2147199794
OK,全出来了,话说为啥都是负数 = = 和 CPU 位宽整数长度啥的有关?换一个路由器是否还是这个值?
不知道,管用就行,Python 里TUNSETIFF = -2147199798
就好了。
P.s. 嘛其实回想起来也不复杂,就是编译 OpenWrt 略显蛋疼:经常在各种下载时卡住,挂VPN、断VPN,反复试。 有个 git clone 就是卡在 84% 死活过不去,最后把 git:// 改成 https:// 才好..
我是从gist顺着链接过来
广告起作用了(误
对了 http://glacjay.is-a-geek.org/blog/archives/308 这个404了怎么办
感谢提醒,链接已更新。
我也是顺着gist来的。。。。。。
求助另一个问题,https://gist.github.com/glacjay/586892 这个gist tun-ping-win.py, 中的 adapter_key ,我的机器中,没有 tun0801,但有个 tap0901,已安装openvpn,且配置为 tun模式。。。
怎样才能运行这个gist里的脚本,需要装什么依赖么?
0901 是版本号,没问题。需要 PyWin32 吧。