Credit: Wolfgang Strobl
You
need to find out which DNS name servers are being used, but
you’re on Microsoft Windows, so you
can’t just parse the
resolv.conf
file, as you might do on Unix and
Unix-like platforms.
On Windows, DNS servers (like much other information) can be found in
the registry, which can be accessed with the standard module
_winreg
:
import string import _winreg def binipdisplay(s): "convert a binary array of ip addresses to a python list" if len(s)%4!= 0: raise EnvironmentError # well ... ol=[] for i in range(len(s)/4): s1=s[:4] s=s[4:] ip=[] for j in s1: ip.append(str(ord(j))) ol.append(string.join(ip,'.')) return ol def stringdisplay(s): 'convert "d.d.d.d,d.d.d.d" to ["d.d.d.d","d.d.d.d"]' return string.split(s,",") def RegistryResolve( ): """ Return the list of dotted-quads addresses of name servers found in the registry -- tested on NT4 Server SP6a, Win/2000 Pro SP2, XP, ME (each of which has a different registry layout for nameservers!) """ nameservers=[] x=_winreg.ConnectRegistry(None,_winreg.HKEY_LOCAL_MACHINE) try: y= _winreg.OpenKey(x, r"SYSTEMCurrentControlSetServicesTcpipParameters") except EnvironmentError: # so it isn't NT/2000/XP # Windows ME, perhaps? try: # for Windows ME y = _winreg.OpenKey(x, r"SYSTEMCurrentControlSetServicesVxDMSTCP") nameserver, dummytype = _winreg.QueryValueEx(y,'NameServer') if nameserver and not (nameserver in nameservers): nameservers.extend(stringdisplay(nameserver)) except EnvironmentError: pass # Must be another Windows dialect, so who knows? return nameservers nameserver = _winreg.QueryValueEx(y,"NameServer")[0] if nameserver: nameservers = [nameserver] _winreg.CloseKey(y) try: # for win2000 y = _winreg.OpenKey(x, r"SYSTEMCurrentControlSetServicesTcpip" r"ParametersDNSRegisteredAdapters") for i in range(1000): try: n = _winreg.EnumKey(y,i) z = _winreg.OpenKey(y,n) dnscount,dnscounttype = _winreg.QueryValueEx(z, 'DNSServerAddressCount') dnsvalues,dnsvaluestype = _winreg.QueryValueEx(z, 'DNSServerAddresses') nameservers.extend(binipdisplay(dnsvalues)) _winreg.CloseKey(z) except EnvironmentError: break _winreg.CloseKey(y) except EnvironmentError: pass try: # for XP y = _winreg.OpenKey(x, r"SYSTEMCurrentControlSetServicesTcpipParametersInterfaces") for i in range(1000): try: n = _winreg.EnumKey(y,i) z = _winreg.OpenKey(y,n) try: nameserver,dummytype = _winreg.QueryValueEx(z,'NameServer') if nameserver and not (nameserver in nameservers): nameservers.extend(stringdisplay(nameserver)) except EnvironmentError: pass _winreg.CloseKey(z) except EnvironmentError: break _winreg.CloseKey(y) except EnvironmentError: # Print "Key Interfaces not found, just do nothing" pass _winreg.CloseKey(x) return nameservers if _ _name_ _=="_ _main_ _": print "Name servers:",RegistryResolve( )
RegistryResolve
returns a list of IP addresses (dotted quads) by scanning the
registry for interfaces with name server entries. This is useful when
porting utilities that scan resolv.conf
from
Unix-based systems to Microsoft Windows. As shown, the code handles
differences between NT, 2000, XP, and ME (I haven’t
tried it on Windows 95/98, but it should work), and is thus a good
example of the many huge differences under the cover that the system
administrator must handle for systems that may appear to end users to
be reasonably close to each other.
Checking which name servers each given machine is using is quite
useful when administering that machine, or a whole network.
Basically, all user access to the network is mediated by DNS. Since
no user wants to work with dotted quads, almost all URLs use
hostnames and not IP addresses. From the user’s
viewpoint, if a DNS server is down, or if name service is
misconfigured for a given machine, it’s almost as
bad as if there is no network access at all. This recipe makes it
feasible for you to keep an eye on this crucial aspect of networking
service, available from Python scripts, for client machines running
Windows (client machines running Unix or Unix-like systems are easy
to use from this point of view, since
/etc/resolv.conf
is a text file, and a pretty
easy one to parse).
Documentation for the standard module _winreg
in
the Library Reference; Windows API documentation
available from Microsoft (http://msdn.microsoft.com).