2013年7月13日土曜日

pythonでTUN/TAPの中継する

TAPを2つ作ってその間を中継する。
以前はselectを使ってたけどasyncoreが便利。
29,30行目のoppositeに強引に送信関数を設定しているが、どうも美しくない。
どうすべきかなぁ

import fcntl
import struct
import asyncore

TUNSETIFF = 0x400454ca
IFF_TUN = 0x0001
IFF_TAP = 0x0002
IFF_NO_PI = 0x1000

class TunTap(asyncore.file_dispatcher):

    def __init__(self, ifname, flags):
        self.ifname = ifname
        self.fd = open('/dev/net/tun', 'r+b')
        ifr = struct.pack('16sH', ifname, flags)
        res = fcntl.ioctl(self.fd, TUNSETIFF, ifr)
        self.ifname = struct.unpack("16sH", res)[0].strip('\x00')
        asyncore.file_dispatcher.__init__(self, self.fd)

    def handle_read(self):
        self.opposite.send(self.recv(2048))

    def writable(self):
        return False

t1 = TunTap( 'tap1', IFF_TAP | IFF_NO_PI )
t2 = TunTap( 'tap2', IFF_TAP | IFF_NO_PI )

t1.opposite = t2
t2.opposite = t1

asyncore.loop()