def get_ips_win():
    from ctypes import Structure, windll, sizeof
    from ctypes import POINTER, byref
    from ctypes import c_ulong, c_uint, c_ubyte, c_char, c_uint64, c_void_p

    time_t = c_uint64 if sizeof(c_void_p) == 8 else c_ulong

    MAX_ADAPTER_DESCRIPTION_LENGTH = 128
    MAX_ADAPTER_NAME_LENGTH = 256
    MAX_ADAPTER_ADDRESS_LENGTH = 8
    ERROR_BUFFER_OVERFLOW = 111

    class IP_ADDR_STRING(Structure):
        pass

    LP_IP_ADDR_STRING = POINTER(IP_ADDR_STRING)
    IP_ADDR_STRING._fields_ = [
        ("next", LP_IP_ADDR_STRING),
        ("ipAddress", c_char * 16),
        ("ipMask", c_char * 16),
        ("context", c_ulong),
    ]

    class IP_ADAPTER_INFO(Structure):
        pass

    LP_IP_ADAPTER_INFO = POINTER(IP_ADAPTER_INFO)
    IP_ADAPTER_INFO._fields_ = [
        ("next", LP_IP_ADAPTER_INFO),
        ("comboIndex", c_ulong),
        ("adapterName", c_char * (MAX_ADAPTER_NAME_LENGTH + 4)),
        ("description", c_char * (MAX_ADAPTER_DESCRIPTION_LENGTH + 4)),
        ("addressLength", c_uint),
        ("address", c_ubyte * MAX_ADAPTER_ADDRESS_LENGTH),
        ("index", c_ulong),
        ("type", c_uint),
        ("dhcpEnabled", c_uint),
        ("currentIpAddress", LP_IP_ADDR_STRING),
        ("ipAddressList", IP_ADDR_STRING),
        ("gatewayList", IP_ADDR_STRING),
        ("dhcpServer", IP_ADDR_STRING),
        ("haveWins", c_uint),
        ("primaryWinsServer", IP_ADDR_STRING),
        ("secondaryWinsServer", IP_ADDR_STRING),
        ("leaseObtained", time_t),
        ("leaseExpires", time_t),
    ]
    GetAdaptersInfo = windll.iphlpapi.GetAdaptersInfo
    GetAdaptersInfo.restype = c_ulong
    GetAdaptersInfo.argtypes = [LP_IP_ADAPTER_INFO, POINTER(c_ulong)]

    buffer_size = c_ulong(1)
    adapter_list = (IP_ADAPTER_INFO * 1)()
    res = GetAdaptersInfo(byref(adapter_list[0]), byref(buffer_size))

    if res == ERROR_BUFFER_OVERFLOW:
        adapter_list = (IP_ADAPTER_INFO * buffer_size.value)()
        res = GetAdaptersInfo(byref(adapter_list[0]), byref(buffer_size))

    if res != 0:
        return []

    ips = []
    for adapter in adapter_list:
        name = adapter.description.decode('utf-8')
        adapter_node = adapter.ipAddressList
        while True:
            ip_addr = adapter_node.ipAddress
            if ip_addr:
                ips.append((name, ip_addr.decode('utf-8')))
            adapter_node = adapter_node.next
            if not adapter_node:
                break
    return ips


def main():
    for addr in get_ips_win():
        print(addr)


if __name__ == '__main__':
    main()

输出示例:

('ZeroTier Virtual Port', '192.168.196.37')
('Hyper-V Virtual Ethernet Adapter', '172.21.128.1')
('VMware Virtual Ethernet Adapter for VMnet1', '192.168.135.1')
('VMware Virtual Ethernet Adapter for VMnet8', '192.168.16.1')
('VirtualBox Host-Only Ethernet Adapter', '192.168.56.1')
('Hyper-V Virtual Ethernet Adapter #2', '192.168.1.154')

  1. Finding local IP addresses using Python’s stdlib

发表回复

您的电子邮箱地址不会被公开。