Created
April 28, 2025 02:34
-
-
Save blink1073/349f83fdccabd23aeeabcfd3583f8017 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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