mirror of
https://github.com/Hopiu/linkchecker.git
synced 2026-04-24 16:14:45 +00:00
update nameserver parsing
git-svn-id: https://linkchecker.svn.sourceforge.net/svnroot/linkchecker/trunk/linkchecker@1103 e7d03fd6-7b0d-0410-9947-9c21f3af8025
This commit is contained in:
parent
9a76724437
commit
b5023d14c4
3 changed files with 207 additions and 175 deletions
|
|
@ -10,9 +10,9 @@ This code is covered by the standard Python License.
|
|||
Base functionality. Request and Response classes, that sort of thing.
|
||||
"""
|
||||
|
||||
import select, socket, string, types, time, asyncore
|
||||
import select, socket, string, types, time, asyncore, os
|
||||
|
||||
class DNSError(Exception): pass
|
||||
class DNSError (Exception): pass
|
||||
|
||||
import Lib, Type, Class, Opcode
|
||||
|
||||
|
|
@ -27,35 +27,90 @@ defaults = {
|
|||
'server': [],
|
||||
}
|
||||
|
||||
def ParseResolvConf(resolv_path="/etc/resolv.conf"):
|
||||
"parses the /etc/resolv.conf file and sets defaults for name servers"
|
||||
global defaults
|
||||
lines=open(resolv_path).readlines()
|
||||
for line in lines:
|
||||
line = string.strip(line)
|
||||
if not line or line[0]==';' or line[0]=='#':
|
||||
continue
|
||||
fields=string.split(line)
|
||||
if len(fields) == 0:
|
||||
continue
|
||||
if fields[0]=='domain':
|
||||
defaults['domain']=fields[1]
|
||||
if fields[0]=='search':
|
||||
pass
|
||||
if fields[0]=='options':
|
||||
pass
|
||||
if fields[0]=='sortlist':
|
||||
pass
|
||||
if fields[0]=='nameserver':
|
||||
defaults['server'].append(fields[1])
|
||||
|
||||
def DiscoverNameServers():
|
||||
import sys
|
||||
if sys.platform in ('win32', 'nt'):
|
||||
import win32dns
|
||||
defaults['server']=win32dns.RegistryResolve()
|
||||
def DiscoverNameServers ():
|
||||
import os
|
||||
if os.name=='posix':
|
||||
init_dns_resolver_posix()
|
||||
elif os.name=='nt':
|
||||
init_dns_resolver_nt()
|
||||
else:
|
||||
return ParseResolvConf()
|
||||
# other platforms not supported (what about Mac?)
|
||||
pass
|
||||
if not defaults['server']:
|
||||
# last fallback: localhost
|
||||
defaults['server'].append('127.0.0.1')
|
||||
|
||||
|
||||
def init_dns_resolver_posix ():
|
||||
"Set up the DnsLookupConnection class with /etc/resolv.conf information"
|
||||
if not os.path.exists('/etc/resolv.conf'):
|
||||
return
|
||||
for line in file('/etc/resolv.conf', 'r').readlines():
|
||||
line = line.strip()
|
||||
if (not line) or line[0]==';' or line[0]=='#':
|
||||
continue
|
||||
m = re.match(r'^search\s+(\.?.+)$', line)
|
||||
if m:
|
||||
for domain in m.group(1).split():
|
||||
# domain search path not used
|
||||
pass
|
||||
m = re.match(r'^nameserver\s+(\S+)\s*$', line)
|
||||
if m:
|
||||
defaults['server'].append(m.group(1))
|
||||
|
||||
|
||||
def init_dns_resolver_nt ():
|
||||
import winreg
|
||||
key = None
|
||||
try:
|
||||
key = winreg.key_handle(winreg.HKEY_LOCAL_MACHINE,
|
||||
r"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters")
|
||||
except EnvironmentError:
|
||||
try: # for Windows ME
|
||||
key = winreg.key_handle(winreg.HKEY_LOCAL_MACHINE,
|
||||
r"SYSTEM\CurrentControlSet\Services\VxD\MSTCP")
|
||||
except EnvironmentError:
|
||||
pass
|
||||
if key:
|
||||
for server in winreg.stringdisplay(key["NameServer"]):
|
||||
if server:
|
||||
defaults['server'].append(str(server))
|
||||
for item in winreg.stringdisplay(key["SearchList"]):
|
||||
if item:
|
||||
pass # domain search not used
|
||||
if not defaults['server']:
|
||||
# XXX the proper way to test this is to search for
|
||||
# the "EnableDhcp" key in the interface adapters...
|
||||
for server in winreg.stringdisplay(key["DhcpNameServer"]):
|
||||
if server:
|
||||
defaults['server'].append(str(server))
|
||||
for item in winreg.stringdisplay(key["DhcpDomain"]):
|
||||
if item:
|
||||
pass # domain search not used
|
||||
|
||||
try: # search adapters
|
||||
key = winreg.key_handle(winreg.HKEY_LOCAL_MACHINE,
|
||||
r"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DNSRegisteredAdapters")
|
||||
for subkey in key.subkeys():
|
||||
count, counttype = subkey['DNSServerAddressCount']
|
||||
values, valuestype = subkey['DNSServerAddresses']
|
||||
for server in winreg.binipdisplay(values):
|
||||
if server:
|
||||
defaults['server'].append(str(server))
|
||||
except EnvironmentError:
|
||||
pass
|
||||
|
||||
try: # search interfaces
|
||||
key = winreg.key_handle(winreg.HKEY_LOCAL_MACHINE,
|
||||
r"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces")
|
||||
for subkey in key.subkeys():
|
||||
for server in winreg.stringdisplay(subkey.get('NameServer', '')):
|
||||
if server:
|
||||
defaults['server'].append(str(server))
|
||||
except EnvironmentError:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class DnsRequest:
|
||||
""" high level Request object """
|
||||
|
|
@ -255,6 +310,9 @@ class DnsAsyncRequest(DnsRequest,asyncore.dispatcher_with_send):
|
|||
|
||||
#
|
||||
# $Log$
|
||||
# Revision 1.7 2003/12/18 14:20:37 calvin
|
||||
# update nameserver parsing
|
||||
#
|
||||
# Revision 1.6 2003/07/04 14:23:22 calvin
|
||||
# add coding line
|
||||
#
|
||||
|
|
|
|||
|
|
@ -1,145 +0,0 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
"""
|
||||
$Id$
|
||||
|
||||
Extract a list of TCP/IP name servers from the registry 0.1
|
||||
0.1 Strobl 2001-07-19
|
||||
Usage:
|
||||
RegistryResolve() returns a list of ip numbers (dotted quads), by
|
||||
scouring the registry for addresses of name servers
|
||||
|
||||
Tested on Windows NT4 Server SP6a, Windows 2000 Pro SP2 and
|
||||
Whistler Pro (XP) Build 2462 and Windows ME
|
||||
... all having a different registry layout wrt name servers :-/
|
||||
|
||||
Todo:
|
||||
|
||||
Program doesn't check whether an interface is up or down
|
||||
|
||||
(c) 2001 Copyright by Wolfgang Strobl ws@mystrobl.de,
|
||||
License analog to the current Python license
|
||||
"""
|
||||
|
||||
import string, re
|
||||
import _winreg
|
||||
|
||||
def binipdisplay(s):
|
||||
"convert a binary array of ip adresses 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"].
|
||||
also handle u'd.d.d.d d.d.d.d', as reporting on SF
|
||||
'''
|
||||
import re
|
||||
return map(str, re.split("[ ,]",s))
|
||||
|
||||
def RegistryResolve():
|
||||
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
|
||||
return nameservers # no idea
|
||||
|
||||
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\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 whistler
|
||||
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()
|
||||
|
||||
#
|
||||
# $Log$
|
||||
# Revision 1.2 2003/07/04 14:23:22 calvin
|
||||
# add coding line
|
||||
#
|
||||
# Revision 1.1 2002/11/26 23:27:43 calvin
|
||||
# update to Python >= 2.2.1
|
||||
#
|
||||
# Revision 1.3 2002/05/06 06:15:31 anthonybaxter
|
||||
# apparently some versions of windows return servers as unicode
|
||||
# string with space sep, rather than strings with comma sep.
|
||||
# *sigh*
|
||||
#
|
||||
# Revision 1.2 2002/03/19 12:41:33 anthonybaxter
|
||||
# tabnannied and reindented everything. 4 space indent, no tabs.
|
||||
# yay.
|
||||
#
|
||||
# Revision 1.1 2001/08/09 09:22:28 anthonybaxter
|
||||
# added what I hope is win32 resolver lookup support. I'll need to try
|
||||
# and figure out how to get the CVS checkout onto my windows machine to
|
||||
# make sure it works (wow, doing something other than games on the
|
||||
# windows machine :)
|
||||
#
|
||||
# Code from Wolfgang.Strobl@gmd.de
|
||||
# win32dns.py from
|
||||
# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66260
|
||||
#
|
||||
# Really, ParseResolvConf() should be renamed "FindNameServers" or
|
||||
# some such.
|
||||
#
|
||||
#
|
||||
119
linkcheck/DNS/winreg.py
Normal file
119
linkcheck/DNS/winreg.py
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
"""_winreg convenience wrapper (currently readonly)"""
|
||||
# Copyright (C) 2001 Bastian Kleineidam (except helper functions below)
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
__version__ = "$Revision$"[11:-2]
|
||||
__date__ = "$Date$"[7:-2]
|
||||
|
||||
# import all from _winreg
|
||||
from _winreg import *
|
||||
from types import StringType
|
||||
|
||||
class key_handle (object):
|
||||
"""represent an opened key with dictionary-like access"""
|
||||
def __init__ (self, key, sub_key):
|
||||
self._key = OpenKey(key, sub_key)
|
||||
self.closed = False
|
||||
|
||||
|
||||
def __getitem__ (self, key):
|
||||
if type(key) != StringType:
|
||||
raise TypeError, "key type must be string"
|
||||
try:
|
||||
val = QueryValueEx(self._key, key)
|
||||
except WindowsError:
|
||||
raise IndexError, "subkey %s not found"%key
|
||||
return val[0]
|
||||
|
||||
|
||||
def get (self, key, default=None):
|
||||
try:
|
||||
return self[key]
|
||||
except IndexError:
|
||||
return default
|
||||
|
||||
|
||||
def subkeys (self):
|
||||
"""get the list of subkeys as key_handle objects"""
|
||||
i = 0
|
||||
keys = []
|
||||
while 1:
|
||||
try:
|
||||
#print repr(EnumKey(self._key, i))
|
||||
keys.append(key_handle(self._key, EnumKey(self._key, i)))
|
||||
except EnvironmentError:
|
||||
break
|
||||
i += 1
|
||||
return keys
|
||||
|
||||
|
||||
def __len__ (self):
|
||||
return QueryInfoKey(self._key)[0]
|
||||
|
||||
|
||||
def __setitem__ (self, key, value):
|
||||
"""Set a registry key value. key is the key name,
|
||||
value is a tuple (type, val). For available types
|
||||
see the _winreg module documentation."""
|
||||
key = self.__getitem__(key)
|
||||
SetValueEx(self._key, key, value[0], value[1])
|
||||
|
||||
|
||||
def __delitem__ (self, key):
|
||||
"""XXX to be implemented"""
|
||||
pass
|
||||
|
||||
|
||||
def close (self):
|
||||
CloseKey(self._key)
|
||||
self.closed = True
|
||||
|
||||
|
||||
def __del__ (self):
|
||||
if not self.closed:
|
||||
self.close()
|
||||
|
||||
#################################################################
|
||||
# helper functions from pydns at sourceforge
|
||||
# (c) 2001 Copyright by Wolfgang Strobl ws@mystrobl.de,
|
||||
# License analog to the current Python license
|
||||
|
||||
def binipdisplay (s):
|
||||
"convert a binary array of ip adresses 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('.'.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 s.split(",")
|
||||
|
||||
#################################################################
|
||||
|
||||
def test ():
|
||||
pass
|
||||
|
||||
if __name__=="__main__":
|
||||
test()
|
||||
Loading…
Reference in a new issue