OpenWrt 上使用 Python 操作 TAP/TUN

这两天折腾 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:// 才好..

OpenWrt 上使用 Python 操作 TAP/TUN》上有6条评论

  1. Sunday

    我也是顺着gist来的。。。。。。

    求助另一个问题,https://gist.github.com/glacjay/586892 这个gist tun-ping-win.py, 中的 adapter_key ,我的机器中,没有 tun0801,但有个 tap0901,已安装openvpn,且配置为 tun模式。。。

    怎样才能运行这个gist里的脚本,需要装什么依赖么?

    回复

发表评论

电子邮件地址不会被公开。 必填项已用*标注