首页 文章

从/ proc / net / tcp6解析IPv6地址(python 2.7)

提问于
浏览
2

我试图在Python 2.7中从 /proc/net/tcp6 读取 IPv6 addresses . 以下是 /proc/net/tcp6 中使用的IPv6表示示例:

00000000000000000000000000000000
00000000000000000000000001000000
0000000000000000FFFF00001F00C80A

我遇到的问题是将这些转换为“适当的”IPv6表示,如维基百科所述:

IPv6地址表示为八组四个十六进制数字,每组代表16位(两个八位字节) . 这些组用冒号(:)分隔 . IPv6地址的示例是:2001:0db8:85a3:0000:0000:8a2e:0370:7334
[...]示例地址可以进一步简化:2001:db8:85a3 :: 8a2e:370:7334

socket.inet_ntopstruct.pack的帮助下,这似乎最容易实现 .

但是,我不知道要采用哪些步骤来生成这两个函数所需的特定格式 .

使用Python 2.7 stdlib中的其他方法的任何其他方法当然都是受欢迎的 .


仅仅为了比较,这里's how I'正在为 IPv4 addresses 做这件事,从 /proc/net/tcp 读取:

>>> addr = '0101007F'
>>> addr = int(addr, 16)
>>> addr = struct.pack('<I', addr)
>>> addr = socket.inet_ntoa(addr)
>>> print addr
127.0.1.1

不幸的是 inet_ntoa 不支持IPv6地址,你必须使用 inet_ntop(AF_INET6, packed_ipv6) .

但是我不知道如何使用 struct.pack 函数将上面的字符串转换为 in6_addr 结构 .

2 回答

  • 0

    这是一种有效的方法,并自动处理本机字节序:

    def ipv6(addr):
        addr = addr.decode('hex')
        addr = struct.unpack('>IIII', addr)
        addr = struct.pack('@IIII', *addr)
        addr = socket.inet_ntop(socket.AF_INET6, addr)
        return addr
    

    样品:

    >>> ipv6('00000000000000000000000001000000')
    '::1'
    >>> ipv6('B80D01200000000067452301EFCDAB89')
    '2001:db8::123:4567:89ab:cdef'
    

    脚步:

    • 地址转换为字节字符串( decode('hex') ),

    • 拆分为4个切片,保持字节顺序不变( >IIII ),

    • 重新打包,每个切片都转换为本机字节顺序( @IIII ),

    • 传递给 socket.inet_ntop ,最终生成正确的IPv6表示

    systems that use little endian上,字节字符串将从 DCBA-HGFE-LKJI-PONM 转换为 ABCD-EFGH-IJKL-MNOP . 见 struct module的byte order notation .


    unpackpack 部分的替代品,但在我的系统上慢两倍,并且它不会自动处理本机字节序(假设这里是小端):

    addr = ''.join(addr[i:i+4][::-1] for i in range(0, 16, 4))
    
  • 1

    像这样的东西?

    from ipaddress import ip_address
    
    components = [line[i:i+4] for i in range(0, len(line), 4)]
    ipv6_string = ":".join(components)
    print(ip_address(ipv6_string))
    

相关问题