Я пытаюсь создать модуль Python для получения параметров сети. Я использую ctypes и у меня есть некоторые проблемы.
Функция __getInterfaces_win2k () работает с python 2.5 и 2.6, но не работает с python 2.7 (необработанное исключение 0x1e001759 в python.exe: 0xC0000005: место чтения нарушения доступа 0x00000010.)
Функция __getInterfaces_win_after_win2k () не работает ни в одной версии python (та же ошибка).
Иногда перед сбоем программы выводят необходимую информацию. Я пробовал сравнить практически все значения с программой на C. Все нормально. Любая помощь высоко ценится.
'''
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