
Retrieve adapters by skipping multicast and IPv6 unicast addresses. Change-Id: I09d6e3593111c200a15f5713d6f4f676a3bcbb6a
183 lines
5.5 KiB
Python
183 lines
5.5 KiB
Python
# Copyright 2014 Cloudbase Solutions Srl
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import ctypes
|
|
|
|
from ctypes import windll
|
|
from ctypes import wintypes
|
|
|
|
from cloudbaseinit.utils.windows import kernel32
|
|
from cloudbaseinit.utils.windows import ws2_32
|
|
|
|
MAX_ADAPTER_NAME_LENGTH = 256
|
|
MAX_ADAPTER_DESCRIPTION_LENGTH = 128
|
|
MAX_ADAPTER_ADDRESS_LENGTH = 8
|
|
|
|
GAA_FLAG_SKIP_ANYCAST = 2
|
|
GAA_FLAG_SKIP_MULTICAST = 4
|
|
|
|
IP_ADAPTER_DHCP_ENABLED = 4
|
|
IP_ADAPTER_IPV4_ENABLED = 0x80
|
|
IP_ADAPTER_IPV6_ENABLED = 0x0100
|
|
|
|
MAX_DHCPV6_DUID_LENGTH = 130
|
|
|
|
IF_TYPE_ETHERNET_CSMACD = 6
|
|
IF_TYPE_SOFTWARE_LOOPBACK = 24
|
|
IF_TYPE_IEEE80211 = 71
|
|
IF_TYPE_TUNNEL = 131
|
|
|
|
IP_ADAPTER_ADDRESSES_SIZE_2003 = 144
|
|
|
|
|
|
class SOCKET_ADDRESS(ctypes.Structure):
|
|
_fields_ = [
|
|
('lpSockaddr', ctypes.POINTER(ws2_32.SOCKADDR)),
|
|
('iSockaddrLength', wintypes.INT),
|
|
]
|
|
|
|
|
|
class IP_ADAPTER_ADDRESSES_Struct1(ctypes.Structure):
|
|
_fields_ = [
|
|
('Length', wintypes.ULONG),
|
|
('IfIndex', wintypes.DWORD),
|
|
]
|
|
|
|
|
|
class IP_ADAPTER_ADDRESSES_Union1(ctypes.Union):
|
|
_fields_ = [
|
|
('Alignment', wintypes.ULARGE_INTEGER),
|
|
('Struct1', IP_ADAPTER_ADDRESSES_Struct1),
|
|
]
|
|
|
|
|
|
class IP_ADAPTER_UNICAST_ADDRESS(ctypes.Structure):
|
|
_fields_ = [
|
|
('Union1', IP_ADAPTER_ADDRESSES_Union1),
|
|
('Next', wintypes.LPVOID),
|
|
('Address', SOCKET_ADDRESS),
|
|
('PrefixOrigin', wintypes.DWORD),
|
|
('SuffixOrigin', wintypes.DWORD),
|
|
('DadState', wintypes.DWORD),
|
|
('ValidLifetime', wintypes.ULONG),
|
|
('PreferredLifetime', wintypes.ULONG),
|
|
('LeaseLifetime', wintypes.ULONG),
|
|
]
|
|
|
|
|
|
class IP_ADAPTER_DNS_SERVER_ADDRESS_Struct1(ctypes.Structure):
|
|
_fields_ = [
|
|
('Length', wintypes.ULONG),
|
|
('Reserved', wintypes.DWORD),
|
|
]
|
|
|
|
|
|
class IP_ADAPTER_DNS_SERVER_ADDRESS_Union1(ctypes.Union):
|
|
_fields_ = [
|
|
('Alignment', wintypes.ULARGE_INTEGER),
|
|
('Struct1', IP_ADAPTER_DNS_SERVER_ADDRESS_Struct1),
|
|
]
|
|
|
|
|
|
class IP_ADAPTER_DNS_SERVER_ADDRESS(ctypes.Structure):
|
|
_fields_ = [
|
|
('Union1', IP_ADAPTER_DNS_SERVER_ADDRESS_Union1),
|
|
('Next', wintypes.LPVOID),
|
|
('Address', SOCKET_ADDRESS),
|
|
]
|
|
|
|
|
|
class IP_ADAPTER_PREFIX_Struct1(ctypes.Structure):
|
|
_fields_ = [
|
|
('Length', wintypes.ULONG),
|
|
('Flags', wintypes.DWORD),
|
|
]
|
|
|
|
|
|
class IP_ADAPTER_PREFIX_Union1(ctypes.Union):
|
|
_fields_ = [
|
|
('Alignment', wintypes.ULARGE_INTEGER),
|
|
('Struct1', IP_ADAPTER_PREFIX_Struct1),
|
|
]
|
|
|
|
|
|
class IP_ADAPTER_PREFIX(ctypes.Structure):
|
|
_fields_ = [
|
|
('Union1', IP_ADAPTER_PREFIX_Union1),
|
|
('Next', wintypes.LPVOID),
|
|
('Address', SOCKET_ADDRESS),
|
|
('PrefixLength', wintypes.ULONG),
|
|
]
|
|
|
|
|
|
class NET_LUID_LH(ctypes.Union):
|
|
_fields_ = [
|
|
('Value', wintypes.ULARGE_INTEGER),
|
|
('Info', wintypes.ULARGE_INTEGER),
|
|
]
|
|
|
|
|
|
class IP_ADAPTER_ADDRESSES(ctypes.Structure):
|
|
_fields_ = [
|
|
('Union1', IP_ADAPTER_ADDRESSES_Union1),
|
|
('Next', wintypes.LPVOID),
|
|
('AdapterName', ctypes.c_char_p),
|
|
('FirstUnicastAddress',
|
|
ctypes.POINTER(IP_ADAPTER_UNICAST_ADDRESS)),
|
|
('FirstAnycastAddress',
|
|
ctypes.POINTER(IP_ADAPTER_DNS_SERVER_ADDRESS)),
|
|
('FirstMulticastAddress',
|
|
ctypes.POINTER(IP_ADAPTER_DNS_SERVER_ADDRESS)),
|
|
('FirstDnsServerAddress',
|
|
ctypes.POINTER(IP_ADAPTER_DNS_SERVER_ADDRESS)),
|
|
('DnsSuffix', wintypes.LPWSTR),
|
|
('Description', wintypes.LPWSTR),
|
|
('FriendlyName', wintypes.LPWSTR),
|
|
('PhysicalAddress', ctypes.c_ubyte * MAX_ADAPTER_ADDRESS_LENGTH),
|
|
('PhysicalAddressLength', wintypes.DWORD),
|
|
('Flags', wintypes.DWORD),
|
|
('Mtu', wintypes.DWORD),
|
|
('IfType', wintypes.DWORD),
|
|
('OperStatus', wintypes.DWORD),
|
|
('Ipv6IfIndex', wintypes.DWORD),
|
|
('ZoneIndices', wintypes.DWORD * 16),
|
|
('FirstPrefix', ctypes.POINTER(IP_ADAPTER_PREFIX)),
|
|
# kernel >= 6.0
|
|
('TransmitLinkSpeed', wintypes.ULARGE_INTEGER),
|
|
('ReceiveLinkSpeed', wintypes.ULARGE_INTEGER),
|
|
('FirstWinsServerAddress',
|
|
ctypes.POINTER(IP_ADAPTER_DNS_SERVER_ADDRESS)),
|
|
('FirstGatewayAddress',
|
|
ctypes.POINTER(IP_ADAPTER_DNS_SERVER_ADDRESS)),
|
|
('Ipv4Metric', wintypes.ULONG),
|
|
('Ipv6Metric', wintypes.ULONG),
|
|
('Luid', NET_LUID_LH),
|
|
('Dhcpv4Server', SOCKET_ADDRESS),
|
|
('CompartmentId', wintypes.DWORD),
|
|
('NetworkGuid', kernel32.GUID),
|
|
('ConnectionType', wintypes.DWORD),
|
|
('TunnelType', wintypes.DWORD),
|
|
('Dhcpv6Server', SOCKET_ADDRESS),
|
|
('Dhcpv6ClientDuid', ctypes.c_ubyte * MAX_DHCPV6_DUID_LENGTH),
|
|
('Dhcpv6ClientDuidLength', wintypes.ULONG),
|
|
('Dhcpv6Iaid', wintypes.ULONG),
|
|
]
|
|
|
|
GetAdaptersAddresses = windll.Iphlpapi.GetAdaptersAddresses
|
|
GetAdaptersAddresses.argtypes = [
|
|
wintypes.ULONG, wintypes.ULONG, wintypes.LPVOID,
|
|
ctypes.POINTER(IP_ADAPTER_ADDRESSES),
|
|
ctypes.POINTER(wintypes.ULONG)]
|
|
GetAdaptersAddresses.restype = wintypes.ULONG
|