Skip to content

Instantly share code, notes, and snippets.

@blink1073
Created April 28, 2025 02:34
Show Gist options
  • Save blink1073/349f83fdccabd23aeeabcfd3583f8017 to your computer and use it in GitHub Desktop.
Save blink1073/349f83fdccabd23aeeabcfd3583f8017 to your computer and use it in GitHub Desktop.
import ctypes
import ctypes.wintypes
import socket
# Load necessary libraries
iphlpapi = ctypes.WinDLL('Iphlpapi.dll')
# Define necessary constants and flags
AF_UNSPEC = 0
GAA_FLAG_INCLUDE_PREFIX = 0x0010
ERROR_BUFFER_OVERFLOW = 111
ERROR_SUCCESS = 0
MAX_DNS_SUFFIX_STRING_LENGTH = 256
MAX_ADAPTER_DESCRIPTION_LENGTH = 128
MAX_ADAPTER_NAME_LENGTH = 256
# Define ctypes structures
class SOCKADDR(ctypes.Structure):
_fields_ = [
("sa_family", ctypes.wintypes.USHORT),
("sa_data", ctypes.wintypes.BYTE * 14),
]
class SOCKET_ADDRESS(ctypes.Structure):
_fields_ = [
("lpSockaddr", ctypes.POINTER(SOCKADDR)),
("iSockaddrLength", ctypes.wintypes.INT),
]
class IP_ADAPTER_DNS_SERVER_ADDRESS(ctypes.Structure):
pass
LP_IP_ADAPTER_DNS_SERVER_ADDRESS = ctypes.POINTER(IP_ADAPTER_DNS_SERVER_ADDRESS)
IP_ADAPTER_DNS_SERVER_ADDRESS._fields_ = [
("Length", ctypes.wintypes.ULONG),
("Reserved", ctypes.wintypes.DWORD),
("Next", LP_IP_ADAPTER_DNS_SERVER_ADDRESS),
("Address", SOCKET_ADDRESS),
]
class IP_ADAPTER_ADDRESSES(ctypes.Structure):
pass
LP_IP_ADAPTER_ADDRESSES = ctypes.POINTER(IP_ADAPTER_ADDRESSES)
IP_ADAPTER_ADDRESSES._fields_ = [
("Length", ctypes.wintypes.ULONG),
("IfIndex", ctypes.wintypes.DWORD),
("Next", LP_IP_ADAPTER_ADDRESSES),
("AdapterName", ctypes.c_char_p),
("FirstUnicastAddress", ctypes.POINTER(SOCKET_ADDRESS)),
("FirstAnycastAddress", ctypes.POINTER(SOCKET_ADDRESS)),
("FirstMulticastAddress", ctypes.POINTER(SOCKET_ADDRESS)),
("FirstDnsServerAddress", LP_IP_ADAPTER_DNS_SERVER_ADDRESS),
("DnsSuffix", ctypes.c_wchar * MAX_DNS_SUFFIX_STRING_LENGTH),
("Description", ctypes.c_wchar * MAX_ADAPTER_DESCRIPTION_LENGTH),
("FriendlyName", ctypes.c_wchar * MAX_ADAPTER_NAME_LENGTH),
# Additional fields are omitted for brevity
]
def print_dns_servers():
buffer_size = ctypes.wintypes.ULONG(15000) # Initial buffer size for the adapter addresses
buffer = ctypes.create_string_buffer(buffer_size.value)
# Call GetAdaptersAddresses to fill the buffer
ret = iphlpapi.GetAdaptersAddresses(
AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, None, buffer, ctypes.byref(buffer_size)
)
if ret == ERROR_BUFFER_OVERFLOW:
buffer = ctypes.create_string_buffer(buffer_size.value)
ret = iphlpapi.GetAdaptersAddresses(
AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, None, buffer, ctypes.byref(buffer_size)
)
if ret != ERROR_SUCCESS:
print("Failed to retrieve adapter addresses")
return
# Cast buffer to IP_ADAPTER_ADDRESSES structure
current_address = ctypes.cast(buffer, LP_IP_ADAPTER_ADDRESSES)
# Iterate through the linked list of IP_ADAPTER_ADDRESSES
while current_address:
adapter = current_address.contents
dns_server_address = adapter.FirstDnsServerAddress
while dns_server_address:
sockaddr = dns_server_address.contents.Address.lpSockaddr.contents
if sockaddr.sa_family == socket.AF_INET:
# Extract IPv4 address, which is in sa_data[2:6]
ip_address_bytes = sockaddr.sa_data[2:6]
ip_address = ".".join(map(str, ip_address_bytes))
print(f"Adapter: {adapter.FriendlyName}")
print(f"DNS Server: {ip_address}")
dns_server_address = dns_server_address.contents.Next
current_address = adapter.Next
if __name__ == '__main__':
print_dns_servers()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment