【问题标题】:Python2 and Python3: exact same tunnel behaves differently when using one or the otherPython2 和 Python3:完全相同的隧道在使用其中一个时表现不同
【发布时间】:2017-07-19 10:19:16
【问题描述】:

我有两个脚本,一个用于 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)

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

如果这无关紧要,关于如何解决此问题的任何建议?隧道看起来一模一样,但做的不一样!

【问题讨论】:

    标签: python tunnel


    【解决方案1】:

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

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

    具体来说,使用 IFF_TUN = 0x0001 | 0x1000 并且不为隧道头添加 4B 可以解决问题。

    【讨论】:

      猜你喜欢
      • 2018-11-26
      • 2017-06-20
      • 2017-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多