I'm attempting to create python module for getting network parameters. I'm using ctypes and has some problems.
Function __getInterfaces_win2k() works with python 2.5 and 2.6, but doesn't work with python 2.7 (Unhandled exception at 0x1e001759 in python.exe: 0xC0000005: Access violation reading location 0x00000010.)
Function __getInterfaces_win_after_win2k() doesn't work in any version of python (same error).
Sometimes, before the crash program print the necessary information. I've tried compare practically all values with program in C. Everything is normal. Any help much appreciated.
'''
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