BIND 10 trac2487, updated. 7190eaa2a3427b067064c1650872df8ad967e776 [trac2487] port of the host.cc example to python
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Nov 20 08:15:04 UTC 2012
The branch, trac2487 has been updated
via 7190eaa2a3427b067064c1650872df8ad967e776 (commit)
from 504f64b2975180c69805756c4e6997c9dfdf140c (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 7190eaa2a3427b067064c1650872df8ad967e776
Author: Francis Dupont <fdupont at isc.org>
Date: Tue Nov 20 09:14:50 2012 +0100
[trac2487] port of the host.cc example to python
-----------------------------------------------------------------------
Summary of changes:
examples/configure.ac | 26 +++++-
examples/host/host.py.in | 199 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 224 insertions(+), 1 deletion(-)
create mode 100644 examples/host/host.py.in
-----------------------------------------------------------------------
diff --git a/examples/configure.ac b/examples/configure.ac
index 37515d9..1799001 100644
--- a/examples/configure.ac
+++ b/examples/configure.ac
@@ -36,7 +36,31 @@ fi
# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
+# Checks for Python
+m4_define([_AM_PYTHON_INTERPRETER_LIST],
+ [python python3.3 python3.2 python3.1 python3])
+AC_ARG_WITH([pythonpath],
+AC_HELP_STRING([--with-pythonpath=PATH],
+ [specify an absolute path to python executable when automatic version check (incorrectly) fails]),
+ [python_path="$withval"], [python_path="auto"])
+if test "$python_path" = auto; then
+ AM_PATH_PYTHON([3.1])
+else
+ # Older versions of automake can't handle python3 well. This is an
+ # in-house workaround for them.
+ PYTHON=$python_path
+ AC_SUBST(PYTHON)
+ PYTHON_VERSION=[`$PYTHON -c "import sys; sys.stdout.write(sys.version[:3])"`]
+ if test `echo "$PYTHON_VERSION >= 3.1" | bc` != 1 ; then
+ AC_MSG_ERROR(["Python version too old: $PYTHON_VERSION, need 3.1 or higher"])
+ fi
+ AC_SUBST(PYTHON_VERSION)
+ PYTHONPATH='${exec_prefix}/lib/python'$PYTHON_VERSION'/site-packages'
+ AC_SUBST(PYTHONPATH)
+fi
+
AC_CONFIG_FILES([Makefile
- host/Makefile])
+ host/Makefile
+ host/host.py])
AC_OUTPUT
diff --git a/examples/host/host.py.in b/examples/host/host.py.in
new file mode 100644
index 0000000..097da88
--- /dev/null
+++ b/examples/host/host.py.in
@@ -0,0 +1,199 @@
+#!@PYTHON@
+
+# Copyright (C) 2012 Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import sys; sys.path.append ('@PYTHONPATH@')
+
+import getopt
+import time
+import socket
+import bind10_config
+from isc.dns import *
+
+def host_lookup(name, dns_class, type, any,
+ sock, sendsa, verbose, recursive_bit):
+ """doing the lookup itself"""
+ msg = Message(Message.RENDER)
+
+ # does this matter?
+ msg.set_qid(0)
+
+ # TODO: add switch for this
+ msg.set_opcode(Opcode.QUERY())
+ msg.set_rcode(Rcode.NOERROR())
+ if recursive_bit:
+ msg.set_header_flag(Message.HEADERFLAG_RD)
+
+ if any:
+ type = RRType.ANY()
+ msg.add_question(Question(Name(name), dns_class, type))
+
+ renderer = MessageRenderer()
+ msg.to_wire(renderer)
+
+ if verbose:
+ before_time = time.time()
+
+ try:
+ sock.sendto(renderer.get_data(), sendsa)
+ except OSError:
+ print('failed to send request', file=sys.stderr)
+ return
+
+ try:
+ (recvbuf, recvsa) = sock.recvfrom(4096)
+ except OSError:
+ print('failed to receive response', file=sys.stderr)
+ return
+
+ try:
+ rmsg = Message(Message.PARSE)
+ rmsg.from_wire(recvbuf)
+ if not verbose:
+ description = ''
+ for rrset in rmsg.get_section(Message.SECTION_ANSWER):
+ if rrset.get_type() == RRType.A():
+ description = 'has address'
+ elif rrset.get_type() == RRType.AAAA():
+ description = 'has IPv6 address'
+ elif rrset.get_type() == RRType.MX():
+ description = 'mail is handled by'
+ elif rrset.get_type() == RRType.TXT():
+ description = 'descriptive text'
+ else:
+ description = 'RR(' + rrset.get_type().to_text() + ')'
+
+ for rdata in rrset.get_rdata():
+ print(name, description, rdata.to_text())
+ else:
+ after_time = time.time()
+
+ # HEADER and QUESTION, ANSWER, AUTHORITY, and ADDITIONAL
+ print(rmsg.to_text())
+
+ elapsed_time = int((after_time - before_time) * 1000.)
+
+ # TODO: if NXDOMAIN, host(1) doesn't show HEADER
+ # Host hsdjkfhksjhdfkj not found: 3(NXDOMAIN)
+ # TODO: test if NXDOMAIN
+
+ print('Received', len(recvbuf), 'bytes in', elapsed_time, 'ms')
+ # TODO: " bytes from 127.0.0.1#53 in 0 ms
+
+ # TODO: handle InvalidRRClass
+ # TODO: handle invalid type exception
+ except Exception as ex:
+ print('parse failed for', name + '/' + type.to_text() + ':', ex,
+ file=sys.stderr)
+ except:
+ print('parse failed for', name + '/' + type.to_text(),
+ file=sys.stderr)
+
+ return False
+
+def usage():
+ """print usage"""
+ print('Usage: host.py [-adrv] [-c class] [-p port] [-t type]',
+ 'hostname [server]')
+ sys.exit(1)
+
+def main():
+ """main/entry point"""
+
+ # not set, so A, AAAA, MX
+ dns_type = None
+ server = '127.0.0.1'
+ server_port = 53
+ dns_class = RRClass.IN()
+ verbose = False
+ dns_any = False
+ recursive_bit = True
+
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], 'ac:dp:rt:v')
+ except getopt.GetoptError as ex:
+ print(str(ex))
+ usage()
+
+ for option, arg in opts:
+ if option == '-a':
+ dns_any = True
+ verbose = True
+ elif option == '-c':
+ dns_class = RRClass(arg)
+ # p for port is a non-standard switch
+ elif option == '-p':
+ server_port = int(arg)
+ elif option == '-r':
+ recursive_bit = False
+ elif option == '-t':
+ dns_type = RRType(arg)
+ # debug and verbose are equivalent
+ elif (option == '-d') or (option == '-v'):
+ verbose = True
+ else:
+ print('unhandled option', option)
+ usage()
+
+ if len(args) == 0:
+ usage()
+ elif len(args) >= 2:
+ server = args[1]
+
+ try:
+ res = socket.getaddrinfo(server, server_port, type=socket.SOCK_DGRAM)
+ except OSError:
+ print('address/port conversion for',
+ server + ':' + server_port,
+ 'failed',
+ file=sys.stderr)
+ raise
+
+ af, socktype, proto, cname, sendsa = res[0]
+ if verbose:
+ print('Trying "' + args[0] + '"')
+ # this is only output the first time
+ print('Using domain server:')
+ print('Name:', server)
+ # TODO: I guess I have to do a lookup to get that address and aliases
+ # too
+ # print('Address:', address) # '#', port
+ # print('Aliases:', server)
+
+ try:
+ sock = socket.socket(af, socktype, proto)
+ except OSError:
+ print('failed to open socket', file=sys.stderr)
+ return
+
+ if dns_type is None:
+ host_lookup(args[0], dns_class, RRType.A(), dns_any,
+ sock, sendsa, verbose, recursive_bit)
+ # TODO: don't do next if A doesn't exist
+ host_lookup(args[0], dns_class, RRType.AAAA(), dns_any,
+ sock, sendsa, verbose, recursive_bit)
+ host_lookup(args[0], dns_class, RRType.MX(), dns_any,
+ sock, sendsa, verbose, recursive_bit)
+ else:
+ # -t overrides -a, regardless of order
+ host_lookup(args[0], dns_class, dns_type, False,
+ sock, sendsa, verbose, recursive_bit)
+
+ sock.close()
+ sys.exit(0)
+
+if __name__ == '__main__':
+ main()
More information about the bind10-changes
mailing list