I l@ve RuBoard |
7.10 Examining the Microsoft Windows Registry for a List of Name Server AddressesCredit: Wolfgang Strobl 7.10.1 ProblemYou 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 SolutionOn 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 DiscussionRegistryResolve 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 AlsoDocumentation for the standard module _winreg in the Library Reference; Windows API documentation available from Microsoft (http://msdn.microsoft.com). |
I l@ve RuBoard |