7.10 Examining the Microsoft Windows Registry for a List of
Name
Server Addresses
Credit: Wolfgang Strobl
7.10.1 Problem
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.
7.10.2 Solution
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"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters")
except EnvironmentError: # so it isn't NT/2000/XP
# Windows ME, perhaps?
try: # for Windows ME
y = _winreg.OpenKey(x,
r"SYSTEM\CurrentControlSet\Services\VxD\MSTCP")
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"SYSTEM\CurrentControlSet\Services\Tcpip"
r"\Parameters\DNSRegisteredAdapters")
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"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces")
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( )
7.10.3 Discussion
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).
7.10.4 See Also
Documentation for the standard module
_winreg
in the
Library Reference
; Windows API documentation available from Microsoft (http://msdn.microsoft.com).
|