python实现tun/tap虚拟设备
2017-03-13 22:13
253 查看
工作中用到了使用tap/tun设备实现虚拟网络,看到网上的例子都是用C实现的。便想试着用python实现一把,主要就是要重新用ctypes定义相关的结构定义。
代码github地址:
https://github.com/happyAnger6/network_programming
这个git库里会不断的用python实现网络相关的编程。
if_tun.py: 主要是相关结构体定义。
ioctl_def.py:主要是ioctl命令字相关定义:
tun_oper.py:创建tun设备并监听数据发送请求.
测试:
为tun3设备设置ip:
#ifconfig tun3 10.0.0.1 up
添加静态路由,通过tun3转发:
#route add -net 10.0.0.2 netmask 255.255.255.255 dev tun3
ping一个地址向tun3发送数据:
#ping 10.0.0.2
tun3收到了数据:
read size:88
read size:88
read size:88
read size:88
read size:88
read size:88
read size:88
read size:88
代码github地址:
https://github.com/happyAnger6/network_programming
这个git库里会不断的用python实现网络相关的编程。
if_tun.py: 主要是相关结构体定义。
import ctypes import ioctl_def TUNSETIFF=ioctl_def._IOW(ord('T'), 202, ctypes.c_int) IFF_TUN=1 IFF_TAP=2 IFNAMSIZ=16 class SockAddr(ctypes.Structure): _fields_=[("sa_family",ctypes.c_ushort), ("sa_data",ctypes.c_char*14)] class IfMap(ctypes.Structure): _fields_=[("mem_start", ctypes.c_ulong), ("mem_end", ctypes.c_ulong), ("base_addr", ctypes.c_ushort), ("irq", ctypes.c_char), ("dma", ctypes.c_char), ("port", ctypes.c_char)] class Ifs_Ifsu(ctypes.Union): _fields_=[("raw_hdlc", ctypes.c_void_p), ("cisco", ctypes.c_void_p), ("fr", ctypes.c_void_p), ("fr_pvc", ctypes.c_void_p), ("fr_pvc_info", ctypes.c_void_p), ("sync", ctypes.c_void_p), ("te1", ctypes.c_void_p)] class IfSettings(ctypes.Structure): _fields_=[("type", ctypes.c_uint), ("size", ctypes.c_uint), ("ifs_ifsu", Ifs_Ifsu)] class Ifr_Ifru(ctypes.Union): _fields_=[("ifru_addr", SockAddr), ("ifru_dstaddr", SockAddr), ("ifru_broadaddr", SockAddr), ("ifru_netmask", SockAddr), ("ifru_hwaddr", SockAddr), ("ifru_flags", ctypes.c_ushort), ("ifru_ivalue", ctypes.c_int), ("ifru_mtu", ctypes.c_int), ("ifru_map", IfMap), ("ifru_slave", ctypes.c_char * IFNAMSIZ), ("ifru_newname", ctypes.c_char * IFNAMSIZ), ("ifru_data", ctypes.c_void_p), ("ifru_settings", IfSettings)] class Ifr_Ifrn(ctypes.Union): _fields_=[("ifrn_name", ctypes.c_char * IFNAMSIZ)] class IfReq(ctypes.Structure): _fields_=[("ifr_ifrn", Ifr_Ifrn), ("ifr_ifru", Ifr_Ifru)] if __name__ == "__main__": ifreq = IfReq() print(ctypes.sizeof(ifreq.ifr_ifrn)) print(ctypes.sizeof(ifreq.ifr_ifru))
ioctl_def.py:主要是ioctl命令字相关定义:
_IOC_NRBITS=8 _IOC_TYPEBITS=8 _IOC_SIZEBITS=14 _IOC_DIRBITS=2 _IOC_NRMASK=((1 << _IOC_NRBITS) - 1) _IOC_TYPEMASK=((1 << _IOC_TYPEBITS) - 1) _IOC_SIZEMASK=((1 << _IOC_SIZEBITS) - 1) _IOC_DIRMASK=((1 << _IOC_DIRBITS) - 1) _IOC_NRSHIFT=0 _IOC_TYPESHIFT=(_IOC_NRSHIFT + _IOC_NRBITS) _IOC_SIZESHIFT=(_IOC_TYPESHIFT + _IOC_TYPEBITS) _IOC_DIRSHIFT=(_IOC_SIZESHIFT + _IOC_SIZEBITS) _IOC_NONE=0 _IOC_WRITE=1 _IOC_READ=2 def _IOC(dir, type, nr, size): return (((dir) << _IOC_DIRSHIFT) | \ ((type) << _IOC_TYPESHIFT) | \ ((nr) << _IOC_NRSHIFT) | \ ((size) << _IOC_SIZESHIFT)) import ctypes def _IOC_TYPECHECK(t): return ctypes.sizeof(t) def _IO(type, nr): return _IOC(_IOC_NONE, type, nr, 0) def _IOR(type, nr, size): return _IOC(_IOC_READ, type, nr, _IOC_TYPECHECK(size)) def _IOW(type, nr, size): return _IOC(_IOC_WRITE, type, nr, _IOC_TYPECHECK(size)) if __name__ == "__main__": print(_IOC_TYPESHIFT,_IOC_SIZESHIFT,_IOC_DIRSHIFT) print(_IOC())
tun_oper.py:创建tun设备并监听数据发送请求.
import fcntl import os import ctypes import struct from if_tun import IfReq, TUNSETIFF, IFF_TUN def tun_create(devname, flags): fd = -1 if not devname: return -1 fd = os.open("/dev/net/tun", os.O_RDWR) if fd < 0: print("open /dev/net/tun err!") return fd r=IfReq() ctypes.memset(ctypes.byref(r), 0, ctypes.sizeof(r)) r.ifr_ifru.ifru_flags |= flags r.ifr_ifrn.ifrn_name = devname.encode('utf-8') try: err = fcntl.ioctl(fd, TUNSETIFF, r) except Exception as e: print("err:",e) os.close(fd) return -1 return fd if __name__ == "__main__": fd = tun_create("tun3", IFF_TUN) if fd < 0: raise OSError MAXSIZE=4096 while(True): buf = os.read(fd,MAXSIZE) if not buf: break print("read size:%d" % len(buf))
测试:
为tun3设备设置ip:
#ifconfig tun3 10.0.0.1 up
添加静态路由,通过tun3转发:
#route add -net 10.0.0.2 netmask 255.255.255.255 dev tun3
ping一个地址向tun3发送数据:
#ping 10.0.0.2
tun3收到了数据:
read size:88
read size:88
read size:88
read size:88
read size:88
read size:88
read size:88
read size:88