mirror of
https://github.com/clinton-hall/nzbToMedia.git
synced 2024-11-14 17:40:24 -08:00
119 lines
3.9 KiB
Python
119 lines
3.9 KiB
Python
"""
|
|
Some routines for retrieving the addresses from the local
|
|
network config.
|
|
"""
|
|
|
|
import itertools
|
|
import ctypes
|
|
|
|
|
|
from jaraco.windows.api import errors, inet
|
|
|
|
|
|
def GetAdaptersAddresses():
|
|
size = ctypes.c_ulong()
|
|
res = inet.GetAdaptersAddresses(0, 0, None, None, size)
|
|
if res != errors.ERROR_BUFFER_OVERFLOW:
|
|
raise RuntimeError("Error getting structure length (%d)" % res)
|
|
print(size.value)
|
|
pointer_type = ctypes.POINTER(inet.IP_ADAPTER_ADDRESSES)
|
|
buffer = ctypes.create_string_buffer(size.value)
|
|
struct_p = ctypes.cast(buffer, pointer_type)
|
|
res = inet.GetAdaptersAddresses(0, 0, None, struct_p, size)
|
|
if res != errors.NO_ERROR:
|
|
raise RuntimeError("Error retrieving table (%d)" % res)
|
|
while struct_p:
|
|
yield struct_p.contents
|
|
struct_p = struct_p.contents.next
|
|
|
|
|
|
class AllocatedTable(object):
|
|
"""
|
|
Both the interface table and the ip address table use the same
|
|
technique to store arrays of structures of variable length. This
|
|
base class captures the functionality to retrieve and access those
|
|
table entries.
|
|
|
|
The subclass needs to define three class attributes:
|
|
method: a callable that takes three arguments - a pointer to
|
|
the structure, the length of the data contained by the
|
|
structure, and a boolean of whether the result should
|
|
be sorted.
|
|
structure: a C structure defininition that describes the table
|
|
format.
|
|
row_structure: a C structure definition that describes the row
|
|
format.
|
|
"""
|
|
|
|
def __get_table_size(self):
|
|
"""
|
|
Retrieve the size of the buffer needed by calling the method
|
|
with a null pointer and length of zero. This should trigger an
|
|
insufficient buffer error and return the size needed for the
|
|
buffer.
|
|
"""
|
|
length = ctypes.wintypes.DWORD()
|
|
res = self.method(None, length, False)
|
|
if res != errors.ERROR_INSUFFICIENT_BUFFER:
|
|
raise RuntimeError("Error getting table length (%d)" % res)
|
|
return length.value
|
|
|
|
def get_table(self):
|
|
"""
|
|
Get the table
|
|
"""
|
|
buffer_length = self.__get_table_size()
|
|
returned_buffer_length = ctypes.wintypes.DWORD(buffer_length)
|
|
buffer = ctypes.create_string_buffer(buffer_length)
|
|
pointer_type = ctypes.POINTER(self.structure)
|
|
table_p = ctypes.cast(buffer, pointer_type)
|
|
res = self.method(table_p, returned_buffer_length, False)
|
|
if res != errors.NO_ERROR:
|
|
raise RuntimeError("Error retrieving table (%d)" % res)
|
|
return table_p.contents
|
|
|
|
@property
|
|
def entries(self):
|
|
"""
|
|
Using the table structure, return the array of entries based
|
|
on the table size.
|
|
"""
|
|
table = self.get_table()
|
|
entries_array = self.row_structure * table.num_entries
|
|
pointer_type = ctypes.POINTER(entries_array)
|
|
return ctypes.cast(table.entries, pointer_type).contents
|
|
|
|
|
|
class InterfaceTable(AllocatedTable):
|
|
method = inet.GetIfTable
|
|
structure = inet.MIB_IFTABLE
|
|
row_structure = inet.MIB_IFROW
|
|
|
|
|
|
class AddressTable(AllocatedTable):
|
|
method = inet.GetIpAddrTable
|
|
structure = inet.MIB_IPADDRTABLE
|
|
row_structure = inet.MIB_IPADDRROW
|
|
|
|
|
|
class AddressManager(object):
|
|
@staticmethod
|
|
def hardware_address_to_string(addr):
|
|
hex_bytes = (byte.encode('hex') for byte in addr)
|
|
return ':'.join(hex_bytes)
|
|
|
|
def get_host_mac_address_strings(self):
|
|
return (
|
|
self.hardware_address_to_string(addr)
|
|
for addr in self.get_host_mac_addresses()
|
|
)
|
|
|
|
def get_host_ip_address_strings(self):
|
|
return itertools.imap(str, self.get_host_ip_addresses())
|
|
|
|
def get_host_mac_addresses(self):
|
|
return (entry.physical_address for entry in InterfaceTable().entries)
|
|
|
|
def get_host_ip_addresses(self):
|
|
return (entry.address for entry in AddressTable().entries)
|