Python DNS Library のメモ書き

PythonDNS 問い合わせを色々と送信する必要があったので、以下のライブラリを使用した。付属している test スクリプトだと細かな使用方法まで言及していない。このライブラリを利用する上で必要となりそうな、問い合わせに必要な情報・レスポンスがどのように格納されるのか、といった点をまとめた。実行結果は Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit (Intel)] on win32 の Python Shell で試したもの。

Python DNS Library

>>> import DNS
>>> DNS.defaults
# 初期パラメータを格納した辞書 defautls
{'protocol': 'udp', 'server': [], 'rd': 1, 'opcode': 0, 'timeout': 30, 'timing': 1, 'qtype': 1, 'port': 53}
>>> DNS.DiscoverNameServers()
# Windows Registry に設定した DNS サーバの設定を抽出し、defaults に設定
>>> DNS.defaults
# x.x.x.x が Windows に設定した DNS サーバ。マスクしてます
{'protocol': 'udp', 'server': ['x.x.x.x', '0.0.0.0'], 'rd': 1, 'opcode': 0, 'timeout': 30, 'timing': 1, 'qtype': 1, 'port': 53}
>>> req = DNS.Request(qtype="ANY")
>>> res = req.req(name="www.example.com",qtype="A")
# 問い合わせ先の DNS サーバを変更したい場合、req の引数として server を設定する。
# res = req.req(name="www.example.com",qtype="A",server="x.x.x.x")
>>> res.show()
# dig と同様の形式で出力する
; <<>> PDG.py 1.0 <<>> www.example.com A
;; options: recurs 
;; got answer:
;; ->>HEADER<<- opcode 0, status NOERROR, id 9409
;; flags: qr rd ra; Ques: 1, Ans: 1, Auth: 2, Addit: 2
;; QUESTIONS:
;;      www.example.com, type = A, class = IN

;; ANSWERS:
www.example.com         36360   A       208.77.188.166

;; AUTHORITY RECORDS:
example.com             6196    NS      b.iana-servers.net
example.com             6196    NS      a.iana-servers.net

;; ADDITIONAL RECORDS:
a.iana-servers.net      12013   A       192.0.34.43
b.iana-servers.net      72874   A       193.0.0.236

;; Total query time: 31 msec
;; To SERVER: x.x.x.x
;; WHEN: Sun Sep 13 22:17:10 2009
>>> res.header
# DNS レスポンスのヘッダ情報を格納した辞書 header
{'aa': 0, 'status': 'NOERROR', 'qr': 1, 'nscount': 2, 'opcodestr': 'QUERY', 'qdcount': 1, 'tc': 0, 'rd': 1, 'arcount': 2, 'opcode': 0, 'ra': 1, 'z': 0, 'rcode': 0, 'id': 9409, 'ancount': 1}
>>> res.answers
# DNS レスポンスの RR(Resource Record) Answer レコードを格納したリスト answer
# Answer レコードが複数ある場合、それぞれのレコードが 1 辞書形式でリストに登録される
[{'name': 'www.example.com', 'data': '208.77.188.166', 'typename': 'A', 'classstr': 'IN', 'ttl': 36360, 'type': 1, 'class': 1, 'rdlength': 4}]
>>> res.authority
# DNS レスポンスの RR(Resource Record) Authority レコードを格納したリスト authority
[{'name': 'example.com', 'data': 'b.iana-servers.net', 'typename': 'NS', 'classstr': 'IN', 'ttl': 6196, 'type': 2, 'class': 1, 'rdlength': 20}, {'name': 'example.com', 'data': 'a.iana-servers.net', 'typename': 'NS', 'classstr': 'IN', 'ttl': 6196, 'type': 2, 'class': 1, 'rdlength': 4}]
>>> res.additional
# DNS レスポンスの RR(Resource Record) Authority レコードを格納したリスト additional
[{'name': 'a.iana-servers.net', 'data': '192.0.34.43', 'typename': 'A', 'classstr': 'IN', 'ttl': 12013, 'type': 1, 'class': 1, 'rdlength': 4}, {'name': 'b.iana-servers.net', 'data': '193.0.0.236', 'typename': 'A', 'classstr': 'IN', 'ttl': 72874, 'type': 1, 'class': 1, 'rdlength': 4}]

>>> res = req.req(name="wwwww.example.com",qtype="A")
# 存在しないホスト名を問い合わせると、どうなるか。
# 特に例外が生じるわけではない
>>> res.show()
; <<>> PDG.py 1.0 <<>> wwwww.example.com A
;; options: recurs 
;; got answer:
;; ->>HEADER<<- opcode 0, status NXDOMAIN, id 22029
;; flags: qr rd ra; Ques: 1, Ans: 0, Auth: 1, Addit: 0
;; QUESTIONS:
;;      wwwww.example.com, type = A, class = IN

;; ANSWERS:

;; AUTHORITY RECORDS:
example.com             10800   SOA     ('dns1.icann.org', 'hostmaster.icann.org', ('serial', 2007051703), ('refresh ', 7200, '2 hours'), ('retry', 3600, '1 hours'), ('expire', 1209600, '2 weeks'), ('minimum', 86400, '1 days'))

;; ADDITIONAL RECORDS:

;; Total query time: 140 msec
;; To SERVER: x.x.x.x
;; WHEN: Sun Sep 13 22:20:30 2009
>>> res.header
# 通常の DNS 問い合わせ同様、ヘッダ Status=NXDOMAIN で返答される
{'aa': 0, 'status': 'NXDOMAIN', 'qr': 1, 'nscount': 1, 'opcodestr': 'QUERY', 'qdcount': 1, 'tc': 0, 'rd': 1, 'arcount': 0, 'opcode': 0, 'ra': 1, 'z': 0, 'rcode': 3, 'id': 22029, 'ancount': 0}


>>> res = req.req(name="www.example.com",qtype="A",server="192.168.0.123")
# プライベートアドレスの存在しない DNS サーバに問い合わせした場合、
# DNSError が例外として生じる。このライブラリを利用する場合、
# except DNSError で例外処理を実装すればよい

Traceback (most recent call last):
  File "<pyshell#16>", line 1, in <module>
    res = req.req(name="www.example.com",qtype="A",server="192.168.0.123")
  File "G:\Python25\Lib\site-packages\DNS\Base.py", line 206, in req
    self.sendUDPRequest(server)
  File "G:\Python25\Lib\site-packages\DNS\Base.py", line 236, in sendUDPRequest
    r=self.processUDPReply()
  File "G:\Python25\Lib\site-packages\DNS\Base.py", line 104, in processUDPReply
    raise DNSError, 'Timeout'
DNSError: Timeout