Je tente de créer un module python pour obtenir les paramètres réseau. J'utilise des ctypes et j'ai quelques problèmes.Problème avec l'utilisation de l'API Win32 IPHelper en python
Fonction __getInterfaces_win2k() fonctionne avec Python 2.5 et 2.6, mais ne fonctionne pas avec Python 2.7 (exception non gérée à 0x1e001759 dans python.exe: 0xC0000005: emplacement lecture violation d'accès 0x00000010.)
Fonction __getInterfaces_win_after_win2k() ne fonctionne pas dans une version de python (même erreur).
Parfois, avant le programme d'écrasement, imprimez les informations nécessaires. J'ai essayé de comparer pratiquement toutes les valeurs avec le programme en C. Tout est normal. Toute aide très appréciée.
'''
Get different network parameters (interfaces, routing table, etc)
'''
from platform import system
from sys import getwindowsversion
def getInterfaces():
if system() == 'Windows':
winversion = getwindowsversion()
#from table on page OSVERSIONINFO Structure for GetVersionEx Function
if winversion[0] > 5 or (winversion[0] == 5 and winversion[1] > 0):
return __getInterfaces_win_after_win2k()
else:
return __getInterfaces_win2k()
else:
pass
MAX_ADAPTER_ADDRESS_LENGTH = 8
def __getInterfaces_win_after_win2k():
import ctypes.wintypes
class HEADER_STRUCT(ctypes.Structure):
_fields_ = [
("Length", ctypes.c_ulong),
("IfIndex", ctypes.c_ulong)]
class HEADER_UNION(ctypes.Union):
_fields_ = [
("Alignment", ctypes.c_ulonglong),
("HEADER_STRUCT", HEADER_STRUCT)]
class SOCKADDR(ctypes.Structure):
_fields_ = [
("sa_family", ctypes.c_ushort),
("sa_data", ctypes.c_byte * 14)]
PSOCKADDR = ctypes.POINTER(SOCKADDR)
class SOCKET_ADDRESS(ctypes.Structure):
_fields_ = [
("pSockaddr", PSOCKADDR),
("iSockaddrLength", ctypes.c_int)]
class IP_ADAPTER_UNICAST_ADDRESS(ctypes.Structure):
pass
PIP_ADAPTER_UNICAST_ADDRESS = ctypes.POINTER(IP_ADAPTER_UNICAST_ADDRESS)
IP_ADAPTER_UNICAST_ADDRESS._fields_ = [
("length", ctypes.c_ulong),
("flags", ctypes.c_ulong),
("next", PIP_ADAPTER_UNICAST_ADDRESS),
("address", SOCKET_ADDRESS),
("prefixOrigin", ctypes.c_int),
("suffixOrigin", ctypes.c_int),
("dadState", ctypes.c_int),
("validLifetime", ctypes.c_ulong),
("preferredLifetime", ctypes.c_ulong),
("leaseLifetime", ctypes.c_ulong),
("onLinkPrefixLength", ctypes.c_byte)]
class IP_ADAPTER_ANYCAST_ADDRESS(ctypes.Structure):
pass
PIP_ADAPTER_ANYCAST_ADDRESS = ctypes.POINTER(IP_ADAPTER_ANYCAST_ADDRESS)
IP_ADAPTER_ANYCAST_ADDRESS._fields_ = [
("alignment", ctypes.c_ulonglong),
("next", PIP_ADAPTER_ANYCAST_ADDRESS),
("address", SOCKET_ADDRESS)]
class IP_ADAPTER_MULTICAST_ADDRESS(ctypes.Structure):
pass
PIP_ADAPTER_MULTICAST_ADDRESS = ctypes.POINTER(IP_ADAPTER_MULTICAST_ADDRESS)
IP_ADAPTER_MULTICAST_ADDRESS._fields_ = [
("alignment", ctypes.c_ulonglong),
("next", PIP_ADAPTER_MULTICAST_ADDRESS),
("address", SOCKET_ADDRESS)]
class IP_ADAPTER_DNS_SERVER_ADDRESS(ctypes.Structure):
pass
PIP_ADAPTER_DNS_SERVER_ADDRESS = ctypes.POINTER(IP_ADAPTER_DNS_SERVER_ADDRESS)
IP_ADAPTER_DNS_SERVER_ADDRESS._fields_ = [
("alignment", ctypes.c_ulonglong),
("next", PIP_ADAPTER_DNS_SERVER_ADDRESS),
("address", SOCKET_ADDRESS)]
class IP_ADAPTER_PREFIX(ctypes.Structure):
pass
PIP_ADAPTER_PREFIX = ctypes.POINTER(IP_ADAPTER_PREFIX)
IP_ADAPTER_PREFIX._fields_ = [
("alignment", ctypes.c_ulonglong),
("next", PIP_ADAPTER_PREFIX),
("address", SOCKET_ADDRESS),
("prefixLength", ctypes.c_ulong)]
class IP_ADAPTER_WINS_SERVER_ADDRESS(ctypes.Structure):
pass
PIP_ADAPTER_WINS_SERVER_ADDRESS = ctypes.POINTER(IP_ADAPTER_WINS_SERVER_ADDRESS)
IP_ADAPTER_WINS_SERVER_ADDRESS._fields_ = [
("alignment", ctypes.c_ulonglong),
("next", PIP_ADAPTER_WINS_SERVER_ADDRESS),
("address", SOCKET_ADDRESS)]
class IP_ADAPTER_GATEWAY_ADDRESS(ctypes.Structure):
pass
PIP_ADAPTER_GATEWAY_ADDRESS = ctypes.POINTER(IP_ADAPTER_GATEWAY_ADDRESS)
IP_ADAPTER_GATEWAY_ADDRESS._fields_ = [
("alignment", ctypes.c_ulonglong),
("next", PIP_ADAPTER_GATEWAY_ADDRESS),
("address", SOCKET_ADDRESS)]
#ifdef.h
class NET_LUID(ctypes.Structure):
_fields_ = [
("value", ctypes.c_ulonglong)]
class GUID(ctypes.Structure):
_fields_ = [
("data1", ctypes.wintypes.DWORD),
("data2", ctypes.wintypes.WORD),
("data3", ctypes.wintypes.WORD),
("data4", ctypes.c_byte * 8)]
MAX_DNS_SUFFIX_STRING_LENGTH = 256
class IP_ADAPTER_DNS_SUFFIX(ctypes.Structure):
pass
PIP_ADAPTER_DNS_SUFFIX = ctypes.POINTER(IP_ADAPTER_DNS_SUFFIX)
IP_ADAPTER_DNS_SUFFIX._fields_ = [
("next", PIP_ADAPTER_DNS_SUFFIX),
("string", ctypes.c_wchar * MAX_DNS_SUFFIX_STRING_LENGTH)]
class IP_ADAPTER_ADDRESSES(ctypes.Structure):
pass
PIP_ADAPTER_ADDRESSES = ctypes.POINTER(IP_ADAPTER_ADDRESSES)
MAX_DHCPV6_DUID_LENGTH = 130 #IPTypes.h
IP_ADAPTER_ADDRESSES._fields_ = [
("header", HEADER_UNION),
("next", PIP_ADAPTER_ADDRESSES),
("adapterName", ctypes.c_char_p),
("firstUnicastAddress", PIP_ADAPTER_UNICAST_ADDRESS),
("firstAnycastAddress", PIP_ADAPTER_ANYCAST_ADDRESS),
("firstMulticastAddress", PIP_ADAPTER_MULTICAST_ADDRESS),
("firstDnsServerAddress", PIP_ADAPTER_DNS_SERVER_ADDRESS),
("dnsSuffix", ctypes.c_wchar_p),
("description", ctypes.c_wchar_p),
("friendlyName", ctypes.c_wchar_p),
("physicalAddress", ctypes.c_ubyte * MAX_ADAPTER_ADDRESS_LENGTH),
("physicalAddressLength", ctypes.wintypes.DWORD),
("flags", ctypes.wintypes.DWORD),
("mtu", ctypes.wintypes.DWORD),
("ifType", ctypes.wintypes.DWORD),
("operStatus", ctypes.c_int),
("ipv6IfIndex", ctypes.wintypes.DWORD),
("zoneIndices", ctypes.wintypes.DWORD * 16),
("firstPrefix", PIP_ADAPTER_PREFIX),
("transmitLinkSpeed", ctypes.c_ulonglong),
("receiveLinkSpeed", ctypes.c_ulonglong),
("firstWinsServerAddress", PIP_ADAPTER_WINS_SERVER_ADDRESS),
("firstGatewayAddress", PIP_ADAPTER_GATEWAY_ADDRESS),
("ipv4Metric", ctypes.c_ulong),
("ipv6Metric", ctypes.c_ulong),
("luid", NET_LUID),#ifdef.h
("dhcpv4Server", SOCKET_ADDRESS),
("compartmentId", ctypes.c_uint32),#ifdef.h
("networkGuid", GUID),
("connectionType", ctypes.c_int),
("tunnelType", ctypes.c_int),
("dhcpv6Server", SOCKET_ADDRESS),
("dhcpv6ClientDuid", ctypes.c_byte * MAX_DHCPV6_DUID_LENGTH),
("dhcpv6ClientDuidLength", ctypes.c_ulong),
("dhcpv6Iaid", ctypes.c_ulong)]
GetAdaptersAddresses = ctypes.windll.iphlpapi.GetAdaptersAddresses
GetAdaptersAddresses.restype = ctypes.c_ulong
GetAdaptersAddresses.argtypes = [
ctypes.c_ulong, ctypes.c_ulong, ctypes.c_void_p,
PIP_ADAPTER_ADDRESSES, ctypes.POINTER(ctypes.c_ulong)]
outBufLen = ctypes.c_ulong(15000)
adapters = ctypes.pointer(IP_ADAPTER_ADDRESSES())
ctypes.resize(adapters, outBufLen.value)
from socket import AF_INET
GAA_FLAG_INCLUDE_PREFIX = ctypes.c_ulong(0x0010)
GetAdaptersAddresses(ctypes.c_ulong(AF_INET), GAA_FLAG_INCLUDE_PREFIX, None,
adapters, ctypes.byref(outBufLen))
a = adapters[0]
ifaces = {}
while a:
iface = {}
iface['desc'] = a.description
# iface['mac'] = ':'.join(["%02X" % part for part in a.address])
#
# adNode = a.ipAddressList
# iface['ip'] = []
# while True:
# ipAddr = adNode.ipAddress
# if ipAddr:
# iface['ip'].append((ipAddr, adNode.ipMask))
# if adNode.next:
# adNode = adNode.next.contents
# else:
# break
ifaces[a.adapterName] = iface
if a.next:
a = a.next.contents
else:
break
return ifaces
def __getInterfaces_win2k():
import ctypes.wintypes
MAX_ADAPTER_NAME_LENGTH = 256
MAX_ADAPTER_DESCRIPTION_LENGTH = 128
class IP_ADDR_STRING(ctypes.Structure):
pass
LP_IP_ADDR_STRING = ctypes.POINTER(IP_ADDR_STRING)
IP_ADDR_STRING._fields_ = [
("next", LP_IP_ADDR_STRING),
("ipAddress", ctypes.c_char * 16),
("ipMask", ctypes.c_char * 16),
("context", ctypes.wintypes.DWORD)]
class IP_ADAPTER_INFO (ctypes.Structure):
pass
LP_IP_ADAPTER_INFO = ctypes.POINTER(IP_ADAPTER_INFO)
IP_ADAPTER_INFO._fields_ = [
("next", LP_IP_ADAPTER_INFO),
("comboIndex", ctypes.wintypes.DWORD),
("adapterName", ctypes.c_char * (MAX_ADAPTER_NAME_LENGTH + 4)),
("description", ctypes.c_char * (MAX_ADAPTER_DESCRIPTION_LENGTH + 4)),
("addressLength", ctypes.c_uint),
("address", ctypes.c_ubyte * MAX_ADAPTER_ADDRESS_LENGTH),
("index", ctypes.wintypes.DWORD),
("type", ctypes.c_uint),
("dhcpEnabled", ctypes.c_uint),
("currentIpAddress", LP_IP_ADDR_STRING),
("ipAddressList", IP_ADDR_STRING),
("gatewayList", IP_ADDR_STRING),
("dhcpServer", IP_ADDR_STRING),
("haveWins", ctypes.c_uint),
("primaryWinsServer", IP_ADDR_STRING),
("secondaryWinsServer", IP_ADDR_STRING),
("leaseObtained", ctypes.c_ulong),
("leaseExpires", ctypes.c_ulong)]
GetAdaptersInfo = ctypes.windll.iphlpapi.GetAdaptersInfo
GetAdaptersInfo.restype = ctypes.wintypes.DWORD
GetAdaptersInfo.argtypes = [LP_IP_ADAPTER_INFO, ctypes.POINTER(ctypes.c_ulong)]
adapters = ctypes.pointer(IP_ADAPTER_INFO())
buflen = ctypes.c_ulong(ctypes.sizeof(IP_ADAPTER_INFO))
GetAdaptersInfo(adapters, ctypes.byref(buflen))
ctypes.resize(adapters, buflen.value)
GetAdaptersInfo(adapters, ctypes.byref(buflen))
a = adapters.contents
ifaces = {}
while a:
iface = {}
iface['desc'] = a.description
iface['mac'] = ':'.join(["%02X" % part for part in a.address])
adNode = a.ipAddressList
iface['ip'] = []
while True:
ipAddr = adNode.ipAddress
if ipAddr:
iface['ip'].append((ipAddr, adNode.ipMask))
if adNode.next:
adNode = adNode.next.contents
else:
break
ifaces[a.adapterName] = iface
if a.next:
a = a.next.contents
else:
break
return ifaces
if __name__ == "__main__":
ifaces = getInterfaces()
for k, v in ifaces.iteritems():
print k
for k2, v2 in v.iteritems():
print '\t', k2, v2
NET_LUID est l'union de "ULONG64 Value" et "struct Info". Pour la simplicité, je le définis comme "valeur ULONG64". –