Python2和Python3:完全相同的隧道在使用其中一个时表现不同

时间:2017-07-19 10:19:16

标签: python tunnel

我有两个脚本,一个用于Python 2,另一个用于Python 3。 目的是他们完全相同并生成完全相同的隧道。 但是,隧道在Python 2中接收和转发流量,但只接收并且不使用Python 3脚本转发完全相同的流量。

python 2中的代码是:

IFF_TUN       = 0x0001
TUNSETIFF     = 0x400454ca
TUN_FILE      = '/dev/net/tun'
CMD_IFCONFIG  = '/sbin/ifconfig'
CMD_ROUTE     = '/sbin/route'
DUMMY_PREFIX  = 'dead:dead:dead'

class NullLogHandler(logging.Handler):
    def emit(self, record):
        pass

class NetworkSideThread(threading.Thread):

    def __init__(self,username,lowpan,prefix,callbackActivity,callbackDisconnected):

        # record params
        self.username         = username
        self.lowpan           = lowpan
        self.prefix           = prefix
        self.callbackActivity = callbackActivity
        self.callbackDisconnected = callbackDisconnected

        # variables
        self.disconnectNow = False

        # logging
        self.log           = logging.getLogger(self.username+'_NetworkSideThread')
        if len(self.log.handlers)==0:
            self.log.setLevel(logging.DEBUG)
            self.log.addHandler(NullLogHandler())

        # create virtual interface
        self.virtualIf = os.open(TUN_FILE, os.O_RDWR)
        ifs = ioctl(self.virtualIf, TUNSETIFF, struct.pack("16sH", "tun%d", IFF_TUN))
        self.ifname = ifs[:16].strip(b"\x00")
        print('Created virtual interface '+self.ifname+'.'+'.')

        # configure IPv6 addresses of virtual interface
        os.system(CMD_IFCONFIG + ' ' + self.ifname + ' up')
        os.system(CMD_IFCONFIG + ' ' + self.ifname + ' inet6 add ' + self.prefix + '::1/64')
        os.system(CMD_IFCONFIG + ' ' + self.ifname + ' inet6 add fe80::1/64')
        print('Configured IPv6 address')

        # set static route
        os.system(CMD_ROUTE+' -A inet6 add ' + self.prefix + '::/64 dev ' + self.ifname)
        print('Set up static route.')

        # initialize parent class
        threading.Thread.__init__(self)

        # set thread name
        self.setName('NetworkSideThread for '+self.username)

        # thread daemon mode
        self.setDaemon(True)

在Python3中:

IFF_TUN       = 0x0001
TUNSETIFF     = 0x400454ca
TUN_FILE      = '/dev/net/tun'
CMD_IFCONFIG  = '/sbin/ifconfig'
CMD_ROUTE     = '/sbin/route'
DEV_NULL      = '/dev/null'
CMD_PING6     = 'ping6'
DUMMY_PREFIX  = 'dead:dead:dead'

class NullLogHandler(logging.Handler):
    def emit(self, record):
        pass

class NetworkSideThread(threading.Thread):

    def __init__(self,username,lowpan,prefix,callbackActivity,callbackDisconnected):

        # record params
        self.username         = username
        self.lowpan           = lowpan
        self.prefix           = prefix
        self.callbackActivity = callbackActivity
        self.callbackDisconnected = callbackDisconnected

        # variables
        self.disconnectNow = False

        # logging
        self.log           = logging.getLogger(self.username+'_NetworkSideThread')
        if len(self.log.handlers)==0:
            self.log.setLevel(logging.DEBUG)
            self.log.addHandler(NullLogHandler())

        # create virtual interface
        self.virtualIf = os.open(TUN_FILE, os.O_RDWR, mode=0o777)
        os.set_inheritable(self.virtualIf, True)
        tun_name = 'tun0'.encode()
        ifs = ioctl(self.virtualIf, TUNSETIFF, struct.pack("16sH", tun_name, IFF_TUN))
        self.ifname = tun_name.decode
        print('Created virtual interface '+self.ifname+'.'+'.')

        # configure IPv6 addresses of virtual interface
        os.system(CMD_IFCONFIG + ' ' + self.ifname + ' up')
        os.system(CMD_IFCONFIG + ' ' + self.ifname + ' inet6 add ' + self.prefix + '::1/64')
        os.system(CMD_IFCONFIG + ' ' + self.ifname + ' inet6 add fe80::1/64')
        print('Configured IPv6 address')

        # set static route
        os.system(CMD_ROUTE+' -A inet6 add ' + self.prefix + '::/64 dev ' + self.ifname)
        print('Set up static route.')

        # initialize parent class
        threading.Thread.__init__(self)

        # set thread name
        self.setName('NetworkSideThread for '+self.username)

        # thread daemon mode
        self.setDaemon(True)

据我所知,他们都通过ifconfig查看了一个相同的tun0。 我注意到虽然通过os.open制作隧道时使用Python 2与Python 3(即9和17)返回相同路径的不同文件描述符。这看起来很奇怪,这是正常的吗?

如果这是无关的,有关如何解决此问题的任何建议吗?隧道看起来很相似,但不会做同样的事情!

1 个答案:

答案 0 :(得分:0)

我找到了答案。 问题不在于隧道,而在于如何将数据包写入隧道。

在将数据包写入隧道之前,我应该添加或不需要隧道头。

具体来说,使用IFF_TUN = 0x0001 | 0x1000并且没有为隧道头添加4B解决了这个问题。