diff options
Diffstat (limited to 'contrib/python')
66 files changed, 8474 insertions, 0 deletions
diff --git a/contrib/python/LICENSE b/contrib/python/LICENSE new file mode 100644 index 000000000000..1eb01e12161b --- /dev/null +++ b/contrib/python/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz) + Karel Slany (slany AT fit.vutbr.cz) +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the organization nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/contrib/python/Makefile b/contrib/python/Makefile new file mode 100644 index 000000000000..c43970509a4e --- /dev/null +++ b/contrib/python/Makefile @@ -0,0 +1,67 @@ +# Makefile: compilation of sources and documentation, test environment +# +# Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz) +# Karel Slany (slany AT fit.vutbr.cz) +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the organization nor the names of its +# contributors may be used to endorse or promote products derived from this +# software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +help: + @echo "Please use \`make <target>' where <target> is one of" + @echo " testenv to make test environment and run bash " + @echo " usefull in case you don't want to install ldns but want to test examples" + @echo " doc to make documentation" + @echo " clean clean all" + +../../Makefile: ../../configure + cd ../.. && ./configure --with-python + +_ldns.so: ../../Makefile + $(MAKE) -C ../.. + +../../.libs/ldns.so.1: ../../Makefile + $(MAKE) -C ../.. + +clean: + rm -rdf examples/ldns + rm -f _ldns.so ldns_wrapper.o + $(MAKE) -C ../.. clean + +testenv: ../../.libs/libldns.so.1 _ldns.so + rm -rdf examples/ldns + cd examples && mkdir ldns && ln -s ../../ldns.py ldns/__init__.py && ln -s ../../_ldns.so ldns/_ldns.so && ln -s ../../../../.libs/libldns.so.1 ldns/libldns.so.1 && ls -la + @echo "Run a script by typing ./script_name.py" + cd examples && LD_LIBRARY_PATH=ldns bash + rm -rdf examples/ldns + +doc: ../../.libs/ldns.so.1 _ldns.so + $(MAKE) -C docs html + +#for development only +swig: ldns.i + swig -python -py3 -o ldns_wrapper.c -I../.. ldns.i + gcc -c ldns_wrapper.c -O9 -fPIC -I../.. -I../../ldns -I/usr/include/python3.1 -I. -o ldns_wrapper.o + ld -shared ldns_wrapper.o -L../../.libs -lldns -o _ldns.so + diff --git a/contrib/python/docs/Makefile b/contrib/python/docs/Makefile new file mode 100644 index 000000000000..856ecd45e187 --- /dev/null +++ b/contrib/python/docs/Makefile @@ -0,0 +1,70 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source + +.PHONY: help clean html web pickle htmlhelp latex changes linkcheck + +help: + @echo "Please use \`make <target>' where <target> is one of" + @echo " html to make standalone HTML files" + @echo " pickle to make pickle files (usable by e.g. sphinx-web)" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " changes to make an overview over all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + +clean: + -rm -rf build/* + +html: + mkdir -p build/html build/doctrees + LD_LIBRARY_PATH=../../../.libs $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html + @echo + @echo "Build finished. The HTML pages are in build/html." + +pickle: + mkdir -p build/pickle build/doctrees + LD_LIBRARY_PATH=../../../.libs $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) build/pickle + @echo + @echo "Build finished; now you can process the pickle files or run" + @echo " sphinx-web build/pickle" + @echo "to start the sphinx-web server." + +web: pickle + +htmlhelp: + mkdir -p build/htmlhelp build/doctrees + LD_LIBRARY_PATH=../../../.libs $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) build/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in build/htmlhelp." + +latex: + mkdir -p build/latex build/doctrees + LD_LIBRARY_PATH=../../../.libs $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) build/latex + @echo + @echo "Build finished; the LaTeX files are in build/latex." + @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ + "run these through (pdf)latex." + +changes: + mkdir -p build/changes build/doctrees + LD_LIBRARY_PATH=../../../.libs $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) build/changes + @echo + @echo "The overview file is in build/changes." + +linkcheck: + mkdir -p build/linkcheck build/doctrees + LD_LIBRARY_PATH=../../../.libs $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) build/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in build/linkcheck/output.txt." diff --git a/contrib/python/docs/source/conf.py b/contrib/python/docs/source/conf.py new file mode 100644 index 000000000000..22b73bcd712d --- /dev/null +++ b/contrib/python/docs/source/conf.py @@ -0,0 +1,180 @@ +# -*- coding: utf-8 -*- +# +# Unbound documentation build configuration file, created by +# sphinx-quickstart on Fri Jan 2 19:14:13 2009. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# The contents of this file are pickled, so don't put values in the namespace +# that aren't pickleable (module imports are okay, they're removed automatically). +# +# All configuration values have a default value; values that are commented out +# serve to show the default value. + +import sys, os + +# If your extensions are in another directory, add it here. If the directory +# is relative to the documentation root, use os.path.abspath to make it +# absolute, like shown here. +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__),'../../'))) +#print sys.path + +# General configuration +# --------------------- + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General substitutions. +project = 'pyLDNS' +copyright = '2009, Karel Slany, Zdenek Vasicek' + +# The default replacements for |version| and |release|, also used in various +# other places throughout the built documents. +# +# The short X.Y version. +version = '1.0' +# The full version, including alpha/beta/rc tags. +release = '1.0.0' + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +today_fmt = '%B %d, %Y' + +# List of documents that shouldn't be included in the build. +#unused_docs = [] + +# List of directories, relative to source directories, that shouldn't be searched +# for source files. +#exclude_dirs = [] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + + +# Options for HTML output +# ----------------------- + +# The style sheet to use for HTML and HTML Help pages. A file of that name +# must exist either in Sphinx' static/ path, or in one of the custom paths +# given in html_static_path. +html_style = 'default.css' + +# The name for this set of Sphinx documents. If None, it defaults to +# "<project> v<release> documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (within the static path) to place at the top of +# the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +html_use_modindex = False + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +html_split_index = False + +# If true, the reST sources are included in the HTML build as _sources/<name>. +html_copy_source = False + +# If true, an OpenSearch description file will be output, and all pages will +# contain a <link> tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = '' + +# Output file base name for HTML help builder. +htmlhelp_basename = 'ldnsdoc' + + +# Options for LaTeX output +# ------------------------ + +# The paper size ('letter' or 'a4'). +#latex_paper_size = 'letter' + +# The font size ('10pt', '11pt' or '12pt'). +#latex_font_size = '10pt' + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, document class [howto/manual]). +latex_documents = [ + ('index', 'ldns-doc.tex', 'LDNS Documentation', + 'Karel Slany, Zdenek Vasicek', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# Additional stuff for the LaTeX preamble. +#latex_preamble = '' + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_use_modindex = True diff --git a/contrib/python/docs/source/examples/example1.rst b/contrib/python/docs/source/examples/example1.rst new file mode 100644 index 000000000000..b44141759f5a --- /dev/null +++ b/contrib/python/docs/source/examples/example1.rst @@ -0,0 +1,68 @@ +Resolving the MX records +============================== + +This basic example shows how to create a resolver which asks for MX records which contain the information about mail servers. + +:: + + #!/usr/bin/python + # + # MX is a small program that prints out the mx records for a particular domain + # + import ldns + + resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf") + + dname = ldns.ldns_dname("nic.cz") + + pkt = resolver.query(dname, ldns.LDNS_RR_TYPE_MX, ldns.LDNS_RR_CLASS_IN, ldns.LDNS_RD) + if (pkt): + mx = pkt.rr_list_by_type(ldns.LDNS_RR_TYPE_MX, ldns.LDNS_SECTION_ANSWER) + if (mx): + mx.sort() + print mx + +Resolving step by step +------------------------ + +First of all we import :mod:`ldns` extension module which make LDNS functions and classes accessible:: + + import ldns + +If importing fails, it means that Python cannot find the module or ldns library. + +Then we create the resolver by :meth:`ldns.ldns_resolver.new_frm_file` constructor :: + + resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf") + +and domain name variable dname:: + + dname = ldns.ldns_dname("nic.cz") + +To create a resolver you may also use:: + + resolver = ldns.ldns_resolver.new_frm_file(None) + +which behaves in the same manner as the command above. + +In the third step we tell the resolver to query for our domain, type MX, of class IN:: + + pkt = resolver.query(dname, ldns.LDNS_RR_TYPE_MX, ldns.LDNS_RR_CLASS_IN, ldns.LDNS_RD) + +The function should return a packet if everything goes well and this packet will contain resource records we asked for. +Note that there exists a simplier way. Instead of using a dname variable, we can use a string which will be automatically converted. +:: + + pkt = resolver.query("fit.vutbr.cz", ldns.LDNS_RR_TYPE_MX, ldns.LDNS_RR_CLASS_IN, ldns.LDNS_RD) + +Now, we test whether the resolver returns a packet and then get all RRs of type MX from the answer packet and store them in list mx:: + + if (pkt): + mx = pkt.rr_list_by_type(ldns.LDNS_RR_TYPE_MX, ldns.LDNS_SECTION_ANSWER) + +If this list is not empty, we sort and print the content to stdout:: + + if (mx): + mx.sort() + print mx + diff --git a/contrib/python/docs/source/examples/example2.py b/contrib/python/docs/source/examples/example2.py new file mode 100755 index 000000000000..7dabb9179025 --- /dev/null +++ b/contrib/python/docs/source/examples/example2.py @@ -0,0 +1,45 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +import ldns +import sys + +debug = True + +# Check args +argc = len(sys.argv) +name = "www.nic.cz" +if argc < 2: + print("Usage:", sys.argv[0], "domain [resolver_addr]") + sys.exit(1) +else: + name = sys.argv[1] + +# Create resolver +resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf") +resolver.set_dnssec(True) + +# Custom resolver +if argc > 2: + # Clear previous nameservers + ns = resolver.pop_nameserver() + while ns != None: + ns = resolver.pop_nameserver() + ip = ldns.ldns_rdf.new_frm_str(sys.argv[2], ldns.LDNS_RDF_TYPE_A) + resolver.push_nameserver(ip) + +# Resolve DNS name +pkt = resolver.query(name, ldns.LDNS_RR_TYPE_A, ldns.LDNS_RR_CLASS_IN) +if pkt and pkt.answer(): + + # Debug + if debug: + print("NS returned:", pkt.get_rcode(), "(AA: %d AD: %d)" % ( pkt.ad(), pkt.ad() )) + + # SERVFAIL indicated bogus name + if pkt.get_rcode() is ldns.LDNS_RCODE_SERVFAIL: + print(name, "is bogus") + + # Check AD (Authenticated) bit + if pkt.get_rcode() is ldns.LDNS_RCODE_NOERROR: + if pkt.ad(): print(name, "is secure") + else: print(name, "is insecure") diff --git a/contrib/python/docs/source/examples/example2.rst b/contrib/python/docs/source/examples/example2.rst new file mode 100644 index 000000000000..b1734386e7de --- /dev/null +++ b/contrib/python/docs/source/examples/example2.rst @@ -0,0 +1,100 @@ +.. _ex_dnssec: + +Querying DNS-SEC validators +=========================== + +This basic example shows how to query validating resolver and +evaluate answer. + +Resolving step by step +------------------------ + +For DNS queries, we need to initialize ldns resolver (covered in previous example). + +:: + + # Create resolver + resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf") + resolver.set_dnssec(True) + + # Custom resolver + if argc > 2: + # Clear previous nameservers + ns = resolver.pop_nameserver() + while ns != None: + ns = resolver.pop_nameserver() + ip = ldns.ldns_rdf.new_frm_str(sys.argv[2], ldns.LDNS_RDF_TYPE_A) + resolver.push_nameserver(ip) + +Note the second line :meth:`resolver.set_dnssec`, which enables DNSSEC OK bit +in queries in order to get meaningful results. + +As we have resolver initialized, we can start querying for domain names : + +:: + + # Resolve DNS name + pkt = resolver.query(name, ldns.LDNS_RR_TYPE_A, ldns.LDNS_RR_CLASS_IN) + if pkt and pkt.answer(): + +Now we evaluate result, where two flags are crucial : + + * Return code + * AD flag (authenticated) + +When return code is `SERVFAIL`, it means that validating resolver marked requested +name as **bogus** (or bad configuration). + +**AD** flag is set if domain name is authenticated **(secure)** or false if +it's insecure. + +Complete source code +-------------------- + + .. literalinclude:: ../../../examples/ldns-dnssec.py + :language: python + + +Testing +------- + +In order to get meaningful results, you have to enter IP address of validating +resolver or setup your own (see howto). + +Execute `./example2.py` with options `domain name` and `resolver IP`, +example: + +:: + + user@localhost# ./example2.py www.dnssec.cz 127.0.0.1 # Secure (Configured Unbound running on localhost) + user@localhost# ./example2.py www.rhybar.cz 127.0.0.1 # Bogus + +Howto setup Unbound as validating resolver +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Install Unbound according to instructions. +Modify following options in `unbound.conf` (located in `/etc` or `/usr/local/etc`)/ + + +Uncomment `module-config` and set `validator` before iterator. + +:: + + module-config: "validator iterator" + +Download DLV keys and update path in `unbound.conf`:: + + # DLV keys + # Download from http://ftp.isc.org/www/dlv/dlv.isc.org.key + dlv-anchor-file: "/usr/local/etc/unbound/dlv.isc.org.key" + +Update trusted keys (`.cz` for example):: + + # Trusted keys + # For current key, see www.dnssec.cz + trusted-keys-file: "/usr/local/etc/unbound/trusted.key" + +Now you should have well configured Unbound, so run it:: + + user@localhost# unbound -dv + diff --git a/contrib/python/docs/source/examples/example3.rst b/contrib/python/docs/source/examples/example3.rst new file mode 100644 index 000000000000..91f5e9d1448c --- /dev/null +++ b/contrib/python/docs/source/examples/example3.rst @@ -0,0 +1,7 @@ +High-level functions +=========================== + +This basic example shows how to get name by addr and vice versa. + +.. literalinclude:: ../../../examples/ldns-higher.py + :language: python diff --git a/contrib/python/docs/source/examples/example4.rst b/contrib/python/docs/source/examples/example4.rst new file mode 100644 index 000000000000..2f41f76bde71 --- /dev/null +++ b/contrib/python/docs/source/examples/example4.rst @@ -0,0 +1,7 @@ +AXFR client with IDN support +=============================== + +This example shows how to get AXFR working and how to get involved Internationalized Domain Names (IDN) + +.. literalinclude:: ../../../examples/ldns-axfr.py + :language: python diff --git a/contrib/python/docs/source/examples/example5.rst b/contrib/python/docs/source/examples/example5.rst new file mode 100644 index 000000000000..787c169265d7 --- /dev/null +++ b/contrib/python/docs/source/examples/example5.rst @@ -0,0 +1,14 @@ +Examine the results +=============================== + +This example shows how to go through the obtained results + +.. literalinclude:: ../../../examples/ldns-mx2.py + :language: python + +This snippet of code prints:: + + nic.cz. 1761 IN MX 20 mx.cznic.org. + nic.cz. 1761 IN MX 10 mail.nic.cz. + nic.cz. 1761 IN MX 15 mail4.nic.cz. + diff --git a/contrib/python/docs/source/examples/example6.rst b/contrib/python/docs/source/examples/example6.rst new file mode 100644 index 000000000000..d0fd68998017 --- /dev/null +++ b/contrib/python/docs/source/examples/example6.rst @@ -0,0 +1,12 @@ +Read zone file +=============================== + +This example shows how to read the content of a zone file + +.. literalinclude:: ../../../examples/ldns-zone.py + :language: python + +Zone file ``zone.txt``: + +.. literalinclude:: ../../../examples/zone.txt + diff --git a/contrib/python/docs/source/examples/example7.rst b/contrib/python/docs/source/examples/example7.rst new file mode 100644 index 000000000000..3e3e2dc22e52 --- /dev/null +++ b/contrib/python/docs/source/examples/example7.rst @@ -0,0 +1,8 @@ +Generate public/private key pair +======================================= + +This example shows how generate keys for DNSSEC (i.e. for signing a zone file according DNSSECbis). + +.. literalinclude:: ../../../examples/ldns-keygen.py + :language: python + diff --git a/contrib/python/docs/source/examples/example8.rst b/contrib/python/docs/source/examples/example8.rst new file mode 100644 index 000000000000..6fc550a86045 --- /dev/null +++ b/contrib/python/docs/source/examples/example8.rst @@ -0,0 +1,17 @@ +Signing of a zone file +=============================== + +This example shows how to sign the content of the given zone file + +.. literalinclude:: ../../../examples/ldns-signzone.py + :language: python + +In order to be able sign a zone file, you have to generate a key-pair using ``ldns-keygen.py``. Don't forget to modify tag number. + +Signing consists of three steps + +1. In the first step, the content of a zone file is readed and parsed. This can be done using :class:`ldns.ldns_zone` class. + +2. In the second step, the private and public key is readed and public key is inserted into zone (as DNSKEY). + +3. In the last step, the DNSSEC zone instace is created and all the RRs from zone file are copied here. Then, all the records are signed using :meth:`ldns.ldns_zone.sign` method. If the signing was successfull, the content of DNSSEC zone is written to a file. diff --git a/contrib/python/docs/source/examples/index.rst b/contrib/python/docs/source/examples/index.rst new file mode 100644 index 000000000000..8f7f381c3294 --- /dev/null +++ b/contrib/python/docs/source/examples/index.rst @@ -0,0 +1,12 @@ +Tutorials +============================== + +Here you can find a set of simple applications which utilizes the ldns library in Python environment. + +`Tutorials` + +.. toctree:: + :maxdepth: 1 + :glob: + + example* diff --git a/contrib/python/docs/source/index.rst b/contrib/python/docs/source/index.rst new file mode 100644 index 000000000000..d00b639d1acb --- /dev/null +++ b/contrib/python/docs/source/index.rst @@ -0,0 +1,22 @@ +PyLDNS documentation +======================================= + +PyLDNS provides an `LDNS`_ wrapper (Python extension module) - the thinnest layer over the library possible. Everything you can do from the C API, you can do from Python, but with less effort. The purpose of porting LDNS library to Python is to simplify DNS programming and usage of LDNS, however, still preserve the performance of this library as the speed represents the main benefit of LDNS. The proposed object approach allows the users to be concentrated at the essential part of application only and don't bother with deallocation of objects and so on. + +.. _LDNS: http://www.nlnetlabs.nl/projects/ldns/ + +Contents +---------- +.. toctree:: + :maxdepth: 2 + + install.rst + examples/index.rst + modules/ldns + +Indices and tables +------------------- + +* :ref:`genindex` +* :ref:`search` + diff --git a/contrib/python/docs/source/install.rst b/contrib/python/docs/source/install.rst new file mode 100644 index 000000000000..b3845b6e21b8 --- /dev/null +++ b/contrib/python/docs/source/install.rst @@ -0,0 +1,46 @@ +Installation +=================================== + +**Prerequisites** + +Python 2.4 or higher, SWIG 1.3 or higher, GNU make + +**Download** + +You can download the source codes `here`_. +The latest release is 1.4.1, Jan 15, 2009. + +.. _here: ldns-1.4.1-py.tar.gz + +**Compiling** + +After downloading, you can compile the library by doing:: + + > tar -xzf ldns-1.4.1-py.tar.gz + > cd ldns-1.4.1 + > ./configure --with-pyldns + > make + +You need GNU make to compile pyLDNS; SWIG and Python development libraries to compile extension module. + + +**Testing** + +If the compilation is successfull, you can test the python LDNS extension module by:: + + > cd contrib/python + > make testenv + > ./ldns-mx.py + +This will start a new shell, during which the symbolic links will be working. +When you exit the shell, then symbolic links will be deleted. + +In ``contrib/examples`` you can find many simple applications in python which demostrates the capabilities of LDNS library. + +**Installation** + +To install libraries and extension type:: + + > cd ldns-1.4.1 + > make install + diff --git a/contrib/python/docs/source/modules/ldns.rst b/contrib/python/docs/source/modules/ldns.rst new file mode 100644 index 000000000000..2c5e7b2455d6 --- /dev/null +++ b/contrib/python/docs/source/modules/ldns.rst @@ -0,0 +1,40 @@ +LDNS module documentation +================================ + +Here you can find the documentation of pyLDNS extension module. This module consists of several classes and a couple of functions. + +.. toctree:: + :maxdepth: 1 + :glob: + + ldns_resolver + ldns_pkt + ldns_rr + ldns_rdf + ldns_dname + ldns_rr_list + ldns_zone + ldns_key + ldns_key_list + ldns_buffer + ldns_dnssec + ldns_func + + + + +**Differences against libLDNS** + +* You don't need to use ldns-compare functions, instances can be compared using standard operators <, >, = :: + + if (some_rr.owner() == another_rr.rdf(1)): + pass + +* Classes contain static methods that create new instances, the name of these methods starts with the new\_ prefix (e.g. :meth:`ldns.ldns_pkt.new_frm_file`). + +* Is it possible to print the content of an object using ``print objinst`` (see :meth:`ldns.ldns_resolver.get_addr_by_name`). + +* Classes contain write_to_buffer method that writes the content into buffer. + +* All the methods that consume parameter of (const ldns_rdf) type allows to use string instead (see :meth:`ldns.ldns_resolver.query`). + diff --git a/contrib/python/docs/source/modules/ldns_buffer.rst b/contrib/python/docs/source/modules/ldns_buffer.rst new file mode 100644 index 000000000000..7f59e75e3edb --- /dev/null +++ b/contrib/python/docs/source/modules/ldns_buffer.rst @@ -0,0 +1,11 @@ +Class ldns_buffer +================================ + + +.. automodule:: ldns + +Class ldns_buffer +------------------------------ +.. autoclass:: ldns_buffer + :members: + :undoc-members: diff --git a/contrib/python/docs/source/modules/ldns_dname.rst b/contrib/python/docs/source/modules/ldns_dname.rst new file mode 100644 index 000000000000..18373bf8e661 --- /dev/null +++ b/contrib/python/docs/source/modules/ldns_dname.rst @@ -0,0 +1,11 @@ +Class ldns_dname +================================ + + +.. automodule:: ldns + +Class ldns_dname +------------------------------ +.. autoclass:: ldns_dname + :members: + :undoc-members: diff --git a/contrib/python/docs/source/modules/ldns_dnssec.rst b/contrib/python/docs/source/modules/ldns_dnssec.rst new file mode 100644 index 000000000000..bc5719dd557f --- /dev/null +++ b/contrib/python/docs/source/modules/ldns_dnssec.rst @@ -0,0 +1,28 @@ +Class ldns_dnssec_zone +================================ + +.. automodule:: ldns + +Class ldns_dnssec_zone +------------------------------ +.. autoclass:: ldns_dnssec_zone + :members: + :undoc-members: + +Class ldns_dnssec_name +------------------------------ +.. autoclass:: ldns_dnssec_name + :members: + :undoc-members: + +Class ldns_dnssec_rrsets +------------------------------ +.. autoclass:: ldns_dnssec_rrsets + :members: + :undoc-members: + +Class ldns_dnssec_rrs +------------------------------ +.. autoclass:: ldns_dnssec_rrs + :members: + :undoc-members: diff --git a/contrib/python/docs/source/modules/ldns_func.rst b/contrib/python/docs/source/modules/ldns_func.rst new file mode 100644 index 000000000000..7a9b8a8959fa --- /dev/null +++ b/contrib/python/docs/source/modules/ldns_func.rst @@ -0,0 +1,253 @@ +Various functions +================================ + +Here you can find list of functions that are not assigned to the classes. +These functions have the same parameters as LDNS functions of the same name. +You are encouraged to read the LDNS documentation. + +**List of functions** + + * ldns_algorithm2buffer_str + * ldns_bget_keyword_data + * ldns_bget_token + * ldns_bgetc + * ldns_bskipcs + * ldns_bubblebabble + * ldns_buffer2pkt_wire + * ldns_buffer2str + * ldns_calc_keytag + * ldns_calc_keytag_raw + * ldns_cert_algorithm2buffer_str + * ldns_convert_dsa_rrsig_asn12rdf + * ldns_convert_dsa_rrsig_rdf2asn1 + * ldns_create_nsec + * ldns_create_nsec3 + * ldns_dname2buffer_wire + * ldns_dname2canonical + * ldns_dnssec_build_data_chain + * ldns_dnssec_chain_nsec3_list + * ldns_dnssec_create_nsec + * ldns_dnssec_create_nsec3 + * ldns_dnssec_create_nsec_bitmap + * ldns_dnssec_data_chain_deep_free + * ldns_dnssec_data_chain_free + * ldns_dnssec_data_chain_new + * ldns_dnssec_data_chain_print + * ldns_dnssec_default_add_to_signatures + * ldns_dnssec_default_delete_signatures + * ldns_dnssec_default_leave_signatures + * ldns_dnssec_default_replace_signatures + * ldns_dnssec_derive_trust_tree + * ldns_dnssec_derive_trust_tree_dnskey_rrset + * ldns_dnssec_derive_trust_tree_ds_rrset + * ldns_dnssec_derive_trust_tree_no_sig + * ldns_dnssec_derive_trust_tree_normal_rrset + * ldns_dnssec_get_dnskey_for_rrsig + * ldns_dnssec_get_rrsig_for_name_and_type + * ldns_dnssec_nsec3_closest_encloser + * ldns_dnssec_pkt_get_rrsigs_for_name_and_type + * ldns_dnssec_pkt_get_rrsigs_for_type + * ldns_dnssec_pkt_has_rrsigs + * ldns_dnssec_remove_signatures + * ldns_dnssec_trust_tree_add_parent + * ldns_dnssec_trust_tree_contains_keys + * ldns_dnssec_trust_tree_depth + * ldns_dnssec_trust_tree_free + * ldns_dnssec_trust_tree_new + * ldns_dnssec_trust_tree_print + * ldns_dnssec_verify_denial + * ldns_dnssec_verify_denial_nsec3 + * ldns_fetch_valid_domain_keys + * ldns_fget_keyword_data + * ldns_fget_keyword_data_l + * ldns_fget_token + * ldns_fget_token_l + * ldns_fskipcs + * ldns_fskipcs_l + * ldns_get_bit + * ldns_get_bit_r + * ldns_get_errorstr_by_id + * ldns_get_rr_class_by_name + * ldns_get_rr_list_addr_by_name + * ldns_get_rr_list_hosts_frm_file + * ldns_get_rr_list_hosts_frm_fp + * ldns_get_rr_list_hosts_frm_fp_l + * ldns_get_rr_list_name_by_addr + * ldns_get_rr_type_by_name + * ldns_getaddrinfo + * ldns_hexdigit_to_int + * ldns_hexstring_to_data + * ldns_init_random + * ldns_int_to_hexdigit + * ldns_is_rrset + * ldns_key2buffer_str + * ldns_key2rr + * ldns_key2str + * ldns_lookup_by_id + * ldns_lookup_by_name + * ldns_native2rdf_int16 + * ldns_native2rdf_int16_data + * ldns_native2rdf_int32 + * ldns_native2rdf_int8 + * ldns_nsec3_add_param_rdfs + * ldns_nsec3_algorithm + * ldns_nsec3_bitmap + * ldns_nsec3_flags + * ldns_nsec3_hash_name + * ldns_nsec3_hash_name_frm_nsec3 + * ldns_nsec3_iterations + * ldns_nsec3_next_owner + * ldns_nsec3_optout + * ldns_nsec3_salt + * ldns_nsec3_salt_data + * ldns_nsec3_salt_length + * ldns_nsec_bitmap_covers_type + * ldns_nsec_covers_name + * ldns_nsec_get_bitmap + * ldns_nsec_type_check + * ldns_octet + * ldns_pkt2buffer_str + * ldns_pkt2buffer_wire + * ldns_pkt2str + * ldns_pkt2wire + * ldns_pktheader2buffer_str + * ldns_power + * ldns_print_rr_rdf + * ldns_rbtree_create + * ldns_rbtree_delete + * ldns_rbtree_find_less_equal + * ldns_rbtree_first + * ldns_rbtree_free + * ldns_rbtree_init + * ldns_rbtree_insert + * ldns_rbtree_insert_vref + * ldns_rbtree_last + * ldns_rbtree_next + * ldns_rbtree_previous + * ldns_rbtree_search + * ldns_rdf2buffer_str + * ldns_rdf2buffer_str_a + * ldns_rdf2buffer_str_aaaa + * ldns_rdf2buffer_str_alg + * ldns_rdf2buffer_str_apl + * ldns_rdf2buffer_str_b64 + * ldns_rdf2buffer_str_cert_alg + * ldns_rdf2buffer_str_class + * ldns_rdf2buffer_str_dname + * ldns_rdf2buffer_str_hex + * ldns_rdf2buffer_str_int16 + * ldns_rdf2buffer_str_int16_data + * ldns_rdf2buffer_str_ipseckey + * ldns_rdf2buffer_str_loc + * ldns_rdf2buffer_str_nsap + * ldns_rdf2buffer_str_nsec + * ldns_rdf2buffer_str_period + * ldns_rdf2buffer_str_str + * ldns_rdf2buffer_str_tsig + * ldns_rdf2buffer_str_tsigtime + * ldns_rdf2buffer_str_type + * ldns_rdf2buffer_str_unknown + * ldns_rdf2buffer_str_wks + * ldns_rdf2buffer_wire + * ldns_rdf2buffer_wire_canonical + * ldns_rdf2native_int16 + * ldns_rdf2native_int32 + * ldns_rdf2native_int8 + * ldns_rdf2native_sockaddr_storage + * ldns_rdf2native_time_t + * ldns_rdf2rr_type + * ldns_rdf2str + * ldns_rdf2wire + * ldns_read_anchor_file + * ldns_read_uint16 + * ldns_read_uint32 + * ldns_rr2buffer_str + * ldns_rr2buffer_wire + * ldns_rr2buffer_wire_canonical + * ldns_rr2canonical + * ldns_rr2str + * ldns_rr2wire + * ldns_rrsig2buffer_wire + * ldns_send + * ldns_send_buffer + * ldns_set_bit + * ldns_sign_public + * ldns_sockaddr_storage2rdf + * ldns_str2period + * ldns_str2rdf_a + * ldns_str2rdf_aaaa + * ldns_str2rdf_alg + * ldns_str2rdf_apl + * ldns_str2rdf_b32_ext + * ldns_str2rdf_b64 + * ldns_str2rdf_cert_alg + * ldns_str2rdf_class + * ldns_str2rdf_dname + * ldns_str2rdf_hex + * ldns_str2rdf_int16 + * ldns_str2rdf_int32 + * ldns_str2rdf_int8 + * ldns_str2rdf_loc + * ldns_str2rdf_nsap + * ldns_str2rdf_nsec + * ldns_str2rdf_nsec3_salt + * ldns_str2rdf_period + * ldns_str2rdf_service + * ldns_str2rdf_str + * ldns_str2rdf_time + * ldns_str2rdf_tsig + * ldns_str2rdf_type + * ldns_str2rdf_unknown + * ldns_str2rdf_wks + * ldns_tcp_bgsend + * ldns_tcp_connect + * ldns_tcp_read_wire + * ldns_tcp_send + * ldns_tcp_send_query + * ldns_traverse_postorder + * ldns_tsig_algorithm + * ldns_tsig_keydata + * ldns_tsig_keydata_clone + * ldns_tsig_keyname + * ldns_tsig_keyname_clone + * ldns_udp_bgsend + * ldns_udp_connect + * ldns_udp_read_wire + * ldns_udp_send + * ldns_udp_send_query + * ldns_update_pkt_new + * ldns_update_pkt_tsig_add + * ldns_update_prcount + * ldns_update_set_adcount + * ldns_update_set_prcount + * ldns_update_set_upcount + * ldns_update_soa_mname + * ldns_update_soa_zone_mname + * ldns_update_upcount + * ldns_update_zocount + * ldns_validate_domain_dnskey + * ldns_validate_domain_ds + * ldns_verify + * ldns_verify_rrsig + * ldns_verify_rrsig_buffers + * ldns_verify_rrsig_buffers_raw + * ldns_verify_rrsig_dsa + * ldns_verify_rrsig_dsa_raw + * ldns_verify_rrsig_keylist + * ldns_verify_rrsig_rsamd5 + * ldns_verify_rrsig_rsamd5_raw + * ldns_verify_rrsig_rsasha1 + * ldns_verify_rrsig_rsasha1_raw + * ldns_verify_rrsig_rsasha256_raw + * ldns_verify_rrsig_rsasha512_raw + * ldns_verify_trusted + * ldns_version + * ldns_wire2dname + * ldns_wire2pkt + * ldns_wire2rdf + * ldns_wire2rr + * ldns_write_uint16 + * ldns_write_uint32 + * ldns_write_uint64_as_uint48 + * mktime_from_utc + * qsort_rr_compare_nsec3 diff --git a/contrib/python/docs/source/modules/ldns_key.rst b/contrib/python/docs/source/modules/ldns_key.rst new file mode 100644 index 000000000000..4d35766b7995 --- /dev/null +++ b/contrib/python/docs/source/modules/ldns_key.rst @@ -0,0 +1,11 @@ +Class ldns_key +================================ + + +.. automodule:: ldns + +Class ldns_key +------------------------------ +.. autoclass:: ldns_key + :members: + :undoc-members: diff --git a/contrib/python/docs/source/modules/ldns_key_list.rst b/contrib/python/docs/source/modules/ldns_key_list.rst new file mode 100644 index 000000000000..e8e447452e3e --- /dev/null +++ b/contrib/python/docs/source/modules/ldns_key_list.rst @@ -0,0 +1,11 @@ +Class ldns_key_list +================================ + + +.. automodule:: ldns + +Class ldns_key_list +------------------------------ +.. autoclass:: ldns_key_list + :members: + :undoc-members: diff --git a/contrib/python/docs/source/modules/ldns_pkt.rst b/contrib/python/docs/source/modules/ldns_pkt.rst new file mode 100644 index 000000000000..eb00a0bc077c --- /dev/null +++ b/contrib/python/docs/source/modules/ldns_pkt.rst @@ -0,0 +1,11 @@ +Class ldns_pkt +================================ + + +.. automodule:: ldns + +Class ldns_pkt +------------------------------ +.. autoclass:: ldns_pkt + :members: + :undoc-members: diff --git a/contrib/python/docs/source/modules/ldns_rdf.rst b/contrib/python/docs/source/modules/ldns_rdf.rst new file mode 100644 index 000000000000..5ed1799b1bb1 --- /dev/null +++ b/contrib/python/docs/source/modules/ldns_rdf.rst @@ -0,0 +1,47 @@ +Class ldns_rdf +================================ + + +.. automodule:: ldns + +Class ldns_rdf +------------------------------ +.. autoclass:: ldns_rdf + :members: + :undoc-members: + +Predefined constants +------------------------------ + +**RDF TYPE** + * LDNS_RDF_TYPE_NONE, + * LDNS_RDF_TYPE_DNAME, + * LDNS_RDF_TYPE_INT8, + * LDNS_RDF_TYPE_INT16, + * LDNS_RDF_TYPE_INT32, + * LDNS_RDF_TYPE_A, + * LDNS_RDF_TYPE_AAAA, + * LDNS_RDF_TYPE_STR, + * LDNS_RDF_TYPE_APL, + * LDNS_RDF_TYPE_B32_EXT, + * LDNS_RDF_TYPE_B64, + * LDNS_RDF_TYPE_HEX, + * LDNS_RDF_TYPE_NSEC, + * LDNS_RDF_TYPE_TYPE, + * LDNS_RDF_TYPE_CLASS, + * LDNS_RDF_TYPE_CERT_ALG, + * LDNS_RDF_TYPE_ALG, + * LDNS_RDF_TYPE_UNKNOWN, + * LDNS_RDF_TYPE_TIME, + * LDNS_RDF_TYPE_PERIOD, + * LDNS_RDF_TYPE_TSIGTIME, + * LDNS_RDF_TYPE_TSIG, + * LDNS_RDF_TYPE_INT16_DATA, + * LDNS_RDF_TYPE_SERVICE, + * LDNS_RDF_TYPE_LOC, + * LDNS_RDF_TYPE_WKS, + * LDNS_RDF_TYPE_NSAP, + * LDNS_RDF_TYPE_IPSECKEY, + * LDNS_RDF_TYPE_NSEC3_SALT, + * LDNS_RDF_TYPE_NSEC3_NEXT_OWNER + diff --git a/contrib/python/docs/source/modules/ldns_resolver.rst b/contrib/python/docs/source/modules/ldns_resolver.rst new file mode 100644 index 000000000000..2fda23a2f016 --- /dev/null +++ b/contrib/python/docs/source/modules/ldns_resolver.rst @@ -0,0 +1,13 @@ +Class ldns_resolver +================================ + +.. automodule:: ldns + +Class ldns_resolver +------------------------------ +.. autoclass:: ldns_resolver + :members: + :undoc-members: + + + diff --git a/contrib/python/docs/source/modules/ldns_rr.rst b/contrib/python/docs/source/modules/ldns_rr.rst new file mode 100644 index 000000000000..78404cda0dcc --- /dev/null +++ b/contrib/python/docs/source/modules/ldns_rr.rst @@ -0,0 +1,18 @@ +Class ldns_rr +================================ + + +.. automodule:: ldns + +Class ldns_rr +------------------------------ +.. autoclass:: ldns_rr + :members: + :undoc-members: + +Class ldns_rr_descriptor +------------------------------ +.. autoclass:: ldns_rr_descriptor + :members: + :undoc-members: + diff --git a/contrib/python/docs/source/modules/ldns_rr_list.rst b/contrib/python/docs/source/modules/ldns_rr_list.rst new file mode 100644 index 000000000000..f044093790e5 --- /dev/null +++ b/contrib/python/docs/source/modules/ldns_rr_list.rst @@ -0,0 +1,11 @@ +Class ldns_rr_list +================================ + + +.. automodule:: ldns + +Class ldns_rr_list +------------------------------ +.. autoclass:: ldns_rr_list + :members: + :undoc-members: diff --git a/contrib/python/docs/source/modules/ldns_zone.rst b/contrib/python/docs/source/modules/ldns_zone.rst new file mode 100644 index 000000000000..5331429222ce --- /dev/null +++ b/contrib/python/docs/source/modules/ldns_zone.rst @@ -0,0 +1,11 @@ +Class ldns_zone +================================ + + +.. automodule:: ldns + +Class ldns_zone +------------------------------ +.. autoclass:: ldns_zone + :members: + :undoc-members: diff --git a/contrib/python/examples/ldns-axfr.py b/contrib/python/examples/ldns-axfr.py new file mode 100755 index 000000000000..5333484fa11a --- /dev/null +++ b/contrib/python/examples/ldns-axfr.py @@ -0,0 +1,56 @@ +#!/usr/bin/python +# vim:fileencoding=utf-8 +# +# AXFR client with IDN (Internationalized Domain Names) support +# + +import ldns +import encodings.idna + +def utf2name(name): + return '.'.join([encodings.idna.ToASCII(a) for a in name.split('.')]) +def name2utf(name): + return '.'.join([encodings.idna.ToUnicode(a) for a in name.split('.')]) + + +resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf") + +#addr = ldns.ldns_get_rr_list_addr_by_name(resolver, "zone.nic.cz", ldns.LDNS_RR_CLASS_IN, ldns.LDNS_RD); +addr = resolver.get_addr_by_name("zone.nic.cz", ldns.LDNS_RR_CLASS_IN, ldns.LDNS_RD); +if (not addr): + raise Exception("Can't retrieve server address") + +print "Addr_by_name:",str(addr).replace("\n","; ") + +#remove all nameservers +while resolver.pop_nameserver(): + pass + +#insert server addr +for rr in addr.rrs(): + resolver.push_nameserver_rr(rr) + +#AXFR transfer +status = resolver.axfr_start(utf2name(u"háčkyčárky.cz"), ldns.LDNS_RR_CLASS_IN) +if status != ldns.LDNS_STATUS_OK: + raise Exception("Can't start AXFR. Error: %s" % ldns.ldns_get_errorstr_by_id(status)) + +#Print results +while True: + rr = resolver.axfr_next() + if not rr: + break + + rdf = rr.owner() + if (rdf.get_type() == ldns.LDNS_RDF_TYPE_DNAME): + print "RDF owner: type=",rdf.get_type_str(),"data=",name2utf(str(rdf)) + else: + print "RDF owner: type=",rdf.get_type_str(),"data=",str(rdf) + print " RR type=", rr.get_type_str()," ttl=",rr.ttl() + for rdf in rr.rdfs(): + if (rdf.get_type() == ldns.LDNS_RDF_TYPE_DNAME): + print " RDF: type=",rdf.get_type_str(),"data=",name2utf(str(rdf)) + else: + print " RDF: type=",rdf.get_type_str(),"data=",str(rdf) + + print diff --git a/contrib/python/examples/ldns-buf.py b/contrib/python/examples/ldns-buf.py new file mode 100755 index 000000000000..73d8a029ffb0 --- /dev/null +++ b/contrib/python/examples/ldns-buf.py @@ -0,0 +1,8 @@ +#!/usr/bin/python + +import ldns + +buf = ldns.ldns_buffer(1024) +buf.printf("Test buffer") +print buf + diff --git a/contrib/python/examples/ldns-dnssec.py b/contrib/python/examples/ldns-dnssec.py new file mode 100755 index 000000000000..bb2acfdf762a --- /dev/null +++ b/contrib/python/examples/ldns-dnssec.py @@ -0,0 +1,45 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +import ldns +import sys + +debug = True + +# Check args +argc = len(sys.argv) +name = "www.nic.cz" +if argc < 2: + print "Usage:", sys.argv[0], "domain [resolver_addr]" + sys.exit(1) +else: + name = sys.argv[1] + +# Create resolver +resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf") +resolver.set_dnssec(True) + +# Custom resolver +if argc > 2: + # Clear previous nameservers + ns = resolver.pop_nameserver() + while ns != None: + ns = resolver.pop_nameserver() + ip = ldns.ldns_rdf.new_frm_str(sys.argv[2], ldns.LDNS_RDF_TYPE_A) + resolver.push_nameserver(ip) + +# Resolve DNS name +pkt = resolver.query(name, ldns.LDNS_RR_TYPE_A, ldns.LDNS_RR_CLASS_IN) +if pkt and pkt.answer(): + + # Debug + if debug: + print "NS returned:", pkt.get_rcode(), "(AA: %d AD: %d)" % ( pkt.ad(), pkt.ad() ) + + # SERVFAIL indicated bogus name + if pkt.get_rcode() is ldns.LDNS_RCODE_SERVFAIL: + print name, "is bogus" + + # Check AD (Authenticated) bit + if pkt.get_rcode() is ldns.LDNS_RCODE_NOERROR: + if pkt.ad(): print name, "is secure" + else: print name, "is insecure" diff --git a/contrib/python/examples/ldns-higher.py b/contrib/python/examples/ldns-higher.py new file mode 100755 index 000000000000..5175ec0e7ae9 --- /dev/null +++ b/contrib/python/examples/ldns-higher.py @@ -0,0 +1,36 @@ +#!/usr/bin/python +import ldns + +resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf") + +dnn = ldns.ldns_dname("www.google.com") +print dnn.get_type_str(), dnn + +dna = ldns.ldns_rdf.new_frm_str("74.125.43.99",ldns.LDNS_RDF_TYPE_A) +print dna.get_type_str(), dna + +name = resolver.get_name_by_addr(dna) +if (not name): raise Exception("Can't retrieve server name") +for rr in name.rrs(): + print rr + +name = resolver.get_name_by_addr("74.125.43.99") +if (not name): raise Exception("Can't retrieve server name") +for rr in name.rrs(): + print rr + +addr = resolver.get_addr_by_name(dnn) +if (not addr): raise Exception("Can't retrieve server address") +for rr in addr.rrs(): + print rr + +addr = resolver.get_addr_by_name("www.google.com") +if (not addr): raise Exception("Can't retrieve server address") +for rr in addr.rrs(): + print rr + +hosts = ldns.ldns_rr_list.new_frm_file("/etc/hosts") +if (not hosts): raise Exception("Can't retrieve the content of file") +for rr in hosts.rrs(): + print rr + diff --git a/contrib/python/examples/ldns-keygen.py b/contrib/python/examples/ldns-keygen.py new file mode 100755 index 000000000000..3ddf41a946e6 --- /dev/null +++ b/contrib/python/examples/ldns-keygen.py @@ -0,0 +1,46 @@ +#!/usr/bin/python +# +# This example shows how to generate public/private key pair +# +import ldns + +algorithm = ldns.LDNS_SIGN_DSA +bits = 512 + +ldns.ldns_init_random(open("/dev/random","rb"), (bits+7)//8) + +domain = ldns.ldns_dname("example.") + +#generate a new key +key = ldns.ldns_key.new_frm_algorithm(algorithm, bits); +print key + +#set owner +key.set_pubkey_owner(domain) + +#create the public from the ldns_key +pubkey = key.key_to_rr() +#previous command is equivalent to +# pubkey = ldns.ldns_key2rr(key) +print pubkey + +#calculate and set the keytag +key.set_keytag(ldns.ldns_calc_keytag(pubkey)) + +#build the DS record +ds = ldns.ldns_key_rr2ds(pubkey, ldns.LDNS_SHA1) +print ds + +owner, tag = pubkey.owner(), key.keytag() + +#write public key to .key file +fw = open("key-%s-%d.key" % (owner,tag), "wb") +pubkey.print_to_file(fw) + +#write private key to .priv file +fw = open("key-%s-%d.private" % (owner,tag), "wb") +key.print_to_file(fw) + +#write DS to .ds file +fw = open("key-%s-%d.ds" % (owner,tag), "wb") +ds.print_to_file(fw) diff --git a/contrib/python/examples/ldns-mx.py b/contrib/python/examples/ldns-mx.py new file mode 100755 index 000000000000..38c3f11c1631 --- /dev/null +++ b/contrib/python/examples/ldns-mx.py @@ -0,0 +1,15 @@ +#!/usr/bin/python +# +# MX is a small program that prints out the mx records for a particular domain +# +import ldns + +resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf") + +pkt = resolver.query("nic.cz", ldns.LDNS_RR_TYPE_MX,ldns.LDNS_RR_CLASS_IN) + +if (pkt): + mx = pkt.rr_list_by_type(ldns.LDNS_RR_TYPE_MX, ldns.LDNS_SECTION_ANSWER) + if (mx): + mx.sort() + print mx diff --git a/contrib/python/examples/ldns-mx1.py b/contrib/python/examples/ldns-mx1.py new file mode 100755 index 000000000000..3dade1ed3d36 --- /dev/null +++ b/contrib/python/examples/ldns-mx1.py @@ -0,0 +1,18 @@ +#!/usr/bin/python +# +# MX is a small program that prints out the mx records for a particular domain +# +import ldns + +dname = ldns.ldns_dname("nic.cz") +print dname + +resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf") + +pkt = resolver.query(dname, ldns.LDNS_RR_TYPE_MX,ldns.LDNS_RR_CLASS_IN) + +if (pkt): + mx = pkt.rr_list_by_type(ldns.LDNS_RR_TYPE_MX, ldns.LDNS_SECTION_ANSWER) + if (mx): + mx.sort() + print mx diff --git a/contrib/python/examples/ldns-mx2.py b/contrib/python/examples/ldns-mx2.py new file mode 100755 index 000000000000..4fff98a4b1d6 --- /dev/null +++ b/contrib/python/examples/ldns-mx2.py @@ -0,0 +1,19 @@ +#!/usr/bin/python +# +# MX is a small program that prints out the mx records for a particular domain +# +import ldns + +resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf") + +pkt = resolver.query("nic.cz", ldns.LDNS_RR_TYPE_MX,ldns.LDNS_RR_CLASS_IN) +if (pkt) and (pkt.answer()): + + for rr in pkt.answer().rrs(): + if (rr.get_type() != ldns.LDNS_RR_TYPE_MX): + continue + + rdf = rr.owner() + print rdf," ",rr.ttl()," ",rr.get_class_str()," ",rr.get_type_str()," ", + print " ".join(str(rdf) for rdf in rr.rdfs()) + diff --git a/contrib/python/examples/ldns-newpkt.py b/contrib/python/examples/ldns-newpkt.py new file mode 100755 index 000000000000..d124a80f80e7 --- /dev/null +++ b/contrib/python/examples/ldns-newpkt.py @@ -0,0 +1,17 @@ +#!/usr/bin/python + +import ldns + +pkt = ldns.ldns_pkt.new_query_frm_str("www.google.com",ldns.LDNS_RR_TYPE_ANY, ldns.LDNS_RR_CLASS_IN, ldns.LDNS_QR | ldns.LDNS_AA) + +rra = ldns.ldns_rr.new_frm_str("www.google.com. IN A 192.168.1.1",300) +rrb = ldns.ldns_rr.new_frm_str("www.google.com. IN TXT Some\ Description",300) + +list = ldns.ldns_rr_list() +if (rra): list.push_rr(rra) +if (rrb): list.push_rr(rrb) + +pkt.push_rr_list(ldns.LDNS_SECTION_ANSWER, list) + +print "Packet:" +print pkt diff --git a/contrib/python/examples/ldns-signzone.py b/contrib/python/examples/ldns-signzone.py new file mode 100755 index 000000000000..41f76626eae3 --- /dev/null +++ b/contrib/python/examples/ldns-signzone.py @@ -0,0 +1,65 @@ +#!/usr/bin/python +# This example shows how to sign a given zone file with private key + +import ldns +import sys, os, time + +#private key TAG which identifies the private key +#use ldns-keygen.py in order to obtain private key +keytag = 30761 + +# Read zone file +#------------------------------------------------------------- + +zone = ldns.ldns_zone.new_frm_fp(open("zone.txt","r"), None, 0, ldns.LDNS_RR_CLASS_IN) +soa = zone.soa() +origin = soa.owner() + +# Prepare keys +#------------------------------------------------------------- + +#Read private key from file +keyfile = open("key-%s-%d.private" % (origin, keytag), "r"); +key = ldns.ldns_key.new_frm_fp(keyfile) + +#Read public key from file +pubfname = "key-%s-%d.key" % (origin, keytag) +pubkey = None +if os.path.isfile(pubfname): + pubkeyfile = open(pubfname, "r"); + pubkey,_,_,_ = ldns.ldns_rr.new_frm_fp(pubkeyfile) + +if not pubkey: + #Create new public key + pubkey = key.key_to_rr() + +#Set key expiration +key.set_expiration(int(time.time()) + 365*60*60*24) #365 days + +#Set key owner (important step) +key.set_pubkey_owner(origin) + +#Insert DNSKEY RR +zone.push_rr(pubkey) + +# Sign zone +#------------------------------------------------------------- + +#Create keylist and push private key +keys = ldns.ldns_key_list() +keys.push_key(key) + +#Add SOA +signed_zone = ldns.ldns_dnssec_zone() +signed_zone.add_rr(soa) + +#Add RRs +for rr in zone.rrs().rrs(): + print "RR:",str(rr), + signed_zone.add_rr(rr) + +added_rrs = ldns.ldns_rr_list() +status = signed_zone.sign(added_rrs, keys) +if (status == ldns.LDNS_STATUS_OK): + signed_zone.print_to_file(open("zone_signed.txt","w")) + diff --git a/contrib/python/examples/ldns-zone.py b/contrib/python/examples/ldns-zone.py new file mode 100755 index 000000000000..266e6e5b4719 --- /dev/null +++ b/contrib/python/examples/ldns-zone.py @@ -0,0 +1,15 @@ +#!/usr/bin/python +import ldns + +#Read zone from file +zone = ldns.ldns_zone.new_frm_fp(open("zone.txt","r"), None, 0, ldns.LDNS_RR_CLASS_IN) +print zone + +print "SOA:", zone.soa() +for r in zone.rrs().rrs(): + print "RR:", r + + +zone = ldns.ldns_zone() +#print zone + diff --git a/contrib/python/examples/ldns_rr_iter_frm_fp_l.demo.py b/contrib/python/examples/ldns_rr_iter_frm_fp_l.demo.py new file mode 100644 index 000000000000..e123f90dbc6a --- /dev/null +++ b/contrib/python/examples/ldns_rr_iter_frm_fp_l.demo.py @@ -0,0 +1,15 @@ +import ldns +import sys + +if len(sys.argv) <= 1: + print "Usage: %s zone_file" % sys.argv[0] + sys.exit() + +inp = open(sys.argv[1],"r"); +for rr in ldns.ldns_rr_iter_frm_fp_l(inp): + print rr + +inp.close() + + + diff --git a/contrib/python/examples/ldns_rr_new_frm_fp_l.demo.py b/contrib/python/examples/ldns_rr_new_frm_fp_l.demo.py new file mode 100644 index 000000000000..70992254b6a0 --- /dev/null +++ b/contrib/python/examples/ldns_rr_new_frm_fp_l.demo.py @@ -0,0 +1,43 @@ +import ldns +import sys + +if len(sys.argv) <= 1: + print "Usage: %s zone_file" % sys.argv[0] + sys.exit() + +inp = open(sys.argv[1],"r"); +# variables that preserve the parsers state +my_ttl = 3600; +my_origin = None +my_prev = None +# additional state variables +last_pos = 0 +line_nr = 0 + +while True: + ret = ldns.ldns_rr_new_frm_fp_l_(inp, my_ttl, my_origin, my_prev) + s, rr, line_inc, new_ttl, new_origin, new_prev = ret # unpack the result + line_nr += line_inc # increase number of parsed lines + my_prev = new_prev # update ref to previous owner + + if s == ldns.LDNS_STATUS_SYNTAX_TTL: + my_ttl = new_ttl # update default TTL + print "$TTL:", my_ttl + elif s == ldns.LDNS_STATUS_SYNTAX_ORIGIN: + my_origin = new_origin # update reference to origin + print "$ORIGIN:", my_origin + elif s == ldns.LDNS_STATUS_SYNTAX_EMPTY: + if last_pos == inp.tell(): + break # no advance since last read - EOF + last_pos = inp.tell() + elif s != ldns.LDNS_STATUS_OK: + print "! parse error in line", line_nr + else: + # we are sure to have LDNS_STATUS_OK + print rr + +inp.close() +print "--------------------" +print "Read %d lines" % line_nr + + diff --git a/contrib/python/examples/python3/ldns-axfr.py b/contrib/python/examples/python3/ldns-axfr.py new file mode 100755 index 000000000000..fb8e5cf5e2f7 --- /dev/null +++ b/contrib/python/examples/python3/ldns-axfr.py @@ -0,0 +1,56 @@ +#!/usr/bin/python +# vim:fileencoding=utf-8 +# +# AXFR client with IDN (Internationalized Domain Names) support +# + +import ldns +import encodings.idna + +def utf2name(name): + return '.'.join([encodings.idna.ToASCII(a).decode("utf-8") for a in name.split('.')]) +def name2utf(name): + return '.'.join([encodings.idna.ToUnicode(a) for a in name.split('.')]) + + +resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf") + +#addr = ldns.ldns_get_rr_list_addr_by_name(resolver, "zone.nic.cz", ldns.LDNS_RR_CLASS_IN, ldns.LDNS_RD); +addr = resolver.get_addr_by_name("zone.nic.cz", ldns.LDNS_RR_CLASS_IN, ldns.LDNS_RD); +if (not addr): + raise Exception("Can't retrieve server address") + +print("Addr_by_name:",str(addr).replace("\n","; ")) + +#remove all nameservers +while resolver.pop_nameserver(): + pass + +#insert server addr +for rr in addr.rrs(): + resolver.push_nameserver_rr(rr) + +#AXFR transfer +status = resolver.axfr_start(utf2name("háčkyčárky.cz"), ldns.LDNS_RR_CLASS_IN) +if status != ldns.LDNS_STATUS_OK: + raise Exception("Can't start AXFR. Error: %s" % ldns.ldns_get_errorstr_by_id(status)) + +#Print results +while True: + rr = resolver.axfr_next() + if not rr: + break + + rdf = rr.owner() + if (rdf.get_type() == ldns.LDNS_RDF_TYPE_DNAME): + print("RDF owner: type=",rdf.get_type_str(),"data=",name2utf(str(rdf))) + else: + print("RDF owner: type=",rdf.get_type_str(),"data=",str(rdf)) + print(" RR type=", rr.get_type_str()," ttl=",rr.ttl()) + for rdf in rr.rdfs(): + if (rdf.get_type() == ldns.LDNS_RDF_TYPE_DNAME): + print(" RDF: type=",rdf.get_type_str(),"data=",name2utf(str(rdf))) + else: + print(" RDF: type=",rdf.get_type_str(),"data=",str(rdf)) + + print() diff --git a/contrib/python/examples/python3/ldns-buf.py b/contrib/python/examples/python3/ldns-buf.py new file mode 100755 index 000000000000..498d51f6c3af --- /dev/null +++ b/contrib/python/examples/python3/ldns-buf.py @@ -0,0 +1,8 @@ +#!/usr/bin/python + +import ldns + +buf = ldns.ldns_buffer(1024) +buf.printf("Test buffer") +print(buf) + diff --git a/contrib/python/examples/python3/ldns-dnssec.py b/contrib/python/examples/python3/ldns-dnssec.py new file mode 100755 index 000000000000..7dabb9179025 --- /dev/null +++ b/contrib/python/examples/python3/ldns-dnssec.py @@ -0,0 +1,45 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +import ldns +import sys + +debug = True + +# Check args +argc = len(sys.argv) +name = "www.nic.cz" +if argc < 2: + print("Usage:", sys.argv[0], "domain [resolver_addr]") + sys.exit(1) +else: + name = sys.argv[1] + +# Create resolver +resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf") +resolver.set_dnssec(True) + +# Custom resolver +if argc > 2: + # Clear previous nameservers + ns = resolver.pop_nameserver() + while ns != None: + ns = resolver.pop_nameserver() + ip = ldns.ldns_rdf.new_frm_str(sys.argv[2], ldns.LDNS_RDF_TYPE_A) + resolver.push_nameserver(ip) + +# Resolve DNS name +pkt = resolver.query(name, ldns.LDNS_RR_TYPE_A, ldns.LDNS_RR_CLASS_IN) +if pkt and pkt.answer(): + + # Debug + if debug: + print("NS returned:", pkt.get_rcode(), "(AA: %d AD: %d)" % ( pkt.ad(), pkt.ad() )) + + # SERVFAIL indicated bogus name + if pkt.get_rcode() is ldns.LDNS_RCODE_SERVFAIL: + print(name, "is bogus") + + # Check AD (Authenticated) bit + if pkt.get_rcode() is ldns.LDNS_RCODE_NOERROR: + if pkt.ad(): print(name, "is secure") + else: print(name, "is insecure") diff --git a/contrib/python/examples/python3/ldns-higher.py b/contrib/python/examples/python3/ldns-higher.py new file mode 100755 index 000000000000..8712e63178d7 --- /dev/null +++ b/contrib/python/examples/python3/ldns-higher.py @@ -0,0 +1,36 @@ +#!/usr/bin/python +import ldns + +resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf") + +dnn = ldns.ldns_dname("www.google.com") +print(dnn.get_type_str(), dnn) + +dna = ldns.ldns_rdf.new_frm_str("74.125.43.99",ldns.LDNS_RDF_TYPE_A) +print(dna.get_type_str(), dna) + +name = resolver.get_name_by_addr(dna) +if (not name): raise Exception("Can't retrieve server name") +for rr in name.rrs(): + print(rr) + +name = resolver.get_name_by_addr("74.125.43.99") +if (not name): raise Exception("Can't retrieve server name") +for rr in name.rrs(): + print(rr) + +addr = resolver.get_addr_by_name(dnn) +if (not addr): raise Exception("Can't retrieve server address") +for rr in addr.rrs(): + print(rr) + +addr = resolver.get_addr_by_name("www.google.com") +if (not addr): raise Exception("Can't retrieve server address") +for rr in addr.rrs(): + print(rr) + +hosts = ldns.ldns_rr_list.new_frm_file("/etc/hosts") +if (not hosts): raise Exception("Can't retrieve the content of file") +for rr in hosts.rrs(): + print(rr) + diff --git a/contrib/python/examples/python3/ldns-keygen.py b/contrib/python/examples/python3/ldns-keygen.py new file mode 100755 index 000000000000..4a5457e4988d --- /dev/null +++ b/contrib/python/examples/python3/ldns-keygen.py @@ -0,0 +1,46 @@ +#!/usr/bin/python +# +# This example shows how to generate public/private key pair +# +import ldns + +algorithm = ldns.LDNS_SIGN_DSA +bits = 512 + +ldns.ldns_init_random(open("/dev/random","rb"), (bits+7)//8) + +domain = ldns.ldns_dname("example.") + +#generate a new key +key = ldns.ldns_key.new_frm_algorithm(algorithm, bits); +print(key) + +#set owner +key.set_pubkey_owner(domain) + +#create the public from the ldns_key +pubkey = key.key_to_rr() +#previous command is equivalent to +# pubkey = ldns.ldns_key2rr(key) +print(pubkey) + +#calculate and set the keytag +key.set_keytag(ldns.ldns_calc_keytag(pubkey)) + +#build the DS record +ds = ldns.ldns_key_rr2ds(pubkey, ldns.LDNS_SHA1) +print(ds) + +owner, tag = pubkey.owner(), key.keytag() + +#write public key to .key file +fw = open("key-%s-%d.key" % (owner,tag), "wb") +pubkey.print_to_file(fw) + +#write private key to .priv file +fw = open("key-%s-%d.private" % (owner,tag), "wb") +key.print_to_file(fw) + +#write DS to .ds file +fw = open("key-%s-%d.ds" % (owner,tag), "wb") +ds.print_to_file(fw) diff --git a/contrib/python/examples/python3/ldns-mx.py b/contrib/python/examples/python3/ldns-mx.py new file mode 100755 index 000000000000..1d2ba03669cc --- /dev/null +++ b/contrib/python/examples/python3/ldns-mx.py @@ -0,0 +1,15 @@ +#!/usr/bin/python +# +# MX is a small program that prints out the mx records for a particular domain +# +import ldns + +resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf") + +pkt = resolver.query("nic.cz", ldns.LDNS_RR_TYPE_MX,ldns.LDNS_RR_CLASS_IN) + +if (pkt): + mx = pkt.rr_list_by_type(ldns.LDNS_RR_TYPE_MX, ldns.LDNS_SECTION_ANSWER) + if (mx): + mx.sort() + print(mx) diff --git a/contrib/python/examples/python3/ldns-mx1.py b/contrib/python/examples/python3/ldns-mx1.py new file mode 100755 index 000000000000..d10863e39366 --- /dev/null +++ b/contrib/python/examples/python3/ldns-mx1.py @@ -0,0 +1,18 @@ +#!/usr/bin/python +# +# MX is a small program that prints out the mx records for a particular domain +# +import ldns + +dname = ldns.ldns_dname("nic.cz") +print(dname) + +resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf") + +pkt = resolver.query(dname, ldns.LDNS_RR_TYPE_MX,ldns.LDNS_RR_CLASS_IN) + +if (pkt): + mx = pkt.rr_list_by_type(ldns.LDNS_RR_TYPE_MX, ldns.LDNS_SECTION_ANSWER) + if (mx): + mx.sort() + print(mx) diff --git a/contrib/python/examples/python3/ldns-mx2.py b/contrib/python/examples/python3/ldns-mx2.py new file mode 100755 index 000000000000..9c8b103bf135 --- /dev/null +++ b/contrib/python/examples/python3/ldns-mx2.py @@ -0,0 +1,19 @@ +#!/usr/bin/python +# +# MX is a small program that prints out the mx records for a particular domain +# +import ldns + +resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf") + +pkt = resolver.query("nic.cz", ldns.LDNS_RR_TYPE_MX,ldns.LDNS_RR_CLASS_IN) +if (pkt) and (pkt.answer()): + + for rr in pkt.answer().rrs(): + if (rr.get_type() != ldns.LDNS_RR_TYPE_MX): + continue + + rdf = rr.owner() + print(rdf," ",rr.ttl()," ",rr.get_class_str()," ",rr.get_type_str()," ", end=" ") + print(" ".join(str(rdf) for rdf in rr.rdfs())) + diff --git a/contrib/python/examples/python3/ldns-newpkt.py b/contrib/python/examples/python3/ldns-newpkt.py new file mode 100755 index 000000000000..49bad5ef77e7 --- /dev/null +++ b/contrib/python/examples/python3/ldns-newpkt.py @@ -0,0 +1,17 @@ +#!/usr/bin/python + +import ldns + +pkt = ldns.ldns_pkt.new_query_frm_str("www.google.com",ldns.LDNS_RR_TYPE_ANY, ldns.LDNS_RR_CLASS_IN, ldns.LDNS_QR | ldns.LDNS_AA) + +rra = ldns.ldns_rr.new_frm_str("www.google.com. IN A 192.168.1.1",300) +rrb = ldns.ldns_rr.new_frm_str("www.google.com. IN TXT Some\ Description",300) + +list = ldns.ldns_rr_list() +if (rra): list.push_rr(rra) +if (rrb): list.push_rr(rrb) + +pkt.push_rr_list(ldns.LDNS_SECTION_ANSWER, list) + +print("Packet:") +print(pkt) diff --git a/contrib/python/examples/python3/ldns-zone.py b/contrib/python/examples/python3/ldns-zone.py new file mode 100755 index 000000000000..b465eaa56bdb --- /dev/null +++ b/contrib/python/examples/python3/ldns-zone.py @@ -0,0 +1,15 @@ +#!/usr/bin/python +import ldns + +#Read zone from file +zone = ldns.ldns_zone.new_frm_fp(open("../zone.txt","r"), None, 0, ldns.LDNS_RR_CLASS_IN) +print(zone) + +print("SOA:", zone.soa()) +for r in zone.rrs().rrs(): + print("RR:", r) + + +zone = ldns.ldns_zone() +#print zone + diff --git a/contrib/python/examples/python3/ldns_rr_iter_frm_fp_l.demo.py b/contrib/python/examples/python3/ldns_rr_iter_frm_fp_l.demo.py new file mode 100644 index 000000000000..18edd1109bfa --- /dev/null +++ b/contrib/python/examples/python3/ldns_rr_iter_frm_fp_l.demo.py @@ -0,0 +1,12 @@ +import ldns +import sys + +if len(sys.argv) <= 1: + print("Usage: %s zone_file" % sys.argv[0]) + sys.exit() + +inp = open(sys.argv[1],"r"); +for rr in ldns.ldns_rr_iter_frm_fp_l(inp): + print(rr) + +inp.close() diff --git a/contrib/python/examples/python3/ldns_rr_new_frm_fp_l.demo.py b/contrib/python/examples/python3/ldns_rr_new_frm_fp_l.demo.py new file mode 100644 index 000000000000..1bd667b027c4 --- /dev/null +++ b/contrib/python/examples/python3/ldns_rr_new_frm_fp_l.demo.py @@ -0,0 +1,43 @@ +import ldns +import sys + +if len(sys.argv) <= 1: + print("Usage: %s zone_file" % sys.argv[0]) + sys.exit() + +inp = open(sys.argv[1],"r"); +# variables that preserve the parsers state +my_ttl = 3600; +my_origin = None +my_prev = None +# additional state variables +last_pos = 0 +line_nr = 0 + +while True: + ret = ldns.ldns_rr_new_frm_fp_l_(inp, my_ttl, my_origin, my_prev) + s, rr, line_inc, new_ttl, new_origin, new_prev = ret # unpack the result + line_nr += line_inc # increase number of parsed lines + my_prev = new_prev # update ref to previous owner + + if s == ldns.LDNS_STATUS_SYNTAX_TTL: + my_ttl = new_ttl # update default TTL + print("$TTL:", my_ttl) + elif s == ldns.LDNS_STATUS_SYNTAX_ORIGIN: + my_origin = new_origin # update reference to origin + print("$ORIGIN:", my_origin) + elif s == ldns.LDNS_STATUS_SYNTAX_EMPTY: + if last_pos == inp.tell(): + break # no advance since last read - EOF + last_pos = inp.tell() + elif s != ldns.LDNS_STATUS_OK: + print("! parse error in line", line_nr) + else: + # we are sure to have LDNS_STATUS_OK + print(rr) + +inp.close() +print("--------------------") +print("Read %d lines" % line_nr) + + diff --git a/contrib/python/examples/zone.txt b/contrib/python/examples/zone.txt new file mode 100644 index 000000000000..ffc87263f124 --- /dev/null +++ b/contrib/python/examples/zone.txt @@ -0,0 +1,15 @@ +$ORIGIN example. +$TTL 600 + +example. IN SOA example. admin.example. ( + 2008022501 ; serial + 28800 ; refresh (8 hours) + 7200 ; retry (2 hours) + 604800 ; expire (1 week) + 18000 ; minimum (5 hours) + ) + +@ IN MX 10 mail.example. +@ IN NS ns1 +@ IN NS ns2 +@ IN A 192.168.1.1 diff --git a/contrib/python/file_py3.i b/contrib/python/file_py3.i new file mode 100644 index 000000000000..b3f55e82ab5b --- /dev/null +++ b/contrib/python/file_py3.i @@ -0,0 +1,120 @@ +/* + * file_py3.i: Typemaps for FILE* for Python 3 + * + * Copyright (c) 2011, Karel Slany (karel.slany AT nic.cz) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the organization nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +%{ +#include <unistd.h> +#include <fcntl.h> +%} + +%types(FILE *); + +/* converts basic file descriptor flags onto a string */ +%fragment("fdfl_to_str", "header") { +const char * +fdfl_to_str(int fdfl) { + + static const char * const file_mode[] = {"w+", "w", "r"}; + + if (fdfl & O_RDWR) { + return file_mode[0]; + } else if (fdfl & O_WRONLY) { + return file_mode[1]; + } else { + return file_mode[2]; + } +} +} + +%fragment("obj_to_file","header", fragment="fdfl_to_str") { +FILE * +obj_to_file(PyObject *obj) { +%#if PY_VERSION_HEX >= 0x03000000 + int fd, fdfl; + FILE *fp; + if (!PyLong_Check(obj) && /* is not an integer */ + PyObject_HasAttrString(obj, "fileno") && /* has fileno method */ + (PyObject_CallMethod(obj, "flush", NULL) != NULL) && /* flush() succeeded */ + ((fd = PyObject_AsFileDescriptor(obj)) != -1) && /* got file descriptor */ + ((fdfl = fcntl(fd, F_GETFL)) != -1) /* got descriptor flags */ + ) { + fp = fdopen(dup(fd), fdfl_to_str(fdfl)); /* the FILE* must be flushed + and closed after being used */ +#ifdef SWIG_FILE3_DEBUG + fprintf(stderr, "opening fd %d (fl %d \"%s\") as FILE %p\n", + fd, fdfl, fdfl_to_str(fdfl), (void *)fp); +#endif + return fp; + } +%#endif + return NULL; +} +} + +/* returns -1 if error occurred */ +%fragment("dispose_file", "header") { +int +dispose_file(FILE **fp) { +#ifdef SWIG_FILE3_DEBUG + fprintf(stderr, "flushing FILE %p\n", (void *)fp); +#endif + if (*fp == NULL) { + return 0; + } + if ((fflush(*fp) == 0) && /* flush file */ + (fclose(*fp) == 0)) { /* close file */ + *fp = NULL; + return 0; + } + return -1; +} +} + +%typemap(arginit, noblock = 1) FILE* { + $1 = NULL; +} + +%typemap(check, noblock = 1) FILE* { + if ($1 == NULL) { + SWIG_exception_fail(SWIG_ValueError, "in method '" "$symname" "', argument " + "$argnum"" of type '" "$type""'"); + } +} + +%typemap(in, noblock = 1, fragment = "obj_to_file") FILE* { + $1 = obj_to_file($input); +} + +%typemap(freearg, noblock = 1, fragment = "dispose_file") FILE* { + if (dispose_file(&$1) == -1) { + SWIG_exception_fail(SWIG_IOError, "closing file in method '" "$symname" "', argument " + "$argnum"" of type '" "$type""'"); + } +} diff --git a/contrib/python/ldns.i b/contrib/python/ldns.i new file mode 100644 index 000000000000..122ebe18e0a2 --- /dev/null +++ b/contrib/python/ldns.i @@ -0,0 +1,362 @@ +/* + * ldns.i: LDNS interface file + * + * Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz) + * Karel Slany (slany AT fit.vutbr.cz) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the organization nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +%module ldns +#pragma SWIG nowarn=454 +%{ + +#include "ldns.h" +#include <stdio.h> +#include <stdlib.h> +#include <inttypes.h> + +#include <ldns/util.h> +#include <ldns/buffer.h> +#include <ldns/common.h> +#include <ldns/dname.h> +#include <ldns/dnssec.h> +#include <ldns/dnssec_verify.h> +#include <ldns/dnssec_sign.h> +#include <ldns/error.h> +#include <ldns/higher.h> +#include <ldns/host2str.h> +#include <ldns/host2wire.h> +#include <ldns/net.h> +#include <ldns/packet.h> +#include <ldns/rdata.h> +#include <ldns/resolver.h> +#include <ldns/rr.h> +#include <ldns/str2host.h> +#include <ldns/tsig.h> +#include <ldns/update.h> +#include <ldns/wire2host.h> +#include <ldns/rr_functions.h> +#include <ldns/keys.h> +#include <ldns/parse.h> +#include <ldns/zone.h> +#include <ldns/dnssec_zone.h> +#include <ldns/rbtree.h> +%} + +//#define LDNS_DEBUG +//#define SWIG_FILE3_DEBUG + +%include "stdint.i" // uint_16_t is known type now +#ifdef PY3 +%include "file_py3.i" // python 3 FILE * +#else +%include "file.i" // FILE * +#endif +%include "typemaps.i" + +%inline %{ +struct timeval* ldns_make_timeval(uint32_t sec, uint32_t usec) +{ + struct timeval* res = (struct timeval*)malloc(sizeof(*res)); + res->tv_sec = sec; + res->tv_usec = usec; + return res; +} +uint32_t ldns_read_timeval_sec(struct timeval* t) { + return (uint32_t)t->tv_sec; } +uint32_t ldns_read_timeval_usec(struct timeval* t) { + return (uint32_t)t->tv_usec; } +%} + +%immutable ldns_struct_lookup_table::name; +%immutable ldns_struct_rr_descriptor::_name; +%immutable ldns_error_str; +%immutable ldns_signing_algorithms; + +//new_frm_fp_l +%apply int *OUTPUT { int *line_nr}; +%apply uint32_t *OUTPUT { uint32_t *default_ttl}; + +// wire2pkt +%apply (char *STRING, int LENGTH) { (const char *str, int len) }; + +%include "ldns_packet.i" +%include "ldns_resolver.i" +%include "ldns_rr.i" + +%inline %{ +int Python_str_Check(PyObject *o) { +#if PY_VERSION_HEX>=0x03000000 + return PyUnicode_Check(o); +#else + return PyString_Check(o); +#endif +} +%} + +%include "ldns_rdf.i" +%include "ldns_zone.i" +%include "ldns_key.i" +%include "ldns_buffer.i" +%include "ldns_dnssec.i" + +%include <ldns/util.h> + %include <ldns/buffer.h> +%include <ldns/dnssec.h> +%include <ldns/dnssec_verify.h> + %include <ldns/dnssec_sign.h> +%include <ldns/error.h> +%include <ldns/higher.h> + %include <ldns/host2str.h> + %include <ldns/host2wire.h> +%include <ldns/net.h> + %include <ldns/packet.h> + %include <ldns/rdata.h> + %include <ldns/resolver.h> + %include <ldns/rr.h> +%include <ldns/str2host.h> +%include <ldns/tsig.h> + %include <ldns/update.h> +%include <ldns/wire2host.h> + %include <ldns/rr_functions.h> + %include <ldns/keys.h> +%include <ldns/parse.h> + %include <ldns/zone.h> + %include <ldns/dnssec_zone.h> +%include <ldns/rbtree.h> + %include <ldns/dname.h> + +typedef struct ldns_dnssec_name { }; +typedef struct ldns_dnssec_rrs { }; +typedef struct ldns_dnssec_rrsets { }; +typedef struct ldns_dnssec_zone { }; +// ================================================================================ + +%include "ldns_dname.i" + +%inline %{ + PyObject* ldns_rr_new_frm_str_(const char *str, uint32_t default_ttl, ldns_rdf* origin, ldns_rdf* prev) + //returns tuple (status, ldns_rr, prev) + { + PyObject* tuple; + + /* origin and prev have to be cloned in order to decouple the data + * from the python wrapper + */ + if (origin != NULL) + origin = ldns_rdf_clone(origin); + if (prev != NULL) + prev = ldns_rdf_clone(prev); + + ldns_rdf *p_prev = prev; + ldns_rdf **pp_prev = &p_prev; + if (p_prev == 0) pp_prev = 0; + + ldns_rr *p_rr = 0; + ldns_rr **pp_rr = &p_rr; + + ldns_status st = ldns_rr_new_frm_str(pp_rr, str, default_ttl, origin, pp_prev); + + tuple = PyTuple_New(3); + PyTuple_SetItem(tuple, 0, SWIG_From_int(st)); + PyTuple_SetItem(tuple, 1, (st == LDNS_STATUS_OK) ? + SWIG_NewPointerObj(SWIG_as_voidptr(p_rr), SWIGTYPE_p_ldns_struct_rr, SWIG_POINTER_OWN | 0 ) : + (Py_INCREF(Py_None), Py_None)); + PyTuple_SetItem(tuple, 2, (p_prev != prev) ? + SWIG_NewPointerObj(SWIG_as_voidptr(p_prev), SWIGTYPE_p_ldns_struct_rdf, SWIG_POINTER_OWN | 0 ) : + (Py_INCREF(Py_None), Py_None)); + return tuple; + } + + PyObject* ldns_rr_new_frm_fp_l_(FILE *fp, uint32_t default_ttl, ldns_rdf* origin, ldns_rdf* prev) + //returns tuple (status, ldns_rr, [line if ret_linenr], ttl, origin, prev) + { + int linenr = 0; + int *p_linenr = &linenr; + + uint32_t defttl = default_ttl; + uint32_t *p_defttl = &defttl; + if (defttl == 0) p_defttl = 0; + + /* origin and prev have to be cloned in order to decouple the data + * from the python wrapper + */ + if (origin != NULL) + origin = ldns_rdf_clone(origin); + if (prev != NULL) + prev = ldns_rdf_clone(prev); + + ldns_rdf *p_origin = origin; + ldns_rdf **pp_origin = &p_origin; + //if (p_origin == 0) pp_origin = 0; + + ldns_rdf *p_prev = prev; + ldns_rdf **pp_prev = &p_prev; + //if (p_prev == 0) pp_prev = 0; + + ldns_rr *p_rr = 0; + ldns_rr **pp_rr = &p_rr; + + ldns_status st = ldns_rr_new_frm_fp_l(pp_rr, fp, p_defttl, pp_origin, pp_prev, p_linenr); + + PyObject* tuple; + tuple = PyTuple_New(6); + int idx = 0; + PyTuple_SetItem(tuple, idx, SWIG_From_int(st)); + idx++; + PyTuple_SetItem(tuple, idx, (st == LDNS_STATUS_OK) ? + SWIG_NewPointerObj(SWIG_as_voidptr(p_rr), SWIGTYPE_p_ldns_struct_rr, SWIG_POINTER_OWN | 0 ) : + (Py_INCREF(Py_None), Py_None)); + idx++; + PyTuple_SetItem(tuple, idx, SWIG_From_int(linenr)); + idx++; + PyTuple_SetItem(tuple, idx, SWIG_From_int(defttl)); + idx++; + PyTuple_SetItem(tuple, idx, SWIG_NewPointerObj(SWIG_as_voidptr(p_origin), SWIGTYPE_p_ldns_struct_rdf, SWIG_POINTER_OWN | 0 )); + idx++; + PyTuple_SetItem(tuple, idx, SWIG_NewPointerObj(SWIG_as_voidptr(p_prev), SWIGTYPE_p_ldns_struct_rdf, SWIG_POINTER_OWN | 0 )); + return tuple; + } + + +PyObject* ldns_rr_new_question_frm_str_(const char *str, ldns_rdf* origin, ldns_rdf* prev) + //returns tuple (status, ldns_rr, prev) + { + PyObject* tuple; + + /* origin and prev have to be cloned in order to decouple the data + * from the python wrapper + */ + if (origin != NULL) + origin = ldns_rdf_clone(origin); + if (prev != NULL) + prev = ldns_rdf_clone(prev); + + ldns_rdf *p_prev = prev; + ldns_rdf **pp_prev = &p_prev; + if (p_prev == 0) pp_prev = 0; + + ldns_rr *p_rr = 0; + ldns_rr **pp_rr = &p_rr; + + ldns_status st = ldns_rr_new_question_frm_str(pp_rr, str, origin, pp_prev); + + tuple = PyTuple_New(3); + PyTuple_SetItem(tuple, 0, SWIG_From_int(st)); + PyTuple_SetItem(tuple, 1, (st == LDNS_STATUS_OK) ? + SWIG_NewPointerObj(SWIG_as_voidptr(p_rr), SWIGTYPE_p_ldns_struct_rr, SWIG_POINTER_OWN | 0 ) : + (Py_INCREF(Py_None), Py_None)); + PyTuple_SetItem(tuple, 2, (p_prev != prev) ? + SWIG_NewPointerObj(SWIG_as_voidptr(p_prev), SWIGTYPE_p_ldns_struct_rdf, SWIG_POINTER_OWN | 0 ) : + (Py_INCREF(Py_None), Py_None)); + return tuple; + } + + + +PyObject* ldns_fetch_valid_domain_keys_(const ldns_resolver * res, const ldns_rdf * domain, + const ldns_rr_list * keys) + //returns tuple (status, result) + { + PyObject* tuple; + + ldns_rr_list *rrl = 0; + ldns_status st = 0; + rrl = ldns_fetch_valid_domain_keys(res, domain, keys, &st); + + + tuple = PyTuple_New(2); + PyTuple_SetItem(tuple, 0, SWIG_From_int(st)); + PyTuple_SetItem(tuple, 1, (st == LDNS_STATUS_OK) ? + SWIG_NewPointerObj(SWIG_as_voidptr(rrl), SWIGTYPE_p_ldns_struct_rr_list, SWIG_POINTER_OWN | 0 ) : + (Py_INCREF(Py_None), Py_None)); + return tuple; + } + +PyObject* ldns_wire2pkt_(const char *str, int len) + //returns tuple (status, result) + { + PyObject *resultobj = 0; + ldns_pkt *arg1 = NULL; + uint8_t *arg2 = (uint8_t *) str; + size_t arg3 = (size_t) len; + ldns_status result; + PyObject* tuple; + + result = (ldns_status)ldns_wire2pkt(&arg1,arg2,arg3); + tuple = PyTuple_New(2); + PyTuple_SetItem(tuple, 0, SWIG_From_int(result)); + if (result == LDNS_STATUS_OK) + PyTuple_SetItem(tuple, 1, SWIG_NewPointerObj(SWIG_as_voidptr(arg1), SWIGTYPE_p_ldns_struct_pkt, SWIG_POINTER_OWN | 0 )); + else { + Py_INCREF(Py_None); + PyTuple_SetItem(tuple, 1, Py_None); + } + return tuple; +} + +%} + +%pythoncode %{ +def ldns_fetch_valid_domain_keys(res, domain, keys): + return _ldns.ldns_fetch_valid_domain_keys_(res, domain, keys) + +def ldns_wire2pkt(data): + return _ldns.ldns_wire2pkt_(data) + +def ldns_rr_iter_frm_fp_l(input_file): + """Creates an iterator (generator) that returns individual parsed + RRs from an open zone file.""" + # variables that preserve the parsers state + my_ttl = 0; + my_origin = None + my_prev = None + # additional state variables + last_pos = 0 + line_nr = 0 + + while True: + ret = _ldns.ldns_rr_new_frm_fp_l_(input_file, my_ttl, my_origin, my_prev) + s, rr, line_inc, new_ttl, new_origin, new_prev = ret # unpack the result + line_nr += line_inc # increase number of parsed lines + my_prev = new_prev # update ref to previous owner + + if s == _ldns.LDNS_STATUS_SYNTAX_TTL: + my_ttl = new_ttl # update default TTL + elif s == _ldns.LDNS_STATUS_SYNTAX_ORIGIN: + my_origin = new_origin # update reference to origin + elif s == _ldns.LDNS_STATUS_SYNTAX_EMPTY: + if last_pos == input_file.tell(): + break # no advance since last read - EOF + last_pos = input_file.tell() + elif s != _ldns.LDNS_STATUS_OK: + raise ValueError("Parse error in line %d" % line_nr) + else: + # we are sure to have LDNS_STATUS_OK + yield rr + +%} diff --git a/contrib/python/ldns_buffer.i b/contrib/python/ldns_buffer.i new file mode 100644 index 000000000000..1e743c007803 --- /dev/null +++ b/contrib/python/ldns_buffer.i @@ -0,0 +1,565 @@ +/****************************************************************************** + * ldns_buffer.i: LDNS buffer class + * + * Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz) + * Karel Slany (slany AT fit.vutbr.cz) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the organization nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ + +%typemap(in,numinputs=0,noblock=1) (ldns_buffer **) +{ + ldns_buffer *$1_buf; + $1 = &$1_buf; +} + +/* result generation */ +%typemap(argout,noblock=1) (ldns_buffer **) +{ + $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(SWIG_as_voidptr($1_buf), SWIGTYPE_p_ldns_struct_buffer, SWIG_POINTER_OWN | 0 )); +} + +%nodefaultctor ldns_struct_buffer; //no default constructor & destructor +%nodefaultdtor ldns_struct_buffer; + +%delobject ldns_buffer_free; +%newobject ldns_buffer_new; +%newobject ldns_dname_new; +%newobject ldns_dname_new_frm_data; +%newobject ldns_dname_label; + +# limit the number of arguments to 2 and +# deal with variable number of arguments the Python way +%varargs(2, char *arg = NULL) ldns_buffer_printf; + +%rename(ldns_buffer) ldns_struct_buffer; + +#ifdef LDNS_DEBUG +%rename(__ldns_buffer_free) ldns_buffer_free; +%inline %{ +void _ldns_buffer_free (ldns_buffer* b) { + printf("******** LDNS_BUFFER free 0x%lX ************\n", (long unsigned int)b); + ldns_buffer_free(b); +} +%} +#else +%rename(_ldns_buffer_free) ldns_buffer_free; +#endif + +%ignore ldns_struct_buffer::_position; +%ignore ldns_struct_buffer::_limit; +%ignore ldns_struct_buffer::_capacity; +%ignore ldns_struct_buffer::_data; +%ignore ldns_struct_buffer::_fixed; +%ignore ldns_struct_buffer::_status; + +%extend ldns_struct_buffer { + + %pythoncode %{ + def __init__(self, capacity): + """Creates a new buffer with the specified capacity. + + :param capacity: the size (in bytes) to allocate for the buffer + """ + self.this = _ldns.ldns_buffer_new(capacity) + + __swig_destroy__ = _ldns._ldns_buffer_free + + def __str__(self): + """Returns the data in the buffer as a string. Buffer data must be char * type.""" + return _ldns.ldns_buffer2str(self) + + def getc(self): + """returns the next character from a buffer. + + Advances the position pointer with 1. When end of buffer is reached returns EOF. This is the buffer's equivalent for getc(). + + :returns: (int) EOF on failure otherwise return the character + """ + return _ldns.ldns_bgetc(self) + + #LDNS_BUFFER_METHODS_# + def at(self,at): + """returns a pointer to the data at the indicated position. + + :param at: + position + :returns: (uint8_t \*) the pointer to the data + """ + return _ldns.ldns_buffer_at(self,at) + #parameters: const ldns_buffer *,size_t, + #retvals: uint8_t * + + def available(self,count): + """checks if the buffer has count bytes available at the current position + + :param count: + how much is available + :returns: (int) true or false + """ + return _ldns.ldns_buffer_available(self,count) + #parameters: ldns_buffer *,size_t, + #retvals: int + + def available_at(self,at,count): + """checks if the buffer has at least COUNT more bytes available. + + Before reading or writing the caller needs to ensure enough space is available! + + :param at: + indicated position + :param count: + how much is available + :returns: (int) true or false + """ + return _ldns.ldns_buffer_available_at(self,at,count) + #parameters: ldns_buffer *,size_t,size_t, + #retvals: int + + def begin(self): + """returns a pointer to the beginning of the buffer (the data at position 0). + + :returns: (uint8_t \*) the pointer + """ + return _ldns.ldns_buffer_begin(self) + #parameters: const ldns_buffer *, + #retvals: uint8_t * + + def capacity(self): + """returns the number of bytes the buffer can hold. + + :returns: (size_t) the number of bytes + """ + return _ldns.ldns_buffer_capacity(self) + #parameters: ldns_buffer *, + #retvals: size_t + + def clear(self): + """clears the buffer and make it ready for writing. + + The buffer's limit is set to the capacity and the position is set to 0. + """ + _ldns.ldns_buffer_clear(self) + #parameters: ldns_buffer *, + #retvals: + + def copy(self,bfrom): + """Copy contents of the other buffer to this buffer. + + Silently truncated if this buffer is too small. + + :param bfrom: other buffer + """ + _ldns.ldns_buffer_copy(self,bfrom) + #parameters: ldns_buffer *,ldns_buffer *, + #retvals: + + def current(self): + """returns a pointer to the data at the buffer's current position. + + :returns: (uint8_t \*) the pointer + """ + return _ldns.ldns_buffer_current(self) + #parameters: ldns_buffer *, + #retvals: uint8_t * + + def end(self): + """returns a pointer to the end of the buffer (the data at the buffer's limit). + + :returns: (uint8_t \*) the pointer + """ + return _ldns.ldns_buffer_end(self) + #parameters: ldns_buffer *, + #retvals: uint8_t * + + def export(self): + """Makes the buffer fixed and returns a pointer to the data. + + The caller is responsible for free'ing the result. + + :returns: (void \*) void + """ + return _ldns.ldns_buffer_export(self) + #parameters: ldns_buffer *, + #retvals: void * + + def flip(self): + """makes the buffer ready for reading the data that has been written to the buffer. + + The buffer's limit is set to the current position and the position is set to 0. + """ + _ldns.ldns_buffer_flip(self) + #parameters: ldns_buffer *, + + def invariant(self): + _ldns.ldns_buffer_invariant(self) + #parameters: ldns_buffer *, + + def limit(self): + """returns the maximum size of the buffer + + :returns: (size_t) the size + """ + return _ldns.ldns_buffer_limit(self) + #parameters: ldns_buffer *, + #retvals: size_t + + def position(self): + """returns the current position in the buffer (as a number of bytes) + + :returns: (size_t) the current position + """ + return _ldns.ldns_buffer_position(self) + #parameters: ldns_buffer *, + #retvals: size_t + + def printf(self, str, *args): + """Prints to the buffer, increasing the capacity if required using buffer_reserve(). + + The buffer's position is set to the terminating '\0'. Returns the number of characters written (not including the terminating '\0') or -1 on failure. + :param str: a string + :returns: (int) + """ + data = str % args + return _ldns.ldns_buffer_printf(self,data) + #parameters: ldns_buffer *,const char *,... + #retvals: int + + def read(self,data,count): + """copies count bytes of data at the current position to the given data-array + + :param data: + buffer to copy to + :param count: + the length of the data to copy + """ + _ldns.ldns_buffer_read(self,data,count) + #parameters: ldns_buffer *,void *,size_t, + #retvals: + + def read_at(self,at,data,count): + """copies count bytes of data at the given position to the given data-array + + :param at: + the position in the buffer to start + :param data: + buffer to copy to + :param count: + the length of the data to copy + """ + _ldns.ldns_buffer_read_at(self,at,data,count) + #parameters: ldns_buffer *,size_t,void *,size_t, + #retvals: + + def read_u16(self): + """returns the 2-byte integer value at the current position in the buffer + + :returns: (uint16_t) 2 byte integer + """ + return _ldns.ldns_buffer_read_u16(self) + #parameters: ldns_buffer *, + #retvals: uint16_t + + def read_u16_at(self,at): + """returns the 2-byte integer value at the given position in the buffer + + :param at: + position in the buffer + :returns: (uint16_t) 2 byte integer + """ + return _ldns.ldns_buffer_read_u16_at(self,at) + #parameters: ldns_buffer *,size_t, + #retvals: uint16_t + + def read_u32(self): + """returns the 4-byte integer value at the current position in the buffer + + :returns: (uint32_t) 4 byte integer + """ + return _ldns.ldns_buffer_read_u32(self) + #parameters: ldns_buffer *, + #retvals: uint32_t + + def read_u32_at(self,at): + """returns the 4-byte integer value at the given position in the buffer + + :param at: + position in the buffer + :returns: (uint32_t) 4 byte integer + """ + return _ldns.ldns_buffer_read_u32_at(self,at) + #parameters: ldns_buffer *,size_t, + #retvals: uint32_t + + def read_u8(self): + """returns the byte value at the current position in the buffer + + :returns: (uint8_t) 1 byte integer + """ + return _ldns.ldns_buffer_read_u8(self) + #parameters: ldns_buffer *, + #retvals: uint8_t + + def read_u8_at(self,at): + """returns the byte value at the given position in the buffer + + :param at: + the position in the buffer + :returns: (uint8_t) 1 byte integer + """ + return _ldns.ldns_buffer_read_u8_at(self,at) + #parameters: ldns_buffer *,size_t, + #retvals: uint8_t + + def remaining(self): + """returns the number of bytes remaining between the buffer's position and limit. + + :returns: (size_t) the number of bytes + """ + return _ldns.ldns_buffer_remaining(self) + #parameters: ldns_buffer *, + #retvals: size_t + + def remaining_at(self,at): + """returns the number of bytes remaining between the indicated position and the limit. + + :param at: + indicated position + :returns: (size_t) number of bytes + """ + return _ldns.ldns_buffer_remaining_at(self,at) + #parameters: ldns_buffer *,size_t, + #retvals: size_t + + def reserve(self,amount): + """ensures BUFFER can contain at least AMOUNT more bytes. + + The buffer's capacity is increased if necessary using buffer_set_capacity(). + + The buffer's limit is always set to the (possibly increased) capacity. + + :param amount: + amount to use + :returns: (bool) whether this failed or succeeded + """ + return _ldns.ldns_buffer_reserve(self,amount) + #parameters: ldns_buffer *,size_t, + #retvals: bool + + def rewind(self): + """make the buffer ready for re-reading the data. + + The buffer's position is reset to 0. + """ + _ldns.ldns_buffer_rewind(self) + #parameters: ldns_buffer *, + #retvals: + + def set_capacity(self,capacity): + """changes the buffer's capacity. + + The data is reallocated so any pointers to the data may become invalid. The buffer's limit is set to the buffer's new capacity. + + :param capacity: + the capacity to use + :returns: (bool) whether this failed or succeeded + """ + return _ldns.ldns_buffer_set_capacity(self,capacity) + #parameters: ldns_buffer *,size_t, + #retvals: bool + + def set_limit(self,limit): + """changes the buffer's limit. + + If the buffer's position is greater than the new limit the position is set to the limit. + + :param limit: + the new limit + """ + _ldns.ldns_buffer_set_limit(self,limit) + #parameters: ldns_buffer *,size_t, + #retvals: + + def set_position(self,mark): + """sets the buffer's position to MARK. + + The position must be less than or equal to the buffer's limit. + + :param mark: + the mark to use + """ + _ldns.ldns_buffer_set_position(self,mark) + #parameters: ldns_buffer *,size_t, + #retvals: + + def skip(self,count): + """changes the buffer's position by COUNT bytes. + + The position must not be moved behind the buffer's limit or before the beginning of the buffer. + + :param count: + the count to use + """ + _ldns.ldns_buffer_skip(self,count) + #parameters: ldns_buffer *,ssize_t, + #retvals: + + def status(self): + """returns the status of the buffer + + :returns: (ldns_status) the status + """ + return _ldns.ldns_buffer_status(self) + #parameters: ldns_buffer *, + #retvals: ldns_status + + def status_ok(self): + """returns true if the status of the buffer is LDNS_STATUS_OK, false otherwise + + :returns: (bool) true or false + """ + return _ldns.ldns_buffer_status_ok(self) + #parameters: ldns_buffer *, + #retvals: bool + + def write(self,data,count): + """writes count bytes of data to the current position of the buffer + + :param data: + the data to write + :param count: + the lenght of the data to write + """ + _ldns.ldns_buffer_write(self,data,count) + #parameters: ldns_buffer *,const void *,size_t, + #retvals: + + def write_at(self,at,data,count): + """writes the given data to the buffer at the specified position + + :param at: + the position (in number of bytes) to write the data at + :param data: + pointer to the data to write to the buffer + :param count: + the number of bytes of data to write + """ + _ldns.ldns_buffer_write_at(self,at,data,count) + #parameters: ldns_buffer *,size_t,const void *,size_t, + #retvals: + + def write_string(self,str): + """copies the given (null-delimited) string to the current position at the buffer + + :param str: + the string to write + """ + _ldns.ldns_buffer_write_string(self,str) + #parameters: ldns_buffer *,const char *, + #retvals: + + def write_string_at(self,at,str): + """copies the given (null-delimited) string to the specified position at the buffer + + :param at: + the position in the buffer + :param str: + the string to write + """ + _ldns.ldns_buffer_write_string_at(self,at,str) + #parameters: ldns_buffer *,size_t,const char *, + #retvals: + + def write_u16(self,data): + """writes the given 2 byte integer at the current position in the buffer + + :param data: + the 16 bits to write + """ + _ldns.ldns_buffer_write_u16(self,data) + #parameters: ldns_buffer *,uint16_t, + #retvals: + + def write_u16_at(self,at,data): + """writes the given 2 byte integer at the given position in the buffer + + :param at: + the position in the buffer + :param data: + the 16 bits to write + """ + _ldns.ldns_buffer_write_u16_at(self,at,data) + #parameters: ldns_buffer *,size_t,uint16_t, + #retvals: + + def write_u32(self,data): + """writes the given 4 byte integer at the current position in the buffer + + :param data: + the 32 bits to write + """ + _ldns.ldns_buffer_write_u32(self,data) + #parameters: ldns_buffer *,uint32_t, + #retvals: + + def write_u32_at(self,at,data): + """writes the given 4 byte integer at the given position in the buffer + + :param at: + the position in the buffer + :param data: + the 32 bits to write + """ + _ldns.ldns_buffer_write_u32_at(self,at,data) + #parameters: ldns_buffer *,size_t,uint32_t, + #retvals: + + def write_u8(self,data): + """writes the given byte of data at the current position in the buffer + + :param data: + the 8 bits to write + """ + _ldns.ldns_buffer_write_u8(self,data) + #parameters: ldns_buffer *,uint8_t, + #retvals: + + def write_u8_at(self,at,data): + """writes the given byte of data at the given position in the buffer + + :param at: + the position in the buffer + :param data: + the 8 bits to write + """ + _ldns.ldns_buffer_write_u8_at(self,at,data) + #parameters: ldns_buffer *,size_t,uint8_t, + #retvals: + + #_LDNS_BUFFER_METHODS# + %} +} + diff --git a/contrib/python/ldns_dname.i b/contrib/python/ldns_dname.i new file mode 100644 index 000000000000..0aac54c1060b --- /dev/null +++ b/contrib/python/ldns_dname.i @@ -0,0 +1,196 @@ +/****************************************************************************** + * ldns_dname.i: LDNS domain name class + * + * Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz) + * Karel Slany (slany AT fit.vutbr.cz) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the organization nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +%pythoncode %{ + class ldns_dname(ldns_rdf): + """Domain name + + This class contains methods to read and manipulate domain names. + Domain names are stored in ldns_rdf structures, with the type LDNS_RDF_TYPE_DNAME + + **Usage** + + >>> import ldns + >>> resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf") + >>> dn1 = ldns.ldns_dname("test.nic.cz") + >>> print dn1 + test.nic.cz. + >>> dn2 = ldns.ldns_dname("nic.cz") + >>> if dn2.is_subdomain(dn1): print dn2,"is subdomain of",dn1 + >>> if dn1.is_subdomain(dn2): print dn1,"is subdomain of",dn2 + test.nic.cz. is subdomain of nic.cz. + """ + def __init__(self, str): + """Creates a new dname rdf from a string. + + :parameter str: str string to use + """ + self.this = _ldns.ldns_dname_new_frm_str(str) + + @staticmethod + def new_frm_str(str): + """Creates a new dname rdf instance from a string. + + This static method is equivalent to using of default class constructor. + + :parameter str: str string to use + """ + return ldns_dname(str) + + def absolute(self): + """Checks whether the given dname string is absolute (i.e. ends with a '.') + + :returns: (bool) True or False + """ + return self.endswith(".") + + + def make_canonical(self): + """Put a dname into canonical fmt - ie. lowercase it + """ + _ldns.ldns_dname2canonical(self) + + def __cmp__(self,other): + """Compares the two dname rdf's according to the algorithm for ordering in RFC4034 Section 6. + + :param other: + the second dname rdf to compare + :returns: (int) -1 if dname comes before other, 1 if dname comes after other, and 0 if they are equal. + """ + return _ldns.ldns_dname_compare(self,other) + + def write_to_buffer(self,buffer): + """Copies the dname data to the buffer in wire format. + + :param buffer: buffer to append the result to + :returns: (ldns_status) ldns_status + """ + return _ldns.ldns_dname2buffer_wire(buffer,self) + #parameters: ldns_buffer *,const ldns_rdf *, + #retvals: ldns_status + + #LDNS_DNAME_METHODS_# + + def cat(self,rd2): + """concatenates rd2 after this dname (rd2 is copied, this dname is modified) + + :param rd2: + the rightside + :returns: (ldns_status) LDNS_STATUS_OK on success + """ + return _ldns.ldns_dname_cat(self,rd2) + #parameters: ldns_rdf *,ldns_rdf *, + #retvals: ldns_status + + def cat_clone(self,rd2): + """concatenates two dnames together + + :param rd2: + the rightside + :returns: (ldns_rdf \*) a new rdf with leftside/rightside + """ + return _ldns.ldns_dname_cat_clone(self,rd2) + #parameters: const ldns_rdf *,const ldns_rdf *, + #retvals: ldns_rdf * + + def interval(self,middle,next): + """check if middle lays in the interval defined by prev and next prev <= middle < next. + + This is usefull for nsec checking + + :param middle: + the dname to check + :param next: + the next dname return 0 on error or unknown, -1 when middle is in the interval, +1 when not + :returns: (int) + """ + return _ldns.ldns_dname_interval(self,middle,next) + #parameters: const ldns_rdf *,const ldns_rdf *,const ldns_rdf *, + #retvals: int + + def is_subdomain(self,parent): + """Tests wether the name sub falls under parent (i.e. is a subdomain of parent). + + This function will return false if the given dnames are equal. + + :param parent: + (ldns_rdf) the parent's name + :returns: (bool) true if sub falls under parent, otherwise false + """ + return _ldns.ldns_dname_is_subdomain(self,parent) + #parameters: const ldns_rdf *,const ldns_rdf *, + #retvals: bool + + def label(self,labelpos): + """look inside the rdf and if it is an LDNS_RDF_TYPE_DNAME try and retrieve a specific label. + + The labels are numbered starting from 0 (left most). + + :param labelpos: + return the label with this number + :returns: (ldns_rdf \*) a ldns_rdf* with the label as name or NULL on error + """ + return _ldns.ldns_dname_label(self,labelpos) + #parameters: const ldns_rdf *,uint8_t, + #retvals: ldns_rdf * + + def label_count(self): + """count the number of labels inside a LDNS_RDF_DNAME type rdf. + + :returns: (uint8_t) the number of labels + """ + return _ldns.ldns_dname_label_count(self) + #parameters: const ldns_rdf *, + #retvals: uint8_t + + def left_chop(self): + """chop one label off the left side of a dname. + + so wwww.nlnetlabs.nl, becomes nlnetlabs.nl + + :returns: (ldns_rdf \*) the remaining dname + """ + return _ldns.ldns_dname_left_chop(self) + #parameters: const ldns_rdf *, + #retvals: ldns_rdf * + + def reverse(self): + """Returns a clone of the given dname with the labels reversed. + + :returns: (ldns_rdf \*) clone of the dname with the labels reversed. + """ + return _ldns.ldns_dname_reverse(self) + #parameters: const ldns_rdf *, + #retvals: ldns_rdf * + + #_LDNS_DNAME_METHODS# +%} + diff --git a/contrib/python/ldns_dnssec.i b/contrib/python/ldns_dnssec.i new file mode 100644 index 000000000000..6c0656484666 --- /dev/null +++ b/contrib/python/ldns_dnssec.i @@ -0,0 +1,434 @@ +/****************************************************************************** + * ldns_dnssec.i: DNSSEC zone, name, rrs + * + * Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz) + * Karel Slany (slany AT fit.vutbr.cz) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the organization nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +%nodefaultctor ldns_dnssec_rrs; //no default constructor & destructor +%nodefaultdtor ldns_dnssec_rrs; + +%newobject ldns_dnssec_rrs_new; +%delobject ldns_dnssec_rrs_free; + +%extend ldns_dnssec_rrs { + %pythoncode %{ + + def __init__(self): + """Creates a new entry for 1 pointer to an rr and 1 pointer to the next rrs. + + :returns: (ldns_dnssec_rrs) the allocated data + """ + self.this = _ldns.ldns_dnssec_rrs_new() + if not self.this: + raise Exception("Can't create rrs instance") + + __swig_destroy__ = _ldns.ldns_dnssec_rrs_free + + #LDNS_DNSSEC_RRS_METHODS_# + def add_rr(self,rr): + """Adds an RR to the list of RRs. + + The list will remain ordered + + :param rr: + the RR to add + :returns: (ldns_status) LDNS_STATUS_OK on success + """ + return _ldns.ldns_dnssec_rrs_add_rr(self,rr) + #parameters: ldns_dnssec_rrs *,ldns_rr *, + #retvals: ldns_status + #_LDNS_DNSSEC_RRS_METHODS# + %} +} + +// ================================================================================ +// DNNSEC RRS +// ================================================================================ +%nodefaultctor ldns_dnssec_rrsets; //no default constructor & destructor +%nodefaultdtor ldns_dnssec_rrsets; + +%newobject ldns_dnssec_rrsets_new; +%delobject ldns_dnssec_rrsets_free; + +%extend ldns_dnssec_rrsets { + %pythoncode %{ + def __init__(self): + """Creates a new list (entry) of RRsets. + + :returns: (ldns_dnssec_rrsets \*) instance + """ + self.this = _ldns.ldns_dnssec_rrsets_new() + if not self.this: + raise Exception("Can't create rrsets instance") + + __swig_destroy__ = _ldns.ldns_dnssec_rrsets_free + + def print_to_file(self, file, follow): + """Print the given list of rrsets to the given file descriptor. + + :param file: file pointer + :param follow: if set to false, only print the first RRset + """ + _ldns.ldns_dnssec_rrsets_print(file,self,follow) + #parameters: FILE *,ldns_dnssec_rrsets *,bool, + #retvals: + + #LDNS_DNSSEC_RRSETS_METHODS_# + def add_rr(self,rr): + """Add an ldns_rr to the corresponding RRset in the given list of RRsets. + + If it is not present, add it as a new RRset with 1 record. + + :param rr: + the rr to add to the list of rrsets + :returns: (ldns_status) LDNS_STATUS_OK on success + """ + return _ldns.ldns_dnssec_rrsets_add_rr(self,rr) + #parameters: ldns_dnssec_rrsets *,ldns_rr *, + #retvals: ldns_status + + def set_type(self,atype): + """Sets the RR type of the rrset (that is head of the given list). + + :param atype: + :returns: (ldns_status) LDNS_STATUS_OK on success + """ + return _ldns.ldns_dnssec_rrsets_set_type(self,atype) + #parameters: ldns_dnssec_rrsets *,ldns_rr_type, + #retvals: ldns_status + + def type(self): + """Returns the rr type of the rrset (that is head of the given list). + + :returns: (ldns_rr_type) the rr type + """ + return _ldns.ldns_dnssec_rrsets_type(self) + #parameters: ldns_dnssec_rrsets *, + #retvals: ldns_rr_type + #_LDNS_DNSSEC_RRSETS_METHODS# + %} +} + +// ================================================================================ +// DNNSEC NAME +// ================================================================================ +%nodefaultctor ldns_dnssec_name; //no default constructor & destructor +%nodefaultdtor ldns_dnssec_name; + +%newobject ldns_dnssec_name_new; +%delobject ldns_dnssec_name_free; + +%extend ldns_dnssec_name { + %pythoncode %{ + def __init__(self): + """Create a new instance of dnssec name.""" + self.this = _ldns.ldns_dnssec_name_new() + if not self.this: + raise Exception("Can't create dnssec name instance") + + __swig_destroy__ = _ldns.ldns_dnssec_name_free + + def print_to_file(self,file): + """Prints the RRs in the dnssec name structure to the given file descriptor. + + :param file: file pointer + """ + _ldns.ldns_dnssec_name_print(file, self) + #parameters: FILE *,ldns_dnssec_name *, + + @staticmethod + def new_frm_rr(raiseException=True): + """Create a new instace of dnssec name for the given RR. + + :returns: (ldns_dnssec_name) instance + """ + name = _ldns.ldns_dnssec_name_new_frm_rr(self) + if (not name) and (raiseException): + raise Exception("Can't create dnssec name") + return name + + #LDNS_DNSSEC_NAME_METHODS_# + def add_rr(self,rr): + """Inserts the given rr at the right place in the current dnssec_name No checking is done whether the name matches. + + :param rr: + The RR to add + :returns: (ldns_status) LDNS_STATUS_OK on success, error code otherwise + """ + return _ldns.ldns_dnssec_name_add_rr(self,rr) + #parameters: ldns_dnssec_name *,ldns_rr *, + #retvals: ldns_status + + def find_rrset(self,atype): + """Find the RRset with the given type in within this name structure. + + :param atype: + :returns: (ldns_dnssec_rrsets \*) the RRset, or NULL if not present + """ + return _ldns.ldns_dnssec_name_find_rrset(self,atype) + #parameters: ldns_dnssec_name *,ldns_rr_type, + #retvals: ldns_dnssec_rrsets * + + def name(self): + """Returns the domain name of the given dnssec_name structure. + + :returns: (ldns_rdf \*) the domain name + """ + return _ldns.ldns_dnssec_name_name(self) + #parameters: ldns_dnssec_name *, + #retvals: ldns_rdf * + + def set_name(self,dname): + """Sets the domain name of the given dnssec_name structure. + + :param dname: + the domain name to set it to. This data is *not* copied. + """ + _ldns.ldns_dnssec_name_set_name(self,dname) + #parameters: ldns_dnssec_name *,ldns_rdf *, + #retvals: + + def set_nsec(self,nsec): + """Sets the NSEC(3) RR of the given dnssec_name structure. + + :param nsec: + the nsec rr to set it to. This data is *not* copied. + """ + _ldns.ldns_dnssec_name_set_nsec(self,nsec) + #parameters: ldns_dnssec_name *,ldns_rr *, + #retvals: + #_LDNS_DNSSEC_NAME_METHODS# + %} +} + +// ================================================================================ +// DNNSEC ZONE +// ================================================================================ +%nodefaultctor ldns_dnssec_zone; //no default constructor & destructor +%nodefaultdtor ldns_dnssec_zone; + +%newobject ldns_dnssec_zone_new; +%delobject ldns_dnssec_zone_free; + +%inline %{ +ldns_status ldns_dnssec_zone_sign_defcb(ldns_dnssec_zone *zone, ldns_rr_list *new_rrs, ldns_key_list *key_list, int cbtype) +{ + if (cbtype == 0) + return ldns_dnssec_zone_sign(zone, new_rrs, key_list, ldns_dnssec_default_add_to_signatures, NULL); + if (cbtype == 1) + return ldns_dnssec_zone_sign(zone, new_rrs, key_list, ldns_dnssec_default_leave_signatures, NULL); + if (cbtype == 2) + return ldns_dnssec_zone_sign(zone, new_rrs, key_list, ldns_dnssec_default_delete_signatures, NULL); + + return ldns_dnssec_zone_sign(zone, new_rrs, key_list, ldns_dnssec_default_replace_signatures, NULL); +} +%} + +%extend ldns_dnssec_zone { + %pythoncode %{ + + def __init__(self): + """Creates a new dnssec_zone instance""" + self.this = _ldns.ldns_dnssec_zone_new() + if not self.this: + raise Exception("Can't create dnssec zone instance") + + __swig_destroy__ = _ldns.ldns_dnssec_zone_free + + def print_to_file(self,file): + """Prints the complete zone to the given file descriptor. + + :param file: file pointer + """ + _ldns.ldns_dnssec_zone_print(file, self) + #parameters: FILE *, ldns_dnssec_zone *, + #retvals: + + def create_nsec3s(self,new_rrs,algorithm,flags,iterations,salt_length,salt): + """Adds NSEC3 records to the zone. + + :param new_rrs: + :param algorithm: + :param flags: + :param iterations: + :param salt_length: + :param salt: + :returns: (ldns_status) + """ + return _ldns.ldns_dnssec_zone_create_nsec3s(self,new_rrs,algorithm,flags,iterations,salt_length,salt) + #parameters: ldns_dnssec_zone *,ldns_rr_list *,uint8_t,uint8_t,uint16_t,uint8_t,uint8_t *, + #retvals: ldns_status + + def create_nsecs(self,new_rrs): + """Adds NSEC records to the given dnssec_zone. + + :param new_rrs: + ldns_rr's created by this function are added to this rr list, so the caller can free them later + :returns: (ldns_status) LDNS_STATUS_OK on success, an error code otherwise + """ + return _ldns.ldns_dnssec_zone_create_nsecs(self,new_rrs) + #parameters: ldns_dnssec_zone *,ldns_rr_list *, + #retvals: ldns_status + + def create_rrsigs(self,new_rrs,key_list,func,arg): + """Adds signatures to the zone. + + :param new_rrs: + the RRSIG RRs that are created are also added to this list, so the caller can free them later + :param key_list: + list of keys to sign with. + :param func: + Callback function to decide what keys to use and what to do with old signatures + :param arg: + Optional argument for the callback function + :returns: (ldns_status) LDNS_STATUS_OK on success, error otherwise + """ + return _ldns.ldns_dnssec_zone_create_rrsigs(self,new_rrs,key_list,func,arg) + #parameters: ldns_dnssec_zone *,ldns_rr_list *,ldns_key_list *,int(*)(ldns_rr *, void *),void *, + #retvals: ldns_status + + def sign_cb(self,new_rrs,key_list,func,arg): + """signs the given zone with the given keys (with callback function) + + :param new_rrs: + newly created resource records are added to this list, to free them later + :param key_list: + the list of keys to sign the zone with + :param func: + callback function that decides what to do with old signatures. + This function takes an ldns_rr and an optional arg argument, and returns one of four values: + + * LDNS_SIGNATURE_LEAVE_ADD_NEW - leave the signature and add a new one for the corresponding key + + * LDNS_SIGNATURE_REMOVE_ADD_NEW - remove the signature and replace is with a new one from the same key + + * LDNS_SIGNATURE_LEAVE_NO_ADD - leave the signature and do not add a new one with the corresponding key + + * LDNS_SIGNATURE_REMOVE_NO_ADD - remove the signature and do not replace + + :param arg: + optional argument for the callback function + :returns: (ldns_status) LDNS_STATUS_OK on success, an error code otherwise + """ + return _ldns.ldns_dnssec_zone_sign(self,new_rrs,key_list,func,arg) + #parameters: ldns_dnssec_zone *,ldns_rr_list *,ldns_key_list *,int(*)(ldns_rr *, void *),void *, + #retvals: ldns_status + + def sign(self,new_rrs,key_list, cbtype=3): + """signs the given zone with the given keys + + :param new_rrs: + newly created resource records are added to this list, to free them later + :param key_list: + the list of keys to sign the zone with + :param cb_type: + specifies how to deal with old signatures, possible values: + + * 0 - ldns_dnssec_default_add_to_signatures, + + * 1 - ldns_dnssec_default_leave_signatures, + + * 2 - ldns_dnssec_default_delete_signatures, + + * 3 - ldns_dnssec_default_replace_signatures + + :returns: (ldns_status) LDNS_STATUS_OK on success, an error code otherwise + """ + return _ldns.ldns_dnssec_zone_sign_defcb(self,new_rrs,key_list, cbtype) + #parameters: ldns_dnssec_zone *,ldns_rr_list *,ldns_key_list *, + #retvals: ldns_status + + def sign_nsec3(self,new_rrs,key_list,func,arg,algorithm,flags,iterations,salt_length,salt): + """signs the given zone with the given new zone, with NSEC3 + + :param new_rrs: + newly created resource records are added to this list, to free them later + :param key_list: + the list of keys to sign the zone with + :param func: + callback function that decides what to do with old signatures + :param arg: + optional argument for the callback function + :param algorithm: + the NSEC3 hashing algorithm to use + :param flags: + NSEC3 flags + :param iterations: + the number of NSEC3 hash iterations to use + :param salt_length: + the length (in octets) of the NSEC3 salt + :param salt: + the NSEC3 salt data + :returns: (ldns_status) LDNS_STATUS_OK on success, an error code otherwise + """ + return _ldns.ldns_dnssec_zone_sign_nsec3(self,new_rrs,key_list,func,arg,algorithm,flags,iterations,salt_length,salt) + #parameters: ldns_dnssec_zone *,ldns_rr_list *,ldns_key_list *,int(*)(ldns_rr *, void *),void *,uint8_t,uint8_t,uint16_t,uint8_t,uint8_t *, + #retvals: ldns_status + + #LDNS_DNSSEC_ZONE_METHODS_# + def add_empty_nonterminals(self): + """Adds explicit dnssec_name structures for the empty nonterminals in this zone. + + (this is needed for NSEC3 generation) + + :returns: (ldns_status) + """ + return _ldns.ldns_dnssec_zone_add_empty_nonterminals(self) + #parameters: ldns_dnssec_zone *, + #retvals: ldns_status + + def add_rr(self,rr): + """Adds the given RR to the zone. + + It find whether there is a dnssec_name with that name present. + If so, add it to that, if not create a new one. + Special handling of NSEC and RRSIG provided. + + :param rr: + The RR to add + :returns: (ldns_status) LDNS_STATUS_OK on success, an error code otherwise + """ + return _ldns.ldns_dnssec_zone_add_rr(self,rr) + #parameters: ldns_dnssec_zone *,ldns_rr *, + #retvals: ldns_status + + def find_rrset(self,dname,atype): + """Find the RRset with the given name and type in the zone. + + :param dname: + the domain name of the RRset to find + :param atype: + :returns: (ldns_dnssec_rrsets \*) the RRset, or NULL if not present + """ + return _ldns.ldns_dnssec_zone_find_rrset(self,dname,atype) + #parameters: ldns_dnssec_zone *,ldns_rdf *,ldns_rr_type, + #retvals: ldns_dnssec_rrsets * + + #_LDNS_DNSSEC_ZONE_METHODS# + %} +} diff --git a/contrib/python/ldns_key.i b/contrib/python/ldns_key.i new file mode 100644 index 000000000000..26a9b0f57fa4 --- /dev/null +++ b/contrib/python/ldns_key.i @@ -0,0 +1,536 @@ +/****************************************************************************** + * ldns_key.i: LDNS key class + * + * Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz) + * Karel Slany (slany AT fit.vutbr.cz) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the organization nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +%typemap(in,numinputs=0,noblock=1) (ldns_key **) +{ + ldns_key *$1_key; + $1 = &$1_key; +} + +/* result generation */ +%typemap(argout,noblock=1) (ldns_key **) +{ + $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(SWIG_as_voidptr($1_key), SWIGTYPE_p_ldns_struct_key, SWIG_POINTER_OWN | 0 )); +} + +%exception ldns_key_set_pubkey_owner(ldns_key *k, ldns_rdf *r) %{ $action Py_INCREF(obj1); %} + +%nodefaultctor ldns_struct_key; //no default constructor & destructor +%nodefaultdtor ldns_struct_key; + +%delobject ldns_key_free; +%delobject ldns_key_deep_free; +%newobject ldns_key_list_pop_key; +%newobject ldns_key2rr; +%newobject ldns_key_new_frm_algorithm; +%newobject ldns_key_new_frm_fp; +%newobject ldns_key_new_frm_fp_l; +%newobject ldns_key_new_frm_engine; + +%rename(ldns_key) ldns_struct_key; + +#ifdef LDNS_DEBUG +%rename(__ldns_key_free) ldns_key_free; +%inline %{ +void _ldns_key_free (ldns_key* k) { + printf("******** LDNS_KEY free 0x%lX ************\n", (long unsigned int)k); + ldns_key_deep_free(k); +} +%} +#else +%rename(_ldns_key_free) ldns_key_deep_free; +%rename(__ldns_key_free) ldns_key_free; +#endif + +%feature("docstring") ldns_struct_key "Key class + +This class can contains all types of keys that are used in DNSSEC. Mostly used to store private keys, since public keys can also be stored in a ldns_rr with type LDNS_RR_TYPE_DNSKEY. This class can also store some variables that influence the signatures generated by signing with this key, for instance the inception date. + +**Usage** + + >>> import ldns + >>> ldns.ldns_init_random(open(\"/dev/random\",\"rb\"), 512/8) + >>> key = ldns.ldns_key.new_frm_algorithm(ldns.LDNS_SIGN_DSA, 512) #generate new DSA key + >>> print key + Private-key-format: v1.2 + Algorithm: 3 (DSA) + Prime(p): XXXXXXXXHRQBGRflHZQriSAoLI2g+LGvZz8BlEesO+ZQg65wrFGs9IC441y/mn3nFnXfCdtX6zbN5bQuabPdlQ== + Subprime(q): XXXXXdnWs/cWsGDglhEyZRLEVA8= + Base(g): XXXXXXXqrd+dm2bcxDBdCsZRzkXQ22FxCk2ycnjgevr+s2HfA57BPk3xwqCrHUwuOBVg3Fvq4bpldrCe0sT6Og== + Private_value(x): XXXXXcVubZF33pj04z4ZoETsQW1Y= + Public_value(y): XXXXXX8t6zfOxJHoy57qteIw9sOZ/Zu0yFiPO083sPm11NlFx3b4m7TJ2k41gYicHXHLUQK1p0xXFToeZEkPGQ== + >>> fw = open(\"key.priv\", \"wb\") + >>> key.print_to_file(fw) #write priv key to file +" + +%extend ldns_struct_key { + + %pythoncode %{ + def __init__(self): + self.this = _ldns.ldns_key_new() + if not self.this: + raise Exception("Can't create instance of this class") + + __swig_destroy__ = _ldns._ldns_key_free + + def __str__(self): + """converts the data to presentation format""" + return _ldns.ldns_key2str(self) + + + def key_to_rr(self): + """converts a ldns_key to a public key rr + + :returns: (ldns_rr \*) ldns_rr representation of the key + """ + return _ldns.ldns_key2rr(self) + #parameters: const ldns_key *, + #retvals: ldns_rr * + + def print_to_file(self, file): + """print a private key to the file ouput + + :param file: output file pointer + """ + _ldns.ldns_key_print(file, self) + #parameters: FILE *, const ldns_key *, + #retvals: + + #LDNS_KEY_CONSTRUCTORS_# + @staticmethod + def new_frm_fp(file, raiseException=True): + """Creates a new priv key based on the contents of the file pointed by fp. + + :param file: a file object + :param raiseException: if True, an exception occurs in case a key instance can't be created + :returns: key instance or None. If the object can't be created and raiseException is True, an exception occurs. + """ + status, key = _ldns.ldns_key_new_frm_fp(file) + if status != LDNS_STATUS_OK: + if (raiseException): raise Exception("Can't create key, error: %s (%d)" % (_ldns.ldns_get_errorstr_by_id(status),status)) + return None + return key + + @staticmethod + def new_frm_fp_l(file, raiseException=True): + """Creates a new private key based on the contents of the file pointed by fp. + + :param file: a file object + :param raiseException: if True, an exception occurs in case a key instance can't be created + :returns: + * key - key instance or None. If an instance can't be created and raiseException is True, an exception occurs. + + * line - the line number (for debugging) + """ + status, key, line = _ldns.ldns_key_new_frm_fp_l(file) + if status != LDNS_STATUS_OK: + if (raiseException): raise Exception("Can't create key, error: %d" % status) + return None + return key, line + + @staticmethod + def new_frm_algorithm(algorithm, size, raiseException=True): + """Creates a new key based on the algorithm. + + :param algorithm: the algorithm to use + :param size: the number of bytes for the keysize + :param raiseException: if True, an exception occurs in case a key instance can't be created + :returns: key instance or None. If the object can't be created and raiseException is True, an exception occurs. + + **Algorithms** + LDNS_SIGN_RSAMD5, LDNS_SIGN_RSASHA1, LDNS_SIGN_DSA, LDNS_SIGN_RSASHA1_NSEC3, LDNS_SIGN_RSASHA256, LDNS_SIGN_RSASHA256_NSEC3, LDNS_SIGN_RSASHA512, LDNS_SIGN_RSASHA512_NSEC3, LDNS_SIGN_DSA_NSEC3, LDNS_SIGN_HMACMD5, LDNS_SIGN_HMACSHA1, LDNS_SIGN_HMACSHA256 + """ + key = _ldns.ldns_key_new_frm_algorithm(algorithm, size) + if (not key) and (raiseException): raise Exception("Can't create key, error: %d" % status) + return key + #_LDNS_KEY_CONSTRUCTORS# + + #LDNS_KEY_METHODS_# + def algorithm(self): + """return the signing alg of the key + + :returns: (ldns_signing_algorithm) the algorithm + """ + return _ldns.ldns_key_algorithm(self) + #parameters: const ldns_key *, + #retvals: ldns_signing_algorithm + + def dsa_key(self): + """returns the (openssl) DSA struct contained in the key + + :returns: (DSA \*) + """ + return _ldns.ldns_key_dsa_key(self) + #parameters: const ldns_key *, + #retvals: DSA * + + def evp_key(self): + """returns the (openssl) EVP struct contained in the key + + :returns: (EVP_PKEY \*) the RSA * structure in the key + """ + return _ldns.ldns_key_evp_key(self) + #parameters: const ldns_key *, + #retvals: EVP_PKEY * + + def expiration(self): + """return the key's expiration date + + :returns: (uint32_t) the experiration date + """ + return _ldns.ldns_key_expiration(self) + #parameters: const ldns_key *, + #retvals: uint32_t + + def flags(self): + """return the flag of the key + + :returns: (uint16_t) the flag + """ + return _ldns.ldns_key_flags(self) + #parameters: const ldns_key *, + #retvals: uint16_t + + def hmac_key(self): + """return the hmac key data + + :returns: (unsigned char \*) the hmac key data + """ + return _ldns.ldns_key_hmac_key(self) + #parameters: const ldns_key *, + #retvals: unsigned char * + + def hmac_size(self): + """return the hmac key size + + :returns: (size_t) the hmac key size + """ + return _ldns.ldns_key_hmac_size(self) + #parameters: const ldns_key *, + #retvals: size_t + + def inception(self): + """return the key's inception date + + :returns: (uint32_t) the inception date + """ + return _ldns.ldns_key_inception(self) + #parameters: const ldns_key *, + #retvals: uint32_t + + def keytag(self): + """return the keytag + + :returns: (uint16_t) the keytag + """ + return _ldns.ldns_key_keytag(self) + #parameters: const ldns_key *, + #retvals: uint16_t + + def origttl(self): + """return the original ttl of the key + + :returns: (uint32_t) the original ttl + """ + return _ldns.ldns_key_origttl(self) + #parameters: const ldns_key *, + #retvals: uint32_t + + def pubkey_owner(self): + """return the public key's owner + + :returns: (ldns_rdf \*) the owner + """ + return _ldns.ldns_key_pubkey_owner(self) + #parameters: const ldns_key *, + #retvals: ldns_rdf * + + def rsa_key(self): + """returns the (openssl) RSA struct contained in the key + + :returns: (RSA \*) the RSA * structure in the key + """ + return _ldns.ldns_key_rsa_key(self) + #parameters: const ldns_key *, + #retvals: RSA * + + def set_algorithm(self,l): + """Set the key's algorithm. + + :param l: + the algorithm + """ + _ldns.ldns_key_set_algorithm(self,l) + #parameters: ldns_key *,ldns_signing_algorithm, + #retvals: + + def set_dsa_key(self,d): + """Set the key's dsa data. + + :param d: + the dsa data + """ + _ldns.ldns_key_set_dsa_key(self,d) + #parameters: ldns_key *,DSA *, + #retvals: + + def set_evp_key(self,e): + """Set the key's evp key. + + :param e: + the evp key + """ + _ldns.ldns_key_set_evp_key(self,e) + #parameters: ldns_key *,EVP_PKEY *, + #retvals: + + def set_expiration(self,e): + """Set the key's expiration date (seconds after epoch). + + :param e: + the expiration + """ + _ldns.ldns_key_set_expiration(self,e) + #parameters: ldns_key *,uint32_t, + #retvals: + + def set_flags(self,flags): + """Set the key's flags. + + :param flags: + the flags + """ + _ldns.ldns_key_set_flags(self,flags) + #parameters: ldns_key *,uint16_t, + #retvals: + + def set_hmac_key(self,hmac): + """Set the key's hmac data. + + :param hmac: + the raw key data + """ + _ldns.ldns_key_set_hmac_key(self,hmac) + #parameters: ldns_key *,unsigned char *, + #retvals: + + def set_hmac_size(self,hmac_size): + """Set the key's hmac size. + + :param hmac_size: + the size of the hmac data + """ + _ldns.ldns_key_set_hmac_size(self,hmac_size) + #parameters: ldns_key *,size_t, + #retvals: + + def set_inception(self,i): + """Set the key's inception date (seconds after epoch). + + :param i: + the inception + """ + _ldns.ldns_key_set_inception(self,i) + #parameters: ldns_key *,uint32_t, + #retvals: + + def set_keytag(self,tag): + """Set the key's key tag. + + :param tag: + the keytag + """ + _ldns.ldns_key_set_keytag(self,tag) + #parameters: ldns_key *,uint16_t, + #retvals: + + def set_origttl(self,t): + """Set the key's original ttl. + + :param t: + the ttl + """ + _ldns.ldns_key_set_origttl(self,t) + #parameters: ldns_key *,uint32_t, + #retvals: + + def set_pubkey_owner(self,r): + """Set the key's pubkey owner. + + :param r: + the owner + """ + _ldns.ldns_key_set_pubkey_owner(self,r) + #parameters: ldns_key *,ldns_rdf *, + #retvals: + + def set_rsa_key(self,r): + """Set the key's rsa data. + + :param r: + the rsa data + """ + _ldns.ldns_key_set_rsa_key(self,r) + #parameters: ldns_key *,RSA *, + #retvals: + + def set_use(self,v): + """set the use flag + + :param v: + the boolean value to set the _use field to + """ + _ldns.ldns_key_set_use(self,v) + #parameters: ldns_key *,bool, + #retvals: + + def use(self): + """return the use flag + + :returns: (bool) the boolean value of the _use field + """ + return _ldns.ldns_key_use(self) + #parameters: const ldns_key *, + #retvals: bool + #_LDNS_KEY_METHODS# + %} +} + +%nodefaultctor ldns_struct_key_list; //no default constructor & destructor +%nodefaultdtor ldns_struct_key_list; + +%newobject ldns_key_list_new; +%newobject ldns_key_list_pop_key; +%delobject ldns_key_list_free; +%delobject ldns_key_list_push_key; + +%rename(ldns_key_list) ldns_struct_key_list; + +#ifdef LDNS_DEBUG +%rename(__ldns_key_list_free) ldns_key_list_free; +%inline %{ +void _ldns_key_list_free (ldns_key_list* k) { + printf("******** LDNS_KEY_LIST free 0x%lX ************\n", (long unsigned int)k); + ldns_key_list_free(k); +} +%} +#else +%rename(_ldns_key_list_free) ldns_key_list_free; +#endif + +%extend ldns_struct_key_list { + + %pythoncode %{ + def __init__(self): + self.this = _ldns.ldns_key_list_new() + if not self.this: + raise Exception("Can't create class") + + __swig_destroy__ = _ldns._ldns_key_list_free + + def keys(self): + """Key list iterator""" + for i in range(0, self.key_count()): + yield self.key(i) + + def __str__(self): + i = 0 + s = "" + for k in self.keys(): + i += 1 + s += "key %d:\n %s\n" % (i, str(k).replace("\n","\n ")) + return s + + #LDNS_KEY_LIST_METHODS_# + def key(self,nr): + """returns a pointer to the key in the list at the given position + + :param nr: + the position in the list + :returns: (ldns_key \*) the key + """ + return _ldns.ldns_key_list_key(self,nr) + #parameters: const ldns_key_list *,size_t, + #retvals: ldns_key * + + def key_count(self): + """returns the number of keys in the key list + + :returns: (size_t) the numbers of keys in the list + """ + return _ldns.ldns_key_list_key_count(self) + #parameters: const ldns_key_list *, + #retvals: size_t + + def pop_key(self): + """pops the last rr from a keylist + + :returns: (ldns_key \*) NULL if nothing to pop. Otherwise the popped RR + """ + return _ldns.ldns_key_list_pop_key(self) + #parameters: ldns_key_list *, + #retvals: ldns_key * + + def push_key(self,key): + """pushes a key to a keylist + + :param key: + the key to push + :returns: (bool) false on error, otherwise true + """ + return _ldns.ldns_key_list_push_key(self,key) + #parameters: ldns_key_list *,ldns_key *, + #retvals: bool + + def set_key_count(self,count): + """Set the keylist's key count to count. + + :param count: + the cuont + """ + _ldns.ldns_key_list_set_key_count(self,count) + #parameters: ldns_key_list *,size_t, + #retvals: + + def set_use(self,v): + """Set the 'use' flag for all keys in the list. + + :param v: + The value to set the use flags to + """ + _ldns.ldns_key_list_set_use(self,v) + #parameters: ldns_key_list *,bool, + #retvals: + + #_LDNS_KEY_LIST_METHODS# + %} +} + diff --git a/contrib/python/ldns_packet.i b/contrib/python/ldns_packet.i new file mode 100644 index 000000000000..a1ad6b7c8214 --- /dev/null +++ b/contrib/python/ldns_packet.i @@ -0,0 +1,1086 @@ +/****************************************************************************** + * ldns_packet.i: LDNS packet class + * + * Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz) + * Karel Slany (slany AT fit.vutbr.cz) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the organization nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ +%typemap(in,numinputs=0,noblock=1) (ldns_pkt **) +{ + ldns_pkt *$1_pkt; + $1 = &$1_pkt; +} + +/* result generation */ +%typemap(argout,noblock=1) (ldns_pkt **) +{ + $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(SWIG_as_voidptr($1_pkt), SWIGTYPE_p_ldns_struct_pkt, SWIG_POINTER_OWN | 0 )); +} + +%newobject ldns_pkt_new; +%newobject ldns_pkt_clone; +%newobject ldns_pkt_rr_list_by_type; +%newobject ldns_pkt_rr_list_by_name_and_type; +%newobject ldns_pkt_rr_list_by_name; +%newobject ldns_update_pkt_new; + + +%nodefaultctor ldns_struct_pkt; //no default constructor & destructor +%nodefaultdtor ldns_struct_pkt; + +%rename(ldns_pkt) ldns_struct_pkt; +#ifdef LDNS_DEBUG +%rename(__ldns_pkt_free) ldns_pkt_free; +%inline %{ +void _ldns_pkt_free (ldns_pkt* p) { + printf("******** LDNS_PKT free 0x%lX ************\n", (long unsigned int)p); + ldns_pkt_free(p); +} +%} +#else +%rename(_ldns_pkt_free) ldns_pkt_free; +#endif + +%newobject ldns_pkt2str; +%newobject ldns_pkt_opcode2str; +%newobject ldns_pkt_rcode2str; +%newobject ldns_pkt_algorithm2str; +%newobject ldns_pkt_cert_algorithm2str; + + +/* cloning of packet_lists to make them independent of the original packet */ + +%newobject _ldns_pkt_additional; +%newobject _ldns_pkt_answer; +%newobject _ldns_pkt_authority; +%newobject _ldns_pkt_question; + +%rename(__ldns_pkt_additional) ldns_pkt_additional; +%inline %{ +ldns_rr_list* _ldns_pkt_additional(ldns_pkt* p) { + return ldns_rr_list_clone(ldns_pkt_additional(p)); +} +%} + +%rename(__ldns_pkt_answer) ldns_pkt_answer; +%inline %{ +ldns_rr_list* _ldns_pkt_answer(ldns_pkt* p) { + return ldns_rr_list_clone(ldns_pkt_answer(p)); +} +%} + +%rename(__ldns_pkt_authority) ldns_pkt_authority; +%inline %{ +ldns_rr_list* _ldns_pkt_authority(ldns_pkt* p) { + return ldns_rr_list_clone(ldns_pkt_authority(p)); +} +%} + +%rename(__ldns_pkt_question) ldns_pkt_question; +%inline %{ +ldns_rr_list* _ldns_pkt_question(ldns_pkt* p) { + return ldns_rr_list_clone(ldns_pkt_question(p)); +} +%} + +/* clone data when pushed in */ + +%rename(__ldns_pkt_push_rr) ldns_pkt_push_rr; +%inline %{ +bool _ldns_pkt_push_rr(ldns_pkt* p, ldns_pkt_section sec, ldns_rr *rr) { + return ldns_pkt_push_rr(p, sec, ldns_rr_clone(rr)); +} +%} + +%rename(__ldns_pkt_push_rr_list) ldns_pkt_push_rr_list; +%inline %{ +bool _ldns_pkt_push_rr_list(ldns_pkt* p, ldns_pkt_section sec, ldns_rr_list *rrl) { + return ldns_pkt_push_rr_list(p, sec, ldns_rr_list_clone(rrl)); +} +%} + +%feature("docstring") ldns_struct_pkt "LDNS packet object. + +The ldns_pkt object contains DNS packed (either a query or an answer). It is the complete representation of what you actually send to a nameserver, and what you get back (see :class:`ldns.ldns_resolver`). + +**Usage** + +>>> import ldns +>>> resolver = ldns.ldns_resolver.new_frm_file(\"/etc/resolv.conf\") +>>> pkt = resolver.query(\"nic.cz\", ldns.LDNS_RR_TYPE_NS,ldns.LDNS_RR_CLASS_IN) +>>> print pkt +;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 63004 +;; flags: qr rd ra ; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0 +;; QUESTION SECTION: +;; nic.cz. IN NS +;; ANSWER SECTION: +nic.cz. 758 IN NS a.ns.nic.cz. +nic.cz. 758 IN NS c.ns.nic.cz. +nic.cz. 758 IN NS e.ns.nic.cz. +;; AUTHORITY SECTION: +;; ADDITIONAL SECTION: +;; Query time: 8 msec +;; SERVER: 82.100.38.2 +;; WHEN: Thu Jan 11 12:54:33 2009 +;; MSG SIZE rcvd: 75 + +This simple example instances a resolver in order to resolve NS for nic.cz. +" + +%extend ldns_struct_pkt { + + %pythoncode %{ + def __init__(self): + raise Exception("This class can't be created directly. Please use: ldns_pkt_new(), ldns_pkt_query_new() or ldns_pkt_query_new_frm_str()") + + __swig_destroy__ = _ldns._ldns_pkt_free + + #LDNS_PKT_CONSTRUCTORS_# + @staticmethod + def new_query(rr_name, rr_type, rr_class, flags): + """Creates a packet with a query in it for the given name, type and class. + + :param rr_name: the name to query for + :param rr_type: the type to query for + :param rr_class: the class to query for + :param flags: packet flags + :returns: new ldns_pkt object + """ + return _ldns.ldns_pkt_query_new(rr_name, rr_type, rr_class, flags) + + @staticmethod + def new_query_frm_str(rr_name, rr_type, rr_class, flags, raiseException = True): + """Creates a query packet for the given name, type, class. + + :param rr_name: the name to query for + :param rr_type: the type to query for + :param rr_class: the class to query for + :param flags: packet flags + :param raiseException: if True, an exception occurs in case a resolver object can't be created + :returns: query packet object or None. If the object can't be created and raiseException is True, an exception occurs. + + + **Usage** + + >>> pkt = ldns.ldns_pkt.new_query_frm_str("test.nic.cz",ldns.LDNS_RR_TYPE_ANY, ldns.LDNS_RR_CLASS_IN, ldns.LDNS_QR | ldns.LDNS_AA) + >>> rra = ldns.ldns_rr.new_frm_str("test.nic.cz. IN A 192.168.1.1",300) + >>> list = ldns.ldns_rr_list() + >>> if (rra): list.push_rr(rra) + >>> pkt.push_rr_list(ldns.LDNS_SECTION_ANSWER, list) + >>> print pkt + ;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 0 + ;; flags: qr aa ; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 + ;; QUESTION SECTION: + ;; test.nic.cz. IN ANY + ;; ANSWER SECTION: + test.nic.cz. 300 IN A 192.168.1.1 + ;; AUTHORITY SECTION: + ;; ADDITIONAL SECTION: + ;; Query time: 0 msec + ;; WHEN: Thu Jan 1 01:00:00 1970 + ;; MSG SIZE rcvd: 0 + """ + status, pkt = _ldns.ldns_pkt_query_new_frm_str(rr_name, rr_type, rr_class, flags) + if status != LDNS_STATUS_OK: + if (raiseException): raise Exception("Can't create query packet, error: %d" % status) + return None + return pkt + #_LDNS_PKT_CONSTRUCTORS# + + def __str__(self): + """Converts the data in the DNS packet to presentation format""" + return _ldns.ldns_pkt2str(self) + + def opcode2str(self): + """Converts a packet opcode to its mnemonic and returns that as an allocated null-terminated string.""" + return _ldns.ldns_pkt_opcode2str(sefl.get_opcode()) + + def rcode2str(self): + """Converts a packet rcode to its mnemonic and returns that as an allocated null-terminated string.""" + return _ldns.ldns_pkt_rcode2str(self.get_rcode()) + + def print_to_file(self,output): + """Prints the data in the DNS packet to the given file stream (in presentation format).""" + _ldns.ldns_pkt_print(output,self) + #parameters: FILE *,const ldns_pkt *, + + def write_to_buffer(self, buffer): + """Copies the packet data to the buffer in wire format. + + :param buffer: buffer to append the result to + :returns: (ldns_status) ldns_status + """ + return _ldns.ldns_pkt2buffer_wire(buffer, self) + #parameters: ldns_buffer *,const ldns_pkt *, + #retvals: ldns_status + + @staticmethod + def algorithm2str(alg): + """Converts a signing algorithms to its mnemonic and returns that as an allocated null-terminated string.""" + return _ldns.ldns_pkt_algorithm2str(alg) + #parameters: ldns_algorithm, + + @staticmethod + def cert_algorithm2str(alg): + """Converts a cert algorithm to its mnemonic and returns that as an allocated null-terminated string.""" + return _ldns.ldns_pkt_cert_algorithm2str(alg) + #parameters: ldns_algorithm, + + #LDNS_PKT_METHODS_# + def aa(self): + """Read the packet's aa bit. + + :returns: (bool) value of the bit + """ + return _ldns.ldns_pkt_aa(self) + #parameters: const ldns_pkt *, + #retvals: bool + + def ad(self): + """Read the packet's ad bit. + + :returns: (bool) value of the bit + """ + return _ldns.ldns_pkt_ad(self) + #parameters: const ldns_pkt *, + #retvals: bool + + def additional(self): + """Return the packet's additional section. + + :returns: (ldns_rr_list \*) the section + """ + return _ldns._ldns_pkt_additional(self) + #parameters: const ldns_pkt *, + #retvals: ldns_rr_list * + + def all(self): + return _ldns.ldns_pkt_all(self) + #parameters: const ldns_pkt *, + #retvals: ldns_rr_list * + + def all_noquestion(self): + return _ldns.ldns_pkt_all_noquestion(self) + #parameters: const ldns_pkt *, + #retvals: ldns_rr_list * + + def ancount(self): + """Return the packet's an count. + + :returns: (uint16_t) the an count + """ + return _ldns.ldns_pkt_ancount(self) + #parameters: const ldns_pkt *, + #retvals: uint16_t + + def answer(self): + """Return the packet's answer section. + + :returns: (ldns_rr_list \*) the section + """ + return _ldns._ldns_pkt_answer(self) + #parameters: const ldns_pkt *, + #retvals: ldns_rr_list * + + def answerfrom(self): + """Return the packet's answerfrom. + + :returns: (ldns_rdf \*) the name of the server + """ + return _ldns.ldns_pkt_answerfrom(self) + #parameters: const ldns_pkt *, + #retvals: ldns_rdf * + + def arcount(self): + """Return the packet's ar count. + + :returns: (uint16_t) the ar count + """ + return _ldns.ldns_pkt_arcount(self) + #parameters: const ldns_pkt *, + #retvals: uint16_t + + def authority(self): + """Return the packet's authority section. + + :returns: (ldns_rr_list \*) the section + """ + return _ldns._ldns_pkt_authority(self) + #parameters: const ldns_pkt *, + #retvals: ldns_rr_list * + + def cd(self): + """Read the packet's cd bit. + + :returns: (bool) value of the bit + """ + return _ldns.ldns_pkt_cd(self) + #parameters: const ldns_pkt *, + #retvals: bool + + def clone(self): + """clones the given packet, creating a fully allocated copy + + :returns: (ldns_pkt \*) ldns_pkt* pointer to the new packet + """ + return _ldns.ldns_pkt_clone(self) + #parameters: ldns_pkt *, + #retvals: ldns_pkt * + + def edns(self): + """returns true if this packet needs and EDNS rr to be sent. + + At the moment the only reason is an expected packet size larger than 512 bytes, but for instance dnssec would be a good reason too. + + :returns: (bool) true if packet needs edns rr + """ + return _ldns.ldns_pkt_edns(self) + #parameters: const ldns_pkt *, + #retvals: bool + + def edns_data(self): + """return the packet's edns data + + :returns: (ldns_rdf \*) the data + """ + return _ldns.ldns_pkt_edns_data(self) + #parameters: const ldns_pkt *, + #retvals: ldns_rdf * + + def edns_do(self): + """return the packet's edns do bit + + :returns: (bool) the bit's value + """ + return _ldns.ldns_pkt_edns_do(self) + #parameters: const ldns_pkt *, + #retvals: bool + + def edns_extended_rcode(self): + """return the packet's edns extended rcode + + :returns: (uint8_t) the rcode + """ + return _ldns.ldns_pkt_edns_extended_rcode(self) + #parameters: const ldns_pkt *, + #retvals: uint8_t + + def edns_udp_size(self): + """return the packet's edns udp size + + :returns: (uint16_t) the size + """ + return _ldns.ldns_pkt_edns_udp_size(self) + #parameters: const ldns_pkt *, + #retvals: uint16_t + + def edns_version(self): + """return the packet's edns version + + :returns: (uint8_t) the version + """ + return _ldns.ldns_pkt_edns_version(self) + #parameters: const ldns_pkt *, + #retvals: uint8_t + + def edns_z(self): + """return the packet's edns z value + + :returns: (uint16_t) the z value + """ + return _ldns.ldns_pkt_edns_z(self) + #parameters: const ldns_pkt *, + #retvals: uint16_t + + def empty(self): + """check if a packet is empty + + :returns: (bool) true: empty, false: empty + """ + return _ldns.ldns_pkt_empty(self) + #parameters: ldns_pkt *, + #retvals: bool + + def get_opcode(self): + """Read the packet's code. + + :returns: (ldns_pkt_opcode) the opcode + """ + return _ldns.ldns_pkt_get_opcode(self) + #parameters: const ldns_pkt *, + #retvals: ldns_pkt_opcode + + def get_rcode(self): + """Return the packet's respons code. + + :returns: (ldns_pkt_rcode) the respons code + """ + return _ldns.ldns_pkt_get_rcode(self) + #parameters: const ldns_pkt *, + #retvals: ldns_pkt_rcode + + def get_section_clone(self,s): + """return all the rr_list's in the packet. + + Clone the lists, instead of returning pointers. + + :param s: + what section(s) to return + :returns: (ldns_rr_list \*) ldns_rr_list with the rr's or NULL if none were found + """ + return _ldns.ldns_pkt_get_section_clone(self,s) + #parameters: const ldns_pkt *,ldns_pkt_section, + #retvals: ldns_rr_list * + + def id(self): + """Read the packet id. + + :returns: (uint16_t) the packet id + """ + return _ldns.ldns_pkt_id(self) + #parameters: const ldns_pkt *, + #retvals: uint16_t + + def nscount(self): + """Return the packet's ns count. + + :returns: (uint16_t) the ns count + """ + return _ldns.ldns_pkt_nscount(self) + #parameters: const ldns_pkt *, + #retvals: uint16_t + + def push_rr(self,section,rr): + """push an rr on a packet + + :param section: + where to put it + :param rr: + rr to push + :returns: (bool) a boolean which is true when the rr was added + """ + return _ldns._ldns_pkt_push_rr(self,section,rr) + #parameters: ldns_pkt *,ldns_pkt_section,ldns_rr *, + #retvals: bool + + def push_rr_list(self,section,list): + """push a rr_list on a packet + + :param section: + where to put it + :param list: + the rr_list to push + :returns: (bool) a boolean which is true when the rr was added + """ + return _ldns._ldns_pkt_push_rr_list(self,section,list) + #parameters: ldns_pkt *,ldns_pkt_section,ldns_rr_list *, + #retvals: bool + + def qdcount(self): + """Return the packet's qd count. + + :returns: (uint16_t) the qd count + """ + return _ldns.ldns_pkt_qdcount(self) + #parameters: const ldns_pkt *, + #retvals: uint16_t + + def qr(self): + """Read the packet's qr bit. + + :returns: (bool) value of the bit + """ + return _ldns.ldns_pkt_qr(self) + #parameters: const ldns_pkt *, + #retvals: bool + + def querytime(self): + """Return the packet's querytime. + + :returns: (uint32_t) the querytime + """ + return _ldns.ldns_pkt_querytime(self) + #parameters: const ldns_pkt *, + #retvals: uint32_t + + def question(self): + """Return the packet's question section. + + :returns: (ldns_rr_list \*) the section + """ + return _ldns._ldns_pkt_question(self) + #parameters: const ldns_pkt *, + #retvals: ldns_rr_list * + + def ra(self): + """Read the packet's ra bit. + + :returns: (bool) value of the bit + """ + return _ldns.ldns_pkt_ra(self) + #parameters: const ldns_pkt *, + #retvals: bool + + def rd(self): + """Read the packet's rd bit. + + :returns: (bool) value of the bit + """ + return _ldns.ldns_pkt_rd(self) + #parameters: const ldns_pkt *, + #retvals: bool + + def reply_type(self): + """looks inside the packet to determine what kind of packet it is, AUTH, NXDOMAIN, REFERRAL, etc. + + :returns: (ldns_pkt_type) the type of packet + """ + return _ldns.ldns_pkt_reply_type(self) + #parameters: ldns_pkt *, + #retvals: ldns_pkt_type + + def rr(self,sec,rr): + """check to see if an rr exist in the packet + + :param sec: + in which section to look + :param rr: + the rr to look for + :returns: (bool) + """ + return _ldns.ldns_pkt_rr(self,sec,rr) + #parameters: ldns_pkt *,ldns_pkt_section,ldns_rr *, + #retvals: bool + + def rr_list_by_name(self,r,s): + """return all the rr with a specific name from a packet. + + Optionally specify from which section in the packet + + :param r: + the name + :param s: + the packet's section + :returns: (ldns_rr_list \*) a list with the rr's or NULL if none were found + """ + return _ldns.ldns_pkt_rr_list_by_name(self,r,s) + #parameters: ldns_pkt *,ldns_rdf *,ldns_pkt_section, + #retvals: ldns_rr_list * + + def rr_list_by_name_and_type(self,ownername,atype,sec): + """return all the rr with a specific type and type from a packet. + + Optionally specify from which section in the packet + + :param ownername: + the name + :param atype: + :param sec: + the packet's section + :returns: (ldns_rr_list \*) a list with the rr's or NULL if none were found + """ + return _ldns.ldns_pkt_rr_list_by_name_and_type(self,ownername,atype,sec) + #parameters: const ldns_pkt *,const ldns_rdf *,ldns_rr_type,ldns_pkt_section, + #retvals: ldns_rr_list * + + def rr_list_by_type(self,t,s): + """return all the rr with a specific type from a packet. + + Optionally specify from which section in the packet + + :param t: + the type + :param s: + the packet's section + :returns: (ldns_rr_list \*) a list with the rr's or NULL if none were found + """ + return _ldns.ldns_pkt_rr_list_by_type(self,t,s) + #parameters: const ldns_pkt *,ldns_rr_type,ldns_pkt_section, + #retvals: ldns_rr_list * + + def safe_push_rr(self,sec,rr): + """push an rr on a packet, provided the RR is not there. + + :param sec: + where to put it + :param rr: + rr to push + :returns: (bool) a boolean which is true when the rr was added + """ + return _ldns.ldns_pkt_safe_push_rr(self,sec,rr) + #parameters: ldns_pkt *,ldns_pkt_section,ldns_rr *, + #retvals: bool + + def safe_push_rr_list(self,sec,list): + """push an rr_list to a packet, provided the RRs are not already there. + + :param sec: + where to put it + :param list: + the rr_list to push + :returns: (bool) a boolean which is true when the rr was added + """ + return _ldns.ldns_pkt_safe_push_rr_list(self,sec,list) + #parameters: ldns_pkt *,ldns_pkt_section,ldns_rr_list *, + #retvals: bool + + def section_count(self,s): + return _ldns.ldns_pkt_section_count(self,s) + #parameters: const ldns_pkt *,ldns_pkt_section, + #retvals: uint16_t + + def set_aa(self,b): + """Set the packet's aa bit. + + :param b: + the value to set (boolean) + """ + _ldns.ldns_pkt_set_aa(self,b) + #parameters: ldns_pkt *,bool, + #retvals: + + def set_ad(self,b): + """Set the packet's ad bit. + + :param b: + the value to set (boolean) + """ + _ldns.ldns_pkt_set_ad(self,b) + #parameters: ldns_pkt *,bool, + #retvals: + + def set_additional(self,rr): + """directly set the additional section + + :param rr: + rrlist to set + """ + _ldns.ldns_pkt_set_additional(self,rr) + #parameters: ldns_pkt *,ldns_rr_list *, + #retvals: + + def set_ancount(self,c): + """Set the packet's an count. + + :param c: + the count + """ + _ldns.ldns_pkt_set_ancount(self,c) + #parameters: ldns_pkt *,uint16_t, + #retvals: + + def set_answer(self,rr): + """directly set the answer section + + :param rr: + rrlist to set + """ + _ldns.ldns_pkt_set_answer(self,rr) + #parameters: ldns_pkt *,ldns_rr_list *, + #retvals: + + def set_answerfrom(self,r): + """Set the packet's answering server. + + :param r: + the address + """ + _ldns.ldns_pkt_set_answerfrom(self,r) + #parameters: ldns_pkt *,ldns_rdf *, + #retvals: + + def set_arcount(self,c): + """Set the packet's arcount. + + :param c: + the count + """ + _ldns.ldns_pkt_set_arcount(self,c) + #parameters: ldns_pkt *,uint16_t, + #retvals: + + def set_authority(self,rr): + """directly set the auhority section + + :param rr: + rrlist to set + """ + _ldns.ldns_pkt_set_authority(self,rr) + #parameters: ldns_pkt *,ldns_rr_list *, + #retvals: + + def set_cd(self,b): + """Set the packet's cd bit. + + :param b: + the value to set (boolean) + """ + _ldns.ldns_pkt_set_cd(self,b) + #parameters: ldns_pkt *,bool, + #retvals: + + def set_edns_data(self,data): + """Set the packet's edns data. + + :param data: + the data + """ + _ldns.ldns_pkt_set_edns_data(self,data) + #parameters: ldns_pkt *,ldns_rdf *, + #retvals: + + def set_edns_do(self,value): + """Set the packet's edns do bit. + + :param value: + the bit's new value + """ + _ldns.ldns_pkt_set_edns_do(self,value) + #parameters: ldns_pkt *,bool, + #retvals: + + def set_edns_extended_rcode(self,c): + """Set the packet's edns extended rcode. + + :param c: + the code + """ + _ldns.ldns_pkt_set_edns_extended_rcode(self,c) + #parameters: ldns_pkt *,uint8_t, + #retvals: + + def set_edns_udp_size(self,s): + """Set the packet's edns udp size. + + :param s: + the size + """ + _ldns.ldns_pkt_set_edns_udp_size(self,s) + #parameters: ldns_pkt *,uint16_t, + #retvals: + + def set_edns_version(self,v): + """Set the packet's edns version. + + :param v: + the version + """ + _ldns.ldns_pkt_set_edns_version(self,v) + #parameters: ldns_pkt *,uint8_t, + #retvals: + + def set_edns_z(self,z): + """Set the packet's edns z value. + + :param z: + the value + """ + _ldns.ldns_pkt_set_edns_z(self,z) + #parameters: ldns_pkt *,uint16_t, + #retvals: + + def set_flags(self,flags): + """sets the flags in a packet. + + :param flags: + ORed values: LDNS_QR| LDNS_AR for instance + :returns: (bool) true on success otherwise false + """ + return _ldns.ldns_pkt_set_flags(self,flags) + #parameters: ldns_pkt *,uint16_t, + #retvals: bool + + def set_id(self,id): + """Set the packet's id. + + :param id: + the id to set + """ + _ldns.ldns_pkt_set_id(self,id) + #parameters: ldns_pkt *,uint16_t, + #retvals: + + def set_nscount(self,c): + """Set the packet's ns count. + + :param c: + the count + """ + _ldns.ldns_pkt_set_nscount(self,c) + #parameters: ldns_pkt *,uint16_t, + #retvals: + + def set_opcode(self,c): + """Set the packet's opcode. + + :param c: + the opcode + """ + _ldns.ldns_pkt_set_opcode(self,c) + #parameters: ldns_pkt *,ldns_pkt_opcode, + #retvals: + + def set_qdcount(self,c): + """Set the packet's qd count. + + :param c: + the count + """ + _ldns.ldns_pkt_set_qdcount(self,c) + #parameters: ldns_pkt *,uint16_t, + #retvals: + + def set_qr(self,b): + """Set the packet's qr bit. + + :param b: + the value to set (boolean) + """ + _ldns.ldns_pkt_set_qr(self,b) + #parameters: ldns_pkt *,bool, + #retvals: + + def set_querytime(self,t): + """Set the packet's query time. + + :param t: + the querytime in msec + """ + _ldns.ldns_pkt_set_querytime(self,t) + #parameters: ldns_pkt *,uint32_t, + #retvals: + + def set_question(self,rr): + """directly set the question section + + :param rr: + rrlist to set + """ + _ldns.ldns_pkt_set_question(self,rr) + #parameters: ldns_pkt *,ldns_rr_list *, + #retvals: + + def set_ra(self,b): + """Set the packet's ra bit. + + :param b: + the value to set (boolean) + """ + _ldns.ldns_pkt_set_ra(self,b) + #parameters: ldns_pkt *,bool, + #retvals: + + def set_random_id(self): + """Set the packet's id to a random value. + """ + _ldns.ldns_pkt_set_random_id(self) + #parameters: ldns_pkt *, + #retvals: + + def set_rcode(self,c): + """Set the packet's respons code. + + :param c: + the rcode + """ + _ldns.ldns_pkt_set_rcode(self,c) + #parameters: ldns_pkt *,uint8_t, + #retvals: + + def set_rd(self,b): + """Set the packet's rd bit. + + :param b: + the value to set (boolean) + """ + _ldns.ldns_pkt_set_rd(self,b) + #parameters: ldns_pkt *,bool, + #retvals: + + def set_section_count(self,s,x): + """Set a packet's section count to x. + + :param s: + the section + :param x: + the section count + """ + _ldns.ldns_pkt_set_section_count(self,s,x) + #parameters: ldns_pkt *,ldns_pkt_section,uint16_t, + #retvals: + + def set_size(self,s): + """Set the packet's size. + + :param s: + the size + """ + _ldns.ldns_pkt_set_size(self,s) + #parameters: ldns_pkt *,size_t, + #retvals: + + def set_tc(self,b): + """Set the packet's tc bit. + + :param b: + the value to set (boolean) + """ + _ldns.ldns_pkt_set_tc(self,b) + #parameters: ldns_pkt *,bool, + #retvals: + + def set_timestamp(self,timeval): + _ldns.ldns_pkt_set_timestamp(self,timeval) + #parameters: ldns_pkt *,struct timeval, + #retvals: + + def set_tsig(self,t): + """Set the packet's tsig rr. + + :param t: + the tsig rr + """ + _ldns.ldns_pkt_set_tsig(self,t) + #parameters: ldns_pkt *,ldns_rr *, + #retvals: + + def size(self): + """Return the packet's size in bytes. + + :returns: (size_t) the size + """ + return _ldns.ldns_pkt_size(self) + #parameters: const ldns_pkt *, + #retvals: size_t + + def tc(self): + """Read the packet's tc bit. + + :returns: (bool) value of the bit + """ + return _ldns.ldns_pkt_tc(self) + #parameters: const ldns_pkt *, + #retvals: bool + + def timestamp(self): + """Return the packet's timestamp. + + :returns: (struct timeval) the timestamp + """ + return _ldns.ldns_pkt_timestamp(self) + #parameters: const ldns_pkt *, + #retvals: struct timeval + + def tsig(self): + """Return the packet's tsig pseudo rr's. + + :returns: (ldns_rr \*) the tsig rr + """ + return _ldns.ldns_pkt_tsig(self) + #parameters: const ldns_pkt *, + #retvals: ldns_rr * + + #_LDNS_PKT_METHODS# + + #LDNS update methods + #LDNS_METHODS_# + def update_pkt_tsig_add(self,r): + """add tsig credentials to a packet from a resolver + + :param r: + resolver to copy from + :returns: (ldns_status) status wether successfull or not + """ + return _ldns.ldns_update_pkt_tsig_add(self,r) + #parameters: ldns_pkt *,ldns_resolver *, + #retvals: ldns_status + + def update_prcount(self): + """Get the zo count. + + :returns: (uint16_t) the pr count + """ + return _ldns.ldns_update_prcount(self) + #parameters: const ldns_pkt *, + #retvals: uint16_t + + def update_set_adcount(self,c): + """Set the ad count. + + :param c: + the ad count to set + """ + _ldns.ldns_update_set_adcount(self,c) + #parameters: ldns_pkt *,uint16_t, + #retvals: + + def update_set_prcount(self,c): + """Set the pr count. + + :param c: + the pr count to set + """ + _ldns.ldns_update_set_prcount(self,c) + #parameters: ldns_pkt *,uint16_t, + #retvals: + + def update_set_upcount(self,c): + """Set the up count. + + :param c: + the up count to set + """ + _ldns.ldns_update_set_upcount(self,c) + #parameters: ldns_pkt *,uint16_t, + #retvals: + + def update_set_zo(self,v): + _ldns.ldns_update_set_zo(self,v) + #parameters: ldns_pkt *,uint16_t, + #retvals: + + def update_upcount(self): + """Get the zo count. + + :returns: (uint16_t) the up count + """ + return _ldns.ldns_update_upcount(self) + #parameters: const ldns_pkt *, + #retvals: uint16_t + + def update_zocount(self): + """Get the zo count. + + :returns: (uint16_t) the zo count + """ + return _ldns.ldns_update_zocount(self) + #parameters: const ldns_pkt *, + #retvals: uint16_t + + #_LDNS_METHODS# + %} +} diff --git a/contrib/python/ldns_rdf.i b/contrib/python/ldns_rdf.i new file mode 100644 index 000000000000..5a7e30079646 --- /dev/null +++ b/contrib/python/ldns_rdf.i @@ -0,0 +1,426 @@ +/****************************************************************************** + * ldns_rdata.i: LDNS record data + * + * Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz) + * Karel Slany (slany AT fit.vutbr.cz) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the organization nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ + +//automatic conversion of const ldns_rdf* parameter from string +%typemap(in,noblock=1) const ldns_rdf * (void* argp, $1_ltype tmp = 0, int res) { + if (Python_str_Check($input)) { +#ifdef SWIG_Python_str_AsChar + tmp = ldns_dname_new_frm_str(SWIG_Python_str_AsChar($input)); +#else + tmp = ldns_dname_new_frm_str(PyString_AsString($input)); +#endif + if (tmp == NULL) { + %argument_fail(SWIG_TypeError, "char *", $symname, $argnum); + } + $1 = ($1_ltype) tmp; + } else { + res = SWIG_ConvertPtr($input, &argp, SWIGTYPE_p_ldns_struct_rdf, 0 | 0 ); + if (!SWIG_IsOK(res)) { + %argument_fail(res, "ldns_rdf const *", $symname, $argnum); + } + $1 = ($1_ltype) argp; + } +} + +%typemap(in,numinputs=0,noblock=1) (ldns_rdf **) +{ + ldns_rdf *$1_rdf; + $1 = &$1_rdf; +} + +// result generation +%typemap(argout,noblock=1) (ldns_rdf **) +{ + $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(SWIG_as_voidptr($1_rdf), SWIGTYPE_p_ldns_struct_rdf, SWIG_POINTER_OWN | 0 )); +} + +%nodefaultctor ldns_struct_rdf; //no default constructor & destructor +%nodefaultdtor ldns_struct_rdf; + +%newobject ldns_dname_new; +%newobject ldns_dname_new_frm_str; +%newobject ldns_dname_new_frm_data; + +%newobject ldns_rdf_new; +%newobject ldns_rdf_new_frm_str; +%newobject ldns_rdf_new_frm_data; + +%delobject ldns_rdf_deep_free; +%delobject ldns_rdf_free; + +%rename(ldns_rdf) ldns_struct_rdf; + +%inline %{ + +const char *ldns_rdf_type2str(const ldns_rdf *rdf) +{ + if (rdf) { + switch(ldns_rdf_get_type(rdf)) { + case LDNS_RDF_TYPE_NONE: return 0; + case LDNS_RDF_TYPE_DNAME: return "DNAME"; + case LDNS_RDF_TYPE_INT8: return "INT8"; + case LDNS_RDF_TYPE_INT16: return "INT16"; + case LDNS_RDF_TYPE_INT32: return "INT32"; + case LDNS_RDF_TYPE_PERIOD: return "PERIOD"; + case LDNS_RDF_TYPE_TSIGTIME: return "TSIGTIME"; + case LDNS_RDF_TYPE_A: return "A"; + case LDNS_RDF_TYPE_AAAA: return "AAAA"; + case LDNS_RDF_TYPE_STR: return "STR"; + case LDNS_RDF_TYPE_APL: return "APL"; + case LDNS_RDF_TYPE_B32_EXT: return "B32_EXT"; + case LDNS_RDF_TYPE_B64: return "B64"; + case LDNS_RDF_TYPE_HEX: return "HEX"; + case LDNS_RDF_TYPE_NSEC: return "NSEC"; + case LDNS_RDF_TYPE_NSEC3_SALT: return "NSEC3_SALT"; + case LDNS_RDF_TYPE_TYPE: return "TYPE"; + case LDNS_RDF_TYPE_CLASS: return "CLASS"; + case LDNS_RDF_TYPE_CERT_ALG: return "CER_ALG"; + case LDNS_RDF_TYPE_ALG: return "ALG"; + case LDNS_RDF_TYPE_UNKNOWN: return "UNKNOWN"; + case LDNS_RDF_TYPE_TIME: return "TIME"; + case LDNS_RDF_TYPE_LOC: return "LOC"; + case LDNS_RDF_TYPE_WKS: return "WKS"; + case LDNS_RDF_TYPE_SERVICE: return "SERVICE"; + case LDNS_RDF_TYPE_NSAP: return "NSAP"; + case LDNS_RDF_TYPE_ATMA: return "ATMA"; + case LDNS_RDF_TYPE_IPSECKEY: return "IPSECKEY"; + case LDNS_RDF_TYPE_TSIG: return "TSIG"; + case LDNS_RDF_TYPE_INT16_DATA: return "INT16_DATA"; + case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER: return "NSEC3_NEXT_OWNER"; + } + } + return 0; +} +%} + +#ifdef LDNS_DEBUG +%rename(__ldns_rdf_deep_free) ldns_rdf_deep_free; +%rename(__ldns_rdf_free) ldns_rdf_free; +%inline %{ +void _ldns_rdf_free (ldns_rdf* r) { + printf("******** LDNS_RDF free 0x%lX ************\n", (long unsigned int)r); + ldns_rdf_free(r); +} +%} +#else +%rename(_ldns_rdf_deep_free) ldns_rdf_deep_free; +%rename(_ldns_rdf_free) ldns_rdf_free; +#endif + +%newobject ldns_rdf2str; + + +%feature("docstring") ldns_struct_rdf "Resource record data field. + +The data is a network ordered array of bytes, which size is specified by the (16-bit) size field. To correctly parse it, use the type specified in the (16-bit) type field with a value from ldns_rdf_type." + +%extend ldns_struct_rdf { + + %pythoncode %{ + def __init__(self): + raise Exception("This class can't be created directly. Please use: ldns_rdf_new, ldns_rdf_new_frm_data, ldns_rdf_new_frm_str, ldns_rdf_new_frm_fp, ldns_rdf_new_frm_fp_l") + + __swig_destroy__ = _ldns._ldns_rdf_deep_free + + #LDNS_RDF_CONSTRUCTORS_# + @staticmethod + def new_frm_str(str, rr_type, raiseException = True): + """Creates a new rdf from a string of a given type. + + :param str: string to use + :param rr_type: the type of RDF. See predefined `RDF_TYPE_` constants + :param raiseException: if True, an exception occurs in case a RDF object can't be created + :returns: RDF object or None. If the object can't be created and raiseException is True, an exception occurs. + + **Usage** + >>> rdf = ldns.ldns_rdf.new_frm_str("74.125.43.99",ldns.LDNS_RDF_TYPE_A) + >>> print rdf, rdf.get_type_str() + A 74.125.43.99 + >>> name = ldns.ldns_resolver.new_frm_file().get_name_by_addr(rdf) + >>> if (name): print name + 99.43.125.74.in-addr.arpa. 85277 IN PTR bw-in-f99.google.com. + """ + rr = _ldns.ldns_rdf_new_frm_str(rr_type, str) + if not rr: + if (raiseException): raise Exception("Can't create query packet, error: %d" % status) + return rr + #_LDNS_RDF_CONSTRUCTORS# + + def __str__(self): + """Converts the rdata field to presentation format""" + return _ldns.ldns_rdf2str(self) + + def __cmp__(self,other): + """compares two rdf's on their wire formats. + + (To order dnames according to rfc4034, use ldns_dname_compare) + + :param other: + the second one RDF + :returns: (int) 0 if equal -1 if self comes before other +1 if other comes before self + """ + return _ldns.ldns_rdf_compare(self,other) + + def print_to_file(self,output): + """Prints the data in the rdata field to the given file stream (in presentation format).""" + _ldns.ldns_rdf_print(output,self) + + def get_type_str(self): + """Converts type to string""" + return ldns_rdf_type2str(self) + + def write_to_buffer(self, buffer): + """Copies the rdata data to the buffer in wire format. + + :param buffer: buffer to append the result to + :returns: (ldns_status) ldns_status + """ + return _ldns.ldns_rdf2buffer_wire(buffer, self) + #parameters: ldns_buffer *,const ldns_rdf *, + #retvals: ldns_status + + def write_to_buffer_canonical(self, buffer): + """Copies the rdata data to the buffer in wire format If the rdata is a dname, the letters will be lowercased during the conversion. + + :param buffer: LDNS buffer + :returns: (ldns_status) ldns_status + """ + return _ldns.ldns_rdf2buffer_wire_canonical(buffer, self) + #parameters: ldns_buffer *,const ldns_rdf *, + #retvals: ldns_status + + #LDNS_RDF_METHODS_# + def address_reverse(self): + """reverses an rdf, only actually useful for AAAA and A records. + + The returned rdf has the type LDNS_RDF_TYPE_DNAME! + + :returns: (ldns_rdf \*) the reversed rdf (a newly created rdf) + """ + return _ldns.ldns_rdf_address_reverse(self) + #parameters: ldns_rdf *, + #retvals: ldns_rdf * + + def clone(self): + """clones a rdf structure. + + The data is copied. + + :returns: (ldns_rdf \*) a new rdf structure + """ + return _ldns.ldns_rdf_clone(self) + #parameters: const ldns_rdf *, + #retvals: ldns_rdf * + + def data(self): + """returns the data of the rdf. + + :returns: (uint8_t \*) uint8_t* pointer to the rdf's data + """ + return _ldns.ldns_rdf_data(self) + #parameters: const ldns_rdf *, + #retvals: uint8_t * + + def get_type(self): + """returns the type of the rdf. + + We need to insert _get_ here to prevent conflict the the rdf_type TYPE. + + :returns: (ldns_rdf_type) ldns_rdf_type with the type + """ + return _ldns.ldns_rdf_get_type(self) + #parameters: const ldns_rdf *, + #retvals: ldns_rdf_type + + def set_data(self,data): + """sets the size of the rdf. + + :param data: + """ + _ldns.ldns_rdf_set_data(self,data) + #parameters: ldns_rdf *,void *, + #retvals: + + def set_size(self,size): + """sets the size of the rdf. + + :param size: + the new size + """ + _ldns.ldns_rdf_set_size(self,size) + #parameters: ldns_rdf *,size_t, + #retvals: + + def set_type(self,atype): + """sets the size of the rdf. + + :param atype: + """ + _ldns.ldns_rdf_set_type(self,atype) + #parameters: ldns_rdf *,ldns_rdf_type, + #retvals: + + def size(self): + """returns the size of the rdf. + + :returns: (size_t) uint16_t with the size + """ + return _ldns.ldns_rdf_size(self) + #parameters: const ldns_rdf *, + #retvals: size_t + + @staticmethod + def dname_new_frm_str(str): + """Creates a new dname rdf instance from a string. + + This static method is equivalent to using of default class constructor. + + :parameter str: str string to use + """ + return _ldns.ldns_dname_new_frm_str(str) + + def absolute(self): + """Checks whether the given dname string is absolute (i.e. ends with a '.') + + :returns: (bool) True or False + """ + return self.endswith(".") + + def make_canonical(self): + """Put a dname into canonical fmt - ie. lowercase it + """ + _ldns.ldns_dname2canonical(self) + + def dname_compare(self,other): + """Compares the two dname rdf's according to the algorithm for ordering in RFC4034 Section 6. + + :param other: + the second dname rdf to compare + :returns: (int) -1 if dname comes before other, 1 if dname comes after other, and 0 if they are equal. + """ + return _ldns.ldns_dname_compare(self,other) + + def cat(self,rd2): + """concatenates rd2 after this dname (rd2 is copied, this dname is modified) + + :param rd2: + the rightside + :returns: (ldns_status) LDNS_STATUS_OK on success + """ + return _ldns.ldns_dname_cat(self,rd2) + #parameters: ldns_rdf *,ldns_rdf *, + #retvals: ldns_status + + def cat_clone(self,rd2): + """concatenates two dnames together + + :param rd2: + the rightside + :returns: (ldns_rdf \*) a new rdf with leftside/rightside + """ + return _ldns.ldns_dname_cat_clone(self,rd2) + #parameters: const ldns_rdf *,const ldns_rdf *, + #retvals: ldns_rdf * + + def interval(self,middle,next): + """check if middle lays in the interval defined by prev and next prev <= middle < next. + + This is usefull for nsec checking + + :param middle: + the dname to check + :param next: + the next dname return 0 on error or unknown, -1 when middle is in the interval, +1 when not + :returns: (int) + """ + return _ldns.ldns_dname_interval(self,middle,next) + #parameters: const ldns_rdf *,const ldns_rdf *,const ldns_rdf *, + #retvals: int + + def is_subdomain(self,parent): + """Tests wether the name sub falls under parent (i.e. is a subdomain of parent). + + This function will return false if the given dnames are equal. + + :param parent: + (ldns_rdf) the parent's name + :returns: (bool) true if sub falls under parent, otherwise false + """ + return _ldns.ldns_dname_is_subdomain(self,parent) + #parameters: const ldns_rdf *,const ldns_rdf *, + #retvals: bool + + def label(self,labelpos): + """look inside the rdf and if it is an LDNS_RDF_TYPE_DNAME try and retrieve a specific label. + + The labels are numbered starting from 0 (left most). + + :param labelpos: + return the label with this number + :returns: (ldns_rdf \*) a ldns_rdf* with the label as name or NULL on error + """ + return _ldns.ldns_dname_label(self,labelpos) + #parameters: const ldns_rdf *,uint8_t, + #retvals: ldns_rdf * + + def label_count(self): + """count the number of labels inside a LDNS_RDF_DNAME type rdf. + + :returns: (uint8_t) the number of labels + """ + return _ldns.ldns_dname_label_count(self) + #parameters: const ldns_rdf *, + #retvals: uint8_t + + def left_chop(self): + """chop one label off the left side of a dname. + + so wwww.nlnetlabs.nl, becomes nlnetlabs.nl + + :returns: (ldns_rdf \*) the remaining dname + """ + return _ldns.ldns_dname_left_chop(self) + #parameters: const ldns_rdf *, + #retvals: ldns_rdf * + + def reverse(self): + """Returns a clone of the given dname with the labels reversed. + + :returns: (ldns_rdf \*) clone of the dname with the labels reversed. + """ + return _ldns.ldns_dname_reverse(self) + #parameters: const ldns_rdf *, + #retvals: ldns_rdf * + + #_LDNS_RDF_METHODS# + %} +} diff --git a/contrib/python/ldns_resolver.i b/contrib/python/ldns_resolver.i new file mode 100644 index 000000000000..b9640674b5a0 --- /dev/null +++ b/contrib/python/ldns_resolver.i @@ -0,0 +1,946 @@ +/****************************************************************************** + * ldns_resolver.i: LDNS resolver class + * + * Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz) + * Karel Slany (slany AT fit.vutbr.cz) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the organization nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ + +%typemap(in,numinputs=0,noblock=1) (ldns_resolver **r) +{ + ldns_resolver *$1_res; + $1 = &$1_res; +} + +/* result generation */ +%typemap(argout,noblock=1) (ldns_resolver **r) +{ + $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(SWIG_as_voidptr($1_res), SWIGTYPE_p_ldns_struct_resolver, SWIG_POINTER_OWN | 0 )); +} + +//TODO: pop_nameserver a podobne funkce musi predat objekt do spravy PYTHONU!! +%newobject ldns_resolver_pop_nameserver; +%newobject ldns_resolver_query; +%newobject ldns_axfr_next; + +%delobject ldns_resolver_deep_free; +%delobject ldns_resolver_free; + +%nodefaultctor ldns_struct_resolver; //no default constructor & destructor +%nodefaultdtor ldns_struct_resolver; + +%ignore ldns_struct_resolver::_searchlist; +%ignore ldns_struct_resolver::_nameservers; +%ignore ldns_resolver_set_nameservers; + +%rename(ldns_resolver) ldns_struct_resolver; + +#ifdef LDNS_DEBUG +%rename(__ldns_resolver_deep_free) ldns_resolver_deep_free; +%rename(__ldns_resolver_free) ldns_resolver_free; +%inline %{ +void _ldns_resolver_free (ldns_resolver* r) { + printf("******** LDNS_RESOLVER deep free 0x%lX ************\n", (long unsigned int)r); + ldns_resolver_deep_free(r); +} +%} +#else +%rename(_ldns_resolver_deep_free) ldns_resolver_deep_free; +%rename(_ldns_resolver_free) ldns_resolver_free; +#endif + +%feature("docstring") ldns_struct_resolver "LDNS resolver object. + +The ldns_resolver object keeps a list of nameservers and can perform queries. + +**Usage** + +>>> import ldns +>>> resolver = ldns.ldns_resolver.new_frm_file(\"/etc/resolv.conf\") +>>> pkt = resolver.query(\"www.nic.cz\", ldns.LDNS_RR_TYPE_A,ldns.LDNS_RR_CLASS_IN) +>>> if (pkt) and (pkt.answer()): +>>> print pkt.answer() +www.nic.cz. 1757 IN A 217.31.205.50 + +This simple example instances a resolver in order to resolve www.nic.cz record of A type. +" + +%extend ldns_struct_resolver { + + %pythoncode %{ + def __init__(self): + raise Exception("This class can't be created directly. Please use: new_frm_file(filename), new_frm_fp(file) or new_frm_fp_l(file,line)") + + __swig_destroy__ = _ldns._ldns_resolver_free + + #LDNS_RESOLVER_CONSTRUCTORS_# + @staticmethod + def new_frm_file(filename = "/etc/resolv.conf", raiseException=True): + """Creates a resolver object from given filename + + :param filename: name of file which contains informations (usually /etc/resolv.conf) + :param raiseException: if True, an exception occurs in case a resolver object can't be created + :returns: resolver object or None. If the object can't be created and raiseException is True, an exception occurs. + """ + status, resolver = _ldns.ldns_resolver_new_frm_file(filename) + if status != LDNS_STATUS_OK: + if (raiseException): raise Exception("Can't create resolver, error: %d" % status) + return None + return resolver + + @staticmethod + def new_frm_fp(file, raiseException=True): + """Creates a resolver object from file + + :param file: a file object + :param raiseException: if True, an exception occurs in case a resolver object can't be created + :returns: resolver object or None. If the object can't be created and raiseException is True, an exception occurs. + """ + status, resolver = _ldns.ldns_resolver_new_frm_fp(file) + if status != LDNS_STATUS_OK: + if (raiseException): raise Exception("Can't create resolver, error: %d" % status) + return None + return resolver + + @staticmethod + def new_frm_fp_l(file, raiseException=True): + """Creates a resolver object from file + + :param file: a file object + :param raiseException: if True, an exception occurs in case a resolver instance can't be created + :returns: + * resolver - resolver instance or None. If an instance can't be created and raiseException is True, an exception occurs. + + * line - the line number (for debugging) + """ + status, resolver, line = _ldns.ldns_resolver_new_frm_fp_l(file) + if status != LDNS_STATUS_OK: + if (raiseException): raise Exception("Can't create resolver, error: %d" % status) + return None + return resolver, line + + #_LDNS_RESOLVER_CONSTRUCTORS# + + # High level functions + def get_addr_by_name(self, name, aclass = _ldns.LDNS_RR_CLASS_IN, flags = _ldns.LDNS_RD): + """Ask the resolver about name and return all address records + + :param name: (ldns_rdf) the name to look for + :param aclass: the class to use + :param flags: give some optional flags to the query + + :returns: RR List object or None + + **Usage** + >>> addr = resolver.get_addr_by_name("www.google.com", ldns.LDNS_RR_CLASS_IN, ldns.LDNS_RD) + >>> if (not addr): raise Exception("Can't retrieve server address") + >>> for rr in addr.rrs(): + >>> print rr + www.l.google.com. 300 IN A 74.125.43.99 + www.l.google.com. 300 IN A 74.125.43.103 + www.l.google.com. 300 IN A 74.125.43.104 + www.l.google.com. 300 IN A 74.125.43.147 + + """ + rdf = name + if isinstance(name, str): + rdf = _ldns.ldns_dname_new_frm_str(name) + return _ldns.ldns_get_rr_list_addr_by_name(self, rdf, aclass, flags) + + def get_name_by_addr(self, addr, aclass = _ldns.LDNS_RR_CLASS_IN, flags = _ldns.LDNS_RD): + """Ask the resolver about the address and return the name + + :param name: (ldns_rdf of A or AAAA type) the addr to look for. If a string is given, A or AAAA type is identified automatically + :param aclass: the class to use + :param flags: give some optional flags to the query + + :returns: RR List object or None + + **Usage** + >>> addr = resolver.get_name_by_addr("74.125.43.99", ldns.LDNS_RR_CLASS_IN, ldns.LDNS_RD) + >>> if (not addr): raise Exception("Can't retrieve server address") + >>> for rr in addr.rrs(): + >>> print rr + 99.43.125.74.in-addr.arpa. 85641 IN PTR bw-in-f99.google.com. + + """ + rdf = addr + if isinstance(addr, str): + if (addr.find("::") >= 0): #IPv6 + rdf = _ldns.ldns_rdf_new_frm_str(_ldns.LDNS_RDF_TYPE_AAAA, addr) + else: + rdf = _ldns.ldns_rdf_new_frm_str(_ldns.LDNS_RDF_TYPE_A, addr) + return _ldns.ldns_get_rr_list_name_by_addr(self, rdf, aclass, flags) + + def print_to_file(self,output): + """Print a resolver (in sofar that is possible) state to output.""" + _ldns.ldns_resolver_print(output,self) + + def axfr_start(self, domain, aclass): + """Prepares the resolver for an axfr query. The query is sent and the answers can be read with axfr_next + + **Usage** + :: + + status = resolver.axfr_start("nic.cz", ldns.LDNS_RR_CLASS_IN) + if (status != ldns.LDNS_STATUS_OK): raise Exception("Can't start AXFR, error: %s" % ldns.ldns_get_errorstr_by_id(status)) + #Print the results + while True: + rr = resolver.axfr_next() + if not rr: + break + + print rr + + """ + rdf = domain + if isinstance(domain, str): + rdf = _ldns.ldns_dname_new_frm_str(domain) + return _ldns.ldns_axfr_start(self, rdf, aclass) + #parameters: ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class c + #retvals: int + + def axfr_complete(self): + """returns true if the axfr transfer has completed (i.e. 2 SOA RRs and no errors were encountered)""" + return _ldns.ldns_axfr_complete(self) + #parameters: const ldns_resolver *, + #retvals: bool + + def axfr_last_pkt(self): + """returns a pointer to the last ldns_pkt that was sent by the server in the AXFR transfer uasable for instance to get the error code on failure""" + return _ldns.ldns_axfr_last_pkt(self) + #parameters: const ldns_resolver *, + #retvals: ldns_pkt * + + def axfr_next(self): + """get the next stream of RRs in a AXFR""" + return _ldns.ldns_axfr_next(self) + #parameters: ldns_resolver *, + #retvals: ldns_rr * + + #LDNS_RESOLVER_METHODS_# + def debug(self): + """Get the debug status of the resolver. + + :returns: (bool) true if so, otherwise false + """ + return _ldns.ldns_resolver_debug(self) + #parameters: const ldns_resolver *, + #retvals: bool + + def dec_nameserver_count(self): + """Decrement the resolver's nameserver count. + """ + _ldns.ldns_resolver_dec_nameserver_count(self) + #parameters: ldns_resolver *, + #retvals: + + def defnames(self): + return _ldns.ldns_resolver_defnames(self) + #parameters: const ldns_resolver *, + #retvals: bool + + def dnsrch(self): + return _ldns.ldns_resolver_dnsrch(self) + #parameters: const ldns_resolver *, + #retvals: bool + + def dnssec(self): + """Does the resolver do DNSSEC. + + :returns: (bool) true: yes, false: no + """ + return _ldns.ldns_resolver_dnssec(self) + #parameters: const ldns_resolver *, + #retvals: bool + + def dnssec_anchors(self): + """Get the resolver's DNSSEC anchors. + + :returns: (ldns_rr_list \*) an rr_list containg trusted DNSSEC anchors + """ + return _ldns.ldns_resolver_dnssec_anchors(self) + #parameters: const ldns_resolver *, + #retvals: ldns_rr_list * + + def dnssec_cd(self): + """Does the resolver set the CD bit. + + :returns: (bool) true: yes, false: no + """ + return _ldns.ldns_resolver_dnssec_cd(self) + #parameters: const ldns_resolver *, + #retvals: bool + + def domain(self): + """What is the default dname to add to relative queries. + + :returns: (ldns_rdf \*) the dname which is added + """ + return _ldns.ldns_resolver_domain(self) + #parameters: const ldns_resolver *, + #retvals: ldns_rdf * + + def edns_udp_size(self): + """Get the resolver's udp size. + + :returns: (uint16_t) the udp mesg size + """ + return _ldns.ldns_resolver_edns_udp_size(self) + #parameters: const ldns_resolver *, + #retvals: uint16_t + + def fail(self): + """Does the resolver only try the first nameserver. + + :returns: (bool) true: yes, fail, false: no, try the others + """ + return _ldns.ldns_resolver_fail(self) + #parameters: const ldns_resolver *, + #retvals: bool + + def fallback(self): + """Get the truncation fallback status. + + :returns: (bool) whether the truncation fallback mechanism is used + """ + return _ldns.ldns_resolver_fallback(self) + #parameters: const ldns_resolver *, + #retvals: bool + + def igntc(self): + """Does the resolver ignore the TC bit (truncated). + + :returns: (bool) true: yes, false: no + """ + return _ldns.ldns_resolver_igntc(self) + #parameters: const ldns_resolver *, + #retvals: bool + + def incr_nameserver_count(self): + """Incremental the resolver's nameserver count. + """ + _ldns.ldns_resolver_incr_nameserver_count(self) + #parameters: ldns_resolver *, + #retvals: + + def ip6(self): + """Does the resolver use ip6 or ip4. + + :returns: (uint8_t) 0: both, 1: ip4, 2:ip6 + """ + return _ldns.ldns_resolver_ip6(self) + #parameters: const ldns_resolver *, + #retvals: uint8_t + + def nameserver_count(self): + """How many nameserver are configured in the resolver. + + :returns: (size_t) number of nameservers + """ + return _ldns.ldns_resolver_nameserver_count(self) + #parameters: const ldns_resolver *, + #retvals: size_t + + def nameserver_rtt(self,pos): + """Return the used round trip time for a specific nameserver. + + :param pos: + the index to the nameserver + :returns: (size_t) the rrt, 0: infinite, >0: undefined (as of * yet) + """ + return _ldns.ldns_resolver_nameserver_rtt(self,pos) + #parameters: const ldns_resolver *,size_t, + #retvals: size_t + + def nameservers(self): + """Return the configured nameserver ip address. + + :returns: (ldns_rdf \*\*) a ldns_rdf pointer to a list of the addresses + """ + return _ldns.ldns_resolver_nameservers(self) + #parameters: const ldns_resolver *, + #retvals: ldns_rdf ** + + def nameservers_randomize(self): + """randomize the nameserver list in the resolver + """ + _ldns.ldns_resolver_nameservers_randomize(self) + #parameters: ldns_resolver *, + #retvals: + + def pop_nameserver(self): + """pop the last nameserver from the resolver. + + :returns: (ldns_rdf \*) the popped address or NULL if empty + """ + return _ldns.ldns_resolver_pop_nameserver(self) + #parameters: ldns_resolver *, + #retvals: ldns_rdf * + + def port(self): + """Get the port the resolver should use. + + :returns: (uint16_t) the port number + """ + return _ldns.ldns_resolver_port(self) + #parameters: const ldns_resolver *, + #retvals: uint16_t + + def prepare_query_pkt(self,name,t,c,f): + """Form a query packet from a resolver and name/type/class combo. + + :param name: + :param t: + query for this type (may be 0, defaults to A) + :param c: + query for this class (may be 0, default to IN) + :param f: + the query flags + :returns: * (ldns_status) ldns_pkt* a packet with the reply from the nameserver + * (ldns_pkt \*\*) query packet class + """ + return _ldns.ldns_resolver_prepare_query_pkt(self,name,t,c,f) + #parameters: ldns_resolver *,const ldns_rdf *,ldns_rr_type,ldns_rr_class,uint16_t, + #retvals: ldns_status,ldns_pkt ** + + def push_dnssec_anchor(self,rr): + """Push a new trust anchor to the resolver. + + It must be a DS or DNSKEY rr + + :param rr: + the RR to add as a trust anchor. + :returns: (ldns_status) a status + """ + return _ldns.ldns_resolver_push_dnssec_anchor(self,rr) + #parameters: ldns_resolver *,ldns_rr *, + #retvals: ldns_status + + def push_nameserver(self,n): + """push a new nameserver to the resolver. + + It must be an IP address v4 or v6. + + :param n: + the ip address + :returns: (ldns_status) ldns_status a status + """ + return _ldns.ldns_resolver_push_nameserver(self,n) + #parameters: ldns_resolver *,ldns_rdf *, + #retvals: ldns_status + + def push_nameserver_rr(self,rr): + """push a new nameserver to the resolver. + + It must be an A or AAAA RR record type + + :param rr: + the resource record + :returns: (ldns_status) ldns_status a status + """ + return _ldns.ldns_resolver_push_nameserver_rr(self,rr) + #parameters: ldns_resolver *,ldns_rr *, + #retvals: ldns_status + + def push_nameserver_rr_list(self,rrlist): + """push a new nameserver rr_list to the resolver. + + :param rrlist: + the rr_list to push + :returns: (ldns_status) ldns_status a status + """ + return _ldns.ldns_resolver_push_nameserver_rr_list(self,rrlist) + #parameters: ldns_resolver *,ldns_rr_list *, + #retvals: ldns_status + + def push_searchlist(self,rd): + """Push a new rd to the resolver's searchlist. + + :param rd: + to push + """ + _ldns.ldns_resolver_push_searchlist(self,rd) + #parameters: ldns_resolver *,ldns_rdf *, + #retvals: + + def query(self,name,atype=_ldns.LDNS_RR_TYPE_A,aclass=_ldns.LDNS_RR_CLASS_IN,flags=_ldns.LDNS_RD): + """Send a query to a nameserver. + + :param name: (ldns_rdf) the name to look for + :param atype: the RR type to use + :param aclass: the RR class to use + :param flags: give some optional flags to the query + :returns: (ldns_pkt) a packet with the reply from the nameserver if _defnames is true the default domain will be added + """ + return _ldns.ldns_resolver_query(self,name,atype,aclass,flags) + #parameters: const ldns_resolver *,const ldns_rdf *,ldns_rr_type,ldns_rr_class,uint16_t, + #retvals: ldns_pkt * + + def random(self): + """Does the resolver randomize the nameserver before usage. + + :returns: (bool) true: yes, false: no + """ + return _ldns.ldns_resolver_random(self) + #parameters: const ldns_resolver *, + #retvals: bool + + def recursive(self): + """Is the resolver set to recurse. + + :returns: (bool) true if so, otherwise false + """ + return _ldns.ldns_resolver_recursive(self) + #parameters: const ldns_resolver *, + #retvals: bool + + def retrans(self): + """Get the retransmit interval. + + :returns: (uint8_t) the retransmit interval + """ + return _ldns.ldns_resolver_retrans(self) + #parameters: const ldns_resolver *, + #retvals: uint8_t + + def retry(self): + """Get the number of retries. + + :returns: (uint8_t) the number of retries + """ + return _ldns.ldns_resolver_retry(self) + #parameters: const ldns_resolver *, + #retvals: uint8_t + + def rtt(self): + """Return the used round trip times for the nameservers. + + :returns: (size_t \*) a size_t* pointer to the list. yet) + """ + return _ldns.ldns_resolver_rtt(self) + #parameters: const ldns_resolver *, + #retvals: size_t * + + def search(self,rdf,t,c,flags): + """Send the query for using the resolver and take the search list into account The search algorithm is as follows: If the name is absolute, try it as-is, otherwise apply the search list. + + :param rdf: + :param t: + query for this type (may be 0, defaults to A) + :param c: + query for this class (may be 0, default to IN) + :param flags: + the query flags + :returns: (ldns_pkt \*) ldns_pkt* a packet with the reply from the nameserver + """ + return _ldns.ldns_resolver_search(self,rdf,t,c,flags) + #parameters: const ldns_resolver *,const ldns_rdf *,ldns_rr_type,ldns_rr_class,uint16_t, + #retvals: ldns_pkt * + + def searchlist(self): + """What is the searchlist as used by the resolver. + + :returns: (ldns_rdf \*\*) a ldns_rdf pointer to a list of the addresses + """ + return _ldns.ldns_resolver_searchlist(self) + #parameters: const ldns_resolver *, + #retvals: ldns_rdf \*\* + + def searchlist_count(self): + """Return the resolver's searchlist count. + + :returns: (size_t) the searchlist count + """ + return _ldns.ldns_resolver_searchlist_count(self) + #parameters: const ldns_resolver *, + #retvals: size_t + + def send(self,name,t,c,flags): + """Send the query for name as-is. + + :param name: + :param t: + query for this type (may be 0, defaults to A) + :param c: + query for this class (may be 0, default to IN) + :param flags: + the query flags + :returns: * (ldns_status) ldns_pkt* a packet with the reply from the nameserver + * (ldns_pkt \*\*) + """ + return _ldns.ldns_resolver_send(self,name,t,c,flags) + #parameters: ldns_resolver *,const ldns_rdf *,ldns_rr_type,ldns_rr_class,uint16_t, + #retvals: ldns_status,ldns_pkt ** + + def send_pkt(self,query_pkt): + """Send the given packet to a nameserver. + + :param query_pkt: + :returns: * (ldns_status) + * (ldns_pkt \*\*) + """ + return _ldns.ldns_resolver_send_pkt(self,query_pkt) + #parameters: ldns_resolver *,ldns_pkt *, + #retvals: ldns_status,ldns_pkt ** + + def set_debug(self,b): + """Set the resolver debugging. + + :param b: + true: debug on: false debug off + """ + _ldns.ldns_resolver_set_debug(self,b) + #parameters: ldns_resolver *,bool, + #retvals: + + def set_defnames(self,b): + """Whether the resolver uses the name set with _set_domain. + + :param b: + true: use the defaults, false: don't use them + """ + _ldns.ldns_resolver_set_defnames(self,b) + #parameters: ldns_resolver *,bool, + #retvals: + + def set_dnsrch(self,b): + """Whether the resolver uses the searchlist. + + :param b: + true: use the list, false: don't use the list + """ + _ldns.ldns_resolver_set_dnsrch(self,b) + #parameters: ldns_resolver *,bool, + #retvals: + + def set_dnssec(self,b): + """Whether the resolver uses DNSSEC. + + :param b: + true: use DNSSEC, false: don't use DNSSEC + """ + _ldns.ldns_resolver_set_dnssec(self,b) + #parameters: ldns_resolver *,bool, + #retvals: + + def set_dnssec_anchors(self,l): + """Set the resolver's DNSSEC anchor list directly. + + RRs should be of type DS or DNSKEY. + + :param l: + the list of RRs to use as trust anchors + """ + _ldns.ldns_resolver_set_dnssec_anchors(self,l) + #parameters: ldns_resolver *,ldns_rr_list *, + #retvals: + + def set_dnssec_cd(self,b): + """Whether the resolver uses the checking disable bit. + + :param b: + true: enable , false: don't use TCP + """ + _ldns.ldns_resolver_set_dnssec_cd(self,b) + #parameters: ldns_resolver *,bool, + #retvals: + + def set_domain(self,rd): + """Set the resolver's default domain. + + This gets appended when no absolute name is given + + :param rd: + the name to append + """ + _ldns.ldns_resolver_set_domain(self,rd) + #parameters: ldns_resolver *,ldns_rdf *, + #retvals: + + def set_edns_udp_size(self,s): + """Set maximum udp size. + + :param s: + the udp max size + """ + _ldns.ldns_resolver_set_edns_udp_size(self,s) + #parameters: ldns_resolver *,uint16_t, + #retvals: + + def set_fail(self,b): + """Whether or not to fail after one failed query. + + :param b: + true: yes fail, false: continue with next nameserver + """ + _ldns.ldns_resolver_set_fail(self,b) + #parameters: ldns_resolver *,bool, + #retvals: + + def set_fallback(self,fallback): + """Set whether the resolvers truncation fallback mechanism is used when ldns_resolver_query() is called. + + :param fallback: + whether to use the fallback mechanism + """ + _ldns.ldns_resolver_set_fallback(self,fallback) + #parameters: ldns_resolver *,bool, + #retvals: + + def set_igntc(self,b): + """Whether or not to ignore the TC bit. + + :param b: + true: yes ignore, false: don't ignore + """ + _ldns.ldns_resolver_set_igntc(self,b) + #parameters: ldns_resolver *,bool, + #retvals: + + def set_ip6(self,i): + """Whether the resolver uses ip6. + + :param i: + 0: no pref, 1: ip4, 2: ip6 + """ + _ldns.ldns_resolver_set_ip6(self,i) + #parameters: ldns_resolver *,uint8_t, + #retvals: + + def set_nameserver_count(self,c): + """Set the resolver's nameserver count directly. + + :param c: + the nameserver count + """ + _ldns.ldns_resolver_set_nameserver_count(self,c) + #parameters: ldns_resolver *,size_t, + #retvals: + + def set_nameserver_rtt(self,pos,value): + """Set round trip time for a specific nameserver. + + Note this currently differentiates between: unreachable and reachable. + + :param pos: + the nameserver position + :param value: + the rtt + """ + _ldns.ldns_resolver_set_nameserver_rtt(self,pos,value) + #parameters: ldns_resolver *,size_t,size_t, + #retvals: + + def set_nameservers(self,rd): + """Set the resolver's nameserver count directly by using an rdf list. + + :param rd: + the resolver addresses + """ + _ldns.ldns_resolver_set_nameservers(self,rd) + #parameters: ldns_resolver *,ldns_rdf **, + #retvals: + + def set_port(self,p): + """Set the port the resolver should use. + + :param p: + the port number + """ + _ldns.ldns_resolver_set_port(self,p) + #parameters: ldns_resolver *,uint16_t, + #retvals: + + def set_random(self,b): + """Should the nameserver list be randomized before each use. + + :param b: + true: randomize, false: don't + """ + _ldns.ldns_resolver_set_random(self,b) + #parameters: ldns_resolver *,bool, + #retvals: + + def set_recursive(self,b): + """Set the resolver recursion. + + :param b: + true: set to recurse, false: unset + """ + _ldns.ldns_resolver_set_recursive(self,b) + #parameters: ldns_resolver *,bool, + #retvals: + + def set_retrans(self,re): + """Set the resolver retrans timeout (in seconds). + + :param re: + the retransmission interval in seconds + """ + _ldns.ldns_resolver_set_retrans(self,re) + #parameters: ldns_resolver *,uint8_t, + #retvals: + + def set_retry(self,re): + """Set the resolver retry interval (in seconds). + + :param re: + the retry interval + """ + _ldns.ldns_resolver_set_retry(self,re) + #parameters: ldns_resolver *,uint8_t, + #retvals: + + def set_rtt(self,rtt): + """Set round trip time for all nameservers. + + Note this currently differentiates between: unreachable and reachable. + + :param rtt: + a list with the times + """ + _ldns.ldns_resolver_set_rtt(self,rtt) + #parameters: ldns_resolver *,size_t *, + #retvals: + + def set_searchlist_count(self,c): + _ldns.ldns_resolver_set_searchlist_count(self,c) + #parameters: ldns_resolver *,size_t, + #retvals: + + def set_timeout(self,timeout): + """Set the resolver's socket time out when talking to remote hosts. + + :param timeout: + the timeout to use + """ + _ldns.ldns_resolver_set_timeout(self,timeout) + #parameters: ldns_resolver *,struct timeval, + #retvals: + + def set_tsig_algorithm(self,tsig_algorithm): + """Set the tsig algorithm. + + :param tsig_algorithm: + the tsig algorithm + """ + _ldns.ldns_resolver_set_tsig_algorithm(self,tsig_algorithm) + #parameters: ldns_resolver *,char *, + #retvals: + + def set_tsig_keydata(self,tsig_keydata): + """Set the tsig key data. + + :param tsig_keydata: + the key data + """ + _ldns.ldns_resolver_set_tsig_keydata(self,tsig_keydata) + #parameters: ldns_resolver *,char *, + #retvals: + + def set_tsig_keyname(self,tsig_keyname): + """Set the tsig key name. + + :param tsig_keyname: + the tsig key name + """ + _ldns.ldns_resolver_set_tsig_keyname(self,tsig_keyname) + #parameters: ldns_resolver *,char *, + #retvals: + + def set_usevc(self,b): + """Whether the resolver uses a virtual circuit (TCP). + + :param b: + true: use TCP, false: don't use TCP + """ + _ldns.ldns_resolver_set_usevc(self,b) + #parameters: ldns_resolver *,bool, + #retvals: + + def timeout(self): + """What is the timeout on socket connections. + + :returns: (struct timeval) the timeout as struct timeval + """ + return _ldns.ldns_resolver_timeout(self) + #parameters: const ldns_resolver *, + #retvals: struct timeval + + def trusted_key(self,keys,trusted_keys): + """Returns true if at least one of the provided keys is a trust anchor. + + :param keys: + the keyset to check + :param trusted_keys: + the subset of trusted keys in the 'keys' rrset + :returns: (bool) true if at least one of the provided keys is a configured trust anchor + """ + return _ldns.ldns_resolver_trusted_key(self,keys,trusted_keys) + #parameters: const ldns_resolver *,ldns_rr_list *,ldns_rr_list *, + #retvals: bool + + def tsig_algorithm(self): + """Return the tsig algorithm as used by the nameserver. + + :returns: (char \*) the algorithm used. + """ + return _ldns.ldns_resolver_tsig_algorithm(self) + #parameters: const ldns_resolver *, + #retvals: char * + + def tsig_keydata(self): + """Return the tsig keydata as used by the nameserver. + + :returns: (char \*) the keydata used. + """ + return _ldns.ldns_resolver_tsig_keydata(self) + #parameters: const ldns_resolver *, + #retvals: char * + + def tsig_keyname(self): + """Return the tsig keyname as used by the nameserver. + + :returns: (char \*) the name used. + """ + return _ldns.ldns_resolver_tsig_keyname(self) + #parameters: const ldns_resolver *, + #retvals: char * + + def usevc(self): + """Does the resolver use tcp or udp. + + :returns: (bool) true: tcp, false: udp + """ + return _ldns.ldns_resolver_usevc(self) + #parameters: const ldns_resolver *, + #retvals: bool + + #_LDNS_RESOLVER_METHODS# + %} +} diff --git a/contrib/python/ldns_rr.i b/contrib/python/ldns_rr.i new file mode 100644 index 000000000000..1a9f3f1c21bb --- /dev/null +++ b/contrib/python/ldns_rr.i @@ -0,0 +1,1584 @@ +/****************************************************************************** + * ldns_rr.i: LDNS resource records (RR), RR list + * + * Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz) + * Karel Slany (slany AT fit.vutbr.cz) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the organization nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ + +%typemap(in,numinputs=0,noblock=1) (ldns_rr **) +{ + ldns_rr *$1_rr; + $1 = &$1_rr; +} + +/* result generation */ +%typemap(argout,noblock=1) (ldns_rr **) +{ + $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(SWIG_as_voidptr($1_rr), SWIGTYPE_p_ldns_struct_rr, SWIG_POINTER_OWN | 0 )); +} + +%nodefaultctor ldns_struct_rr; //no default constructor & destructor +%nodefaultdtor ldns_struct_rr; + +%ignore ldns_struct_rr::_rdata_fields; + +%newobject ldns_rr_clone; +%newobject ldns_rr_new; +%newobject ldns_rr_pop_rdf; +%delobject ldns_rr_free; + +%rename(ldns_rr) ldns_struct_rr; + +#ifdef LDNS_DEBUG +%rename(__ldns_rr_free) ldns_rr_free; +%inline %{ +void _ldns_rr_free (ldns_rr* r) { + printf("******** LDNS_RR free 0x%lX ************\n", (long unsigned int)r); + ldns_rr_free(r); +} +%} +#else +%rename(_ldns_rr_free) ldns_rr_free; +#endif + +%newobject ldns_rr2str; +%newobject ldns_rr_type2str; +%newobject ldns_rr_class2str; +%newobject ldns_read_anchor_file; + + +// clone rdf data on pull + +%newobject _ldns_rr_rdf; +%rename(__ldns_rr_rdf) ldns_rr_rdf; +%inline %{ +ldns_rdf* _ldns_rr_rdf(ldns_rr* rr, size_t i) { + return ldns_rdf_clone(ldns_rr_rdf(rr, i)); +} +%} + +%newobject _ldns_rr_rrsig_algorithm; +%rename(__ldns_rr_rrsig_algorithm) ldns_rr_rrsig_algorithm; +%inline %{ +ldns_rdf* _ldns_rr_rrsig_algorithm(ldns_rr* rr) { + return ldns_rdf_clone(ldns_rr_rrsig_algorithm(rr)); +} +%} + +%newobject _ldns_rr_dnskey_algorithm; +%rename(__ldns_rr_dnskey_algorithm) ldns_rr_dnskey_algorithm; +%inline %{ +ldns_rdf* _ldns_rr_dnskey_algorithm(ldns_rr* rr) { + return ldns_rdf_clone(ldns_rr_dnskey_algorithm(rr)); +} +%} + +%newobject _ldns_rr_dnskey_flags; +%rename(__ldns_rr_dnskey_flags) ldns_rr_dnskey_flags; +%inline %{ +ldns_rdf* _ldns_rr_dnskey_flags(ldns_rr* rr) { + return ldns_rdf_clone(ldns_rr_dnskey_flags(rr)); +} +%} + +%newobject _ldns_rr_dnskey_key; +%rename(__ldns_rr_dnskey_key) ldns_rr_dnskey_key; +%inline %{ +ldns_rdf* _ldns_rr_dnskey_key(ldns_rr* rr) { + return ldns_rdf_clone(ldns_rr_dnskey_key(rr)); +} +%} + +%newobject _ldns_rr_dnskey_protocol; +%rename(__ldns_rr_dnskey_protocol) ldns_rr_dnskey_protocol; +%inline %{ +ldns_rdf* _ldns_rr_dnskey_protocol(ldns_rr* rr) { + return ldns_rdf_clone(ldns_rr_dnskey_protocol(rr)); +} +%} + + +%newobject _ldns_rr_owner; +%rename(__ldns_rr_owner) ldns_rr_owner; +%inline %{ +ldns_rdf* _ldns_rr_owner(ldns_rr* rr) { + return ldns_rdf_clone(ldns_rr_owner(rr)); +} +%} + + +%newobject _ldns_rr_a_address; +%rename(__ldns_rr_a_address) ldns_rr_a_address; +%inline %{ +ldns_rdf* _ldns_rr_a_address(ldns_rr* rr) { + return ldns_rdf_clone(ldns_rr_a_address(rr)); +} +%} + + +%newobject _ldns_rr_mx_exchange; +%rename(__ldns_rr_mx_exchange) ldns_rr_mx_exchange; +%inline %{ +ldns_rdf* _ldns_rr_mx_exchange(ldns_rr* rr) { + return ldns_rdf_clone(ldns_rr_mx_exchange(rr)); +} +%} + + +%newobject _ldns_rr_mx_preference; +%rename(__ldns_rr_mx_preference) ldns_rr_mx_preference; +%inline %{ +ldns_rdf* _ldns_rr_mx_preference(ldns_rr* rr) { + return ldns_rdf_clone(ldns_rr_mx_preference(rr)); +} +%} + + +%newobject _ldns_rr_ns_nsdname; +%rename(__ldns_rr_ns_nsdname) ldns_rr_ns_nsdname; +%inline %{ +ldns_rdf* _ldns_rr_ns_nsdname(ldns_rr* rr) { + return ldns_rdf_clone(ldns_rr_ns_nsdname(rr)); +} +%} + + +%newobject _ldns_rr_rrsig_expiration; +%rename(__ldns_rr_rrsig_expiration) ldns_rr_rrsig_expiration; +%inline %{ +ldns_rdf* _ldns_rr_rrsig_expiration(ldns_rr* rr) { + return ldns_rdf_clone(ldns_rr_rrsig_expiration(rr)); +} +%} + + +%newobject _ldns_rr_rrsig_inception; +%rename(__ldns_rr_rrsig_inception) ldns_rr_rrsig_inception; +%inline %{ +ldns_rdf* _ldns_rr_rrsig_inception(ldns_rr* rr) { + return ldns_rdf_clone(ldns_rr_rrsig_inception(rr)); +} +%} + + +%newobject _ldns_rr_rrsig_keytag; +%rename(__ldns_rr_rrsig_keytag) ldns_rr_rrsig_keytag; +%inline %{ +ldns_rdf* _ldns_rr_rrsig_keytag(ldns_rr* rr) { + return ldns_rdf_clone(ldns_rr_rrsig_keytag(rr)); +} +%} + + +%newobject _ldns_rr_rrsig_labels; +%rename(__ldns_rr_rrsig_labels) ldns_rr_rrsig_labels; +%inline %{ +ldns_rdf* _ldns_rr_rrsig_labels(ldns_rr* rr) { + return ldns_rdf_clone(ldns_rr_rrsig_labels(rr)); +} +%} + + +%newobject _ldns_rr_rrsig_origttl; +%rename(__ldns_rr_rrsig_origttl) ldns_rr_rrsig_origttl; +%inline %{ +ldns_rdf* _ldns_rr_rrsig_origttl(ldns_rr* rr) { + return ldns_rdf_clone(ldns_rr_rrsig_origttl(rr)); +} +%} + + +%newobject _ldns_rr_rrsig_sig; +%rename(__ldns_rr_rrsig_sig) ldns_rr_rrsig_sig; +%inline %{ +ldns_rdf* _ldns_rr_rrsig_sig(ldns_rr* rr) { + return ldns_rdf_clone(ldns_rr_rrsig_sig(rr)); +} +%} + + +%newobject _ldns_rr_rrsig_signame; +%rename(__ldns_rr_rrsig_signame) ldns_rr_rrsig_signame; +%inline %{ +ldns_rdf* _ldns_rr_rrsig_signame(ldns_rr* rr) { + return ldns_rdf_clone(ldns_rr_rrsig_signame(rr)); +} +%} + + +%newobject _ldns_rr_rrsig_typecovered; +%rename(__ldns_rr_rrsig_typecovered) ldns_rr_rrsig_typecovered; +%inline %{ +ldns_rdf* _ldns_rr_rrsig_typecovered(ldns_rr* rr) { + return ldns_rdf_clone(ldns_rr_rrsig_typecovered(rr)); +} +%} + +// end of pull cloning + +// clone rdf data on push + +%rename(__ldns_rr_a_set_address) ldns_rr_a_set_address; +%inline %{ +bool _ldns_rr_a_set_address(ldns_rr* rr, ldns_rdf* rdf) { + return ldns_rr_a_set_address(rr, ldns_rdf_clone(rdf)); +} +%} + +%rename(__ldns_rr_dnskey_set_algorithm) ldns_rr_dnskey_set_algorithm; +%inline %{ +bool _ldns_rr_dnskey_set_algorithm(ldns_rr* rr, ldns_rdf* rdf) { + return ldns_rr_dnskey_set_algorithm(rr, ldns_rdf_clone(rdf)); +} +%} + +%rename(__ldns_rr_dnskey_set_flags) ldns_rr_dnskey_set_flags; +%inline %{ +bool _ldns_rr_dnskey_set_flags(ldns_rr* rr, ldns_rdf* rdf) { + return ldns_rr_dnskey_set_flags(rr, ldns_rdf_clone(rdf)); +} +%} + +%rename(__ldns_rr_dnskey_set_key) ldns_rr_dnskey_set_key; +%inline %{ +bool _ldns_rr_dnskey_set_key(ldns_rr* rr, ldns_rdf* rdf) { + return ldns_rr_dnskey_set_key(rr, ldns_rdf_clone(rdf)); +} +%} + +%rename(__ldns_rr_dnskey_set_protocol) ldns_rr_dnskey_set_protocol; +%inline %{ +bool _ldns_rr_dnskey_set_protocol(ldns_rr* rr, ldns_rdf* rdf) { + return ldns_rr_dnskey_set_protocol(rr, ldns_rdf_clone(rdf)); +} +%} + +%rename(__ldns_rr_push_rdf) ldns_rr_push_rdf; +%inline %{ +bool _ldns_rr_push_rdf(ldns_rr* rr, ldns_rdf* rdf) { + return ldns_rr_push_rdf(rr, ldns_rdf_clone(rdf)); +} +%} + +%rename(__ldns_rr_rrsig_set_algorithm) ldns_rr_rrsig_set_algorithm; +%inline %{ +bool _ldns_rr_rrsig_set_algorithm(ldns_rr* rr, ldns_rdf* rdf) { + return ldns_rr_rrsig_set_algorithm(rr, ldns_rdf_clone(rdf)); +} +%} + +%rename(__ldns_rr_rrsig_set_expiration) ldns_rr_rrsig_set_expiration; +%inline %{ +bool _ldns_rr_rrsig_set_expiration(ldns_rr* rr, ldns_rdf* rdf) { + return ldns_rr_rrsig_set_expiration(rr, ldns_rdf_clone(rdf)); +} +%} + +%rename(__ldns_rr_rrsig_set_inception) ldns_rr_rrsig_set_inception; +%inline %{ +bool _ldns_rr_rrsig_set_inception(ldns_rr* rr, ldns_rdf* rdf) { + return ldns_rr_rrsig_set_inception(rr, ldns_rdf_clone(rdf)); +} +%} + +%rename(__ldns_rr_rrsig_set_keytag) ldns_rr_rrsig_set_keytag; +%inline %{ +bool _ldns_rr_rrsig_set_keytag(ldns_rr* rr, ldns_rdf* rdf) { + return ldns_rr_rrsig_set_keytag(rr, ldns_rdf_clone(rdf)); +} +%} + +%rename(__ldns_rr_rrsig_set_labels) ldns_rr_rrsig_set_labels; +%inline %{ +bool _ldns_rr_rrsig_set_labels(ldns_rr* rr, ldns_rdf* rdf) { + return ldns_rr_rrsig_set_labels(rr, ldns_rdf_clone(rdf)); +} +%} + +%rename(__ldns_rr_rrsig_set_origttl) ldns_rr_rrsig_set_origttl; +%inline %{ +bool _ldns_rr_rrsig_set_origttl(ldns_rr* rr, ldns_rdf* rdf) { + return ldns_rr_rrsig_set_origttl(rr, ldns_rdf_clone(rdf)); +} +%} + +%rename(__ldns_rr_rrsig_set_sig) ldns_rr_rrsig_set_sig; +%inline %{ +bool _ldns_rr_rrsig_set_sig(ldns_rr* rr, ldns_rdf* rdf) { + return ldns_rr_rrsig_set_sig(rr, ldns_rdf_clone(rdf)); +} +%} + +%rename(__ldns_rr_rrsig_set_signame) ldns_rr_rrsig_set_signame; +%inline %{ +bool _ldns_rr_rrsig_set_signame(ldns_rr* rr, ldns_rdf* rdf) { + return ldns_rr_rrsig_set_signame(rr, ldns_rdf_clone(rdf)); +} +%} + +%rename(__ldns_rr_rrsig_set_typecovered) ldns_rr_rrsig_set_typecovered; +%inline %{ +bool _ldns_rr_rrsig_set_typecovered(ldns_rr* rr, ldns_rdf* rdf) { + return ldns_rr_rrsig_set_typecovered(rr, ldns_rdf_clone(rdf)); +} +%} + +%rename(__ldns_rr_set_owner) ldns_rr_set_owner; +%inline %{ +void _ldns_rr_set_owner(ldns_rr* rr, ldns_rdf* rdf) { + return ldns_rr_set_owner(rr, ldns_rdf_clone(rdf)); +} +%} + +%rename(__ldns_rr_set_rdf) ldns_rr_set_rdf; +%inline %{ + ldns_rdf* _ldns_rr_set_rdf(ldns_rr* rr, ldns_rdf* rdf, size_t pos) { + return ldns_rr_set_rdf(rr, ldns_rdf_clone(rdf), pos); +} +%} + +// end of push cloning + +%rename(_ldns_rr_new_frm_str) ldns_rr_new_frm_str; +%rename(_ldns_rr_new_frm_fp_l) ldns_rr_new_frm_fp_l; +%rename(_ldns_rr_new_frm_fp) ldns_rr_new_frm_fp; + +%feature("docstring") ldns_struct_rr "Resource Record (RR) + +The RR is the basic DNS element that contains actual data. This class allows to create RR and manipulate with the content." + +%extend ldns_struct_rr { + + %pythoncode %{ + def __init__(self): + raise Exception("This class can't be created directly. Please use: ldns_rr_new, ldns_rr_new_frm_type, new_frm_fp(), new_frm_fp_l(), new_frm_str() or new_question_frm_str") + + __swig_destroy__ = _ldns._ldns_rr_free + + #LDNS_RR_CONSTRUCTORS_# + @staticmethod + def new_frm_str(str, default_ttl=0, origin=None, prev=None, raiseException=True): + """Creates an rr object from a string. + + The string should be a fully filled-in rr, like ownername [space] TTL [space] CLASS [space] TYPE [space] RDATA. + + :param str: the string to convert + :param default_ttl: default ttl value for the rr. If 0 DEF_TTL will be used + :param origin: when the owner is relative add this + :param prev: the previous ownername + :param raiseException: if True, an exception occurs in case a rr instance can't be created + :returns: + * rr - (ldnsrr) RR instance or None. If the object can't be created and raiseException is True, an exception occurs. + + **Usage** + + >>> import ldns + >>> rr = ldns.ldns_rr.new_frm_str("www.nic.cz. IN A 192.168.1.1",300) + >>> print rr + www.nic.cz. 300 IN A 192.168.1.1 + """ + status, rr, prev = _ldns.ldns_rr_new_frm_str_(str, default_ttl, origin, prev) + if status != LDNS_STATUS_OK: + if (raiseException): raise Exception("Can't create RR, error: %d" % status) + return None + return rr + + @staticmethod + def new_question_frm_str(str, default_ttl=0, origin=None, prev=None, raiseException=True): + """Creates an rr object from a string. + + The string is like new_frm_str but without rdata. + + :param str: the string to convert + :param origin: when the owner is relative add this + :param prev: the previous ownername + :param raiseException: if True, an exception occurs in case a rr instance can't be created + :returns: + * rr - (ldnsrr) RR instance or None. If the object can't be created and raiseException is True, an exception occurs. + """ + status, rr, prev = _ldns.ldns_rr_new_question_frm_str_(str, origin, prev) + if status != LDNS_STATUS_OK: + if (raiseException): raise Exception("Can't create RR, error: %d" % status) + return None + return rr + + @staticmethod + def new_frm_str_prev(str, default_ttl=0, origin=None, prev=None, raiseException=True): + """Creates an rr object from a string. + + The string should be a fully filled-in rr, like ownername [space] TTL [space] CLASS [space] TYPE [space] RDATA. + + :param str: the string to convert + :param default_ttl: default ttl value for the rr. If 0 DEF_TTL will be used + :param origin: when the owner is relative add this + :param prev: the previous ownername + :param raiseException: if True, an exception occurs in case a rr instance can't be created + :returns: + * rr - (ldnsrr) RR instance or None. If the object can't be created and raiseException is True, an exception occurs. + + * prev - (ldns_rdf) ownername found in this string or None + """ + status, rr, prev = _ldns.ldns_rr_new_frm_str_(str, default_ttl, origin, prev) + if status != LDNS_STATUS_OK: + if (raiseException): raise Exception("Can't create RR, error: %d" % status) + return None + return rr, prev + + @staticmethod + def new_frm_fp(file, default_ttl=0, origin=None, prev=None, raiseException=True): + """Creates a new rr from a file containing a string. + + :param file: file pointer + :param default_ttl: If 0 DEF_TTL will be used + :param origin: when the owner is relative add this. + :param prev: when the owner is whitespaces use this. + :param raiseException: if True, an exception occurs in case a resolver object can't be created + :returns: + * rr - (ldns_rr) RR object or None. If the object can't be created and raiseException is True, an exception occurs. + + * ttl - (int) None or TTL if the file contains a $TTL directive + + * origin - (ldns_rdf) None or dname if the file contains a $ORIGIN directive + + * prev - (ldns_rdf) None or updated value of prev parameter + """ + res = _ldns.ldns_rr_new_frm_fp_l_(file, default_ttl, origin, prev, 0) + if res[0] != LDNS_STATUS_OK: + if (raiseException): raise Exception("Can't create RR, error: %d" % res[0]) + return None + return res[1:] + + @staticmethod + def new_frm_fp_l(file, default_ttl=0, origin=None, prev=None, raiseException=True): + """Creates a new rr from a file containing a string. + + :param file: file pointer + :param default_ttl: If 0 DEF_TTL will be used + :param origin: when the owner is relative add this. + :param prev: when the owner is whitespaces use this. + :param raiseException: if True, an exception occurs in case a resolver object can't be created + :returns: + * rr - (ldns_rr) RR object or None. If the object can't be created and raiseException is True, an exception occurs. + + * line - (int) line number (for debugging) + + * ttl - (int) None or TTL if the file contains a $TTL directive + + * origin - (ldns_rdf) None or dname if the file contains a $ORIGIN directive + + * prev - (ldns_rdf) None or updated value of prev parameter + """ + res = _ldns.ldns_rr_new_frm_fp_l_(file, default_ttl, origin, prev, 1) + if res[0] != LDNS_STATUS_OK: + if (raiseException): raise Exception("Can't create RR, error: %d" % res[0]) + return None + return res[1:] + #_LDNS_RR_CONSTRUCTORS# + + + def __str__(self): + """converts the data in the resource record to presentation format""" + return _ldns.ldns_rr2str(self) + + def __cmp__(self, other): + """compares two rrs. + + The TTL is not looked at. + + :param other: + the second RR one + :returns: (int) 0 if equal -1 if self comes before other RR +1 if other RR comes before self + """ + return _ldns.ldns_rr_compare(self,other) + + def rdfs(self): + """returns the list of rdata records.""" + for i in range(0,self.rd_count()): + yield self.rdf(i) + + def print_to_file(self,output): + """Prints the data in the resource record to the given file stream (in presentation format).""" + _ldns.ldns_rr_print(output,self) + #parameters: FILE *,const ldns_rr *, + + def get_type_str(self): + """Converts an RR type value to its string representation, and returns that string.""" + return _ldns.ldns_rr_type2str(self.get_type()) + #parameters: const ldns_rr_type, + + def get_class_str(self): + """Converts an RR class value to its string representation, and returns that string.""" + return _ldns.ldns_rr_class2str(self.get_class()) + #parameters: const ldns_rr_class, + + @staticmethod + def dnskey_key_size_raw(keydata,len,alg): + """get the length of the keydata in bits""" + return _ldns.ldns_rr_dnskey_key_size_raw(keydata,len,alg) + #parameters: const unsigned char *,const size_t,const ldns_algorithm, + #retvals: size_t + + def write_to_buffer(self,buffer,section): + """Copies the rr data to the buffer in wire format. + + :param buffer: buffer to append the result to buffer + :param section: the section in the packet this rr is supposed to be in (to determine whether to add rdata or not) + :returns: (ldns_status) ldns_status + """ + return _ldns.ldns_rr2buffer_wire(buffer,self,section) + #parameters: ldns_buffer *,const ldns_rr *,int, + #retvals: ldns_status + + def write_to_buffer_canonical(self,buffer,section): + """Copies the rr data to the buffer in wire format, in canonical format according to RFC3597 (every dname in rdata fields of RR's mentioned in that RFC will be lowercased). + + :param buffer: buffer to append the result to buffer + :param section: the section in the packet this rr is supposed to be in (to determine whether to add rdata or not) + :returns: (ldns_status) ldns_status + """ + return _ldns.ldns_rr2buffer_wire_canonical(buffer,self,section) + #parameters: ldns_buffer *,const ldns_rr *,int, + #retvals: ldns_status + + def write_data_to_buffer(self,buffer): + """Converts an rr's rdata to wireformat, while excluding the ownername and all the stuff before the rdata. + + This is needed in DNSSEC keytag calculation, the ds calcalution from the key and maybe elsewhere. + + :param buffer: buffer to append the result to + :returns: (ldns_status) ldns_status + """ + return _ldns.ldns_rr_rdata2buffer_wire(buffer,self) + #parameters: ldns_buffer *,const ldns_rr *, + #retvals: ldns_status + + def write_rrsig_to_buffer(self,buffer): + """Converts a rrsig to wireformat BUT EXCLUDE the rrsig rdata + + This is needed in DNSSEC verification. + + :param buffer: buffer to append the result to + :returns: (ldns_status) ldns_status + """ + return _ldns.ldns_rrsig2buffer_wire(buffer,self) + #parameters: ldns_buffer *,const ldns_rr *, + #retvals: ldns_status + + #LDNS_RR_METHODS_# + def a_address(self): + """returns the address of a LDNS_RR_TYPE_A rr + + :returns: (ldns_rdf \*) a ldns_rdf* with the address or NULL on failure + """ + return _ldns._ldns_rr_a_address(self) + #parameters: const ldns_rr *, + #retvals: ldns_rdf * + + def a_set_address(self,f): + """sets the address of a LDNS_RR_TYPE_A rr + + :param f: + the address to set + :returns: (bool) true on success, false otherwise + """ + return _ldns._ldns_rr_a_set_address(self,f) + #parameters: ldns_rr *,ldns_rdf *, + #retvals: bool + + def clone(self): + """clones a rr and all its data + + :returns: (ldns_rr \*) the new rr or NULL on failure + """ + return _ldns.ldns_rr_clone(self) + #parameters: const ldns_rr *, + #retvals: ldns_rr * + + def compare_ds(self,rr2): + """returns true of the given rr's are equal. + + Also returns true if one record is a DS that represents the same DNSKEY record as the other record + + :param rr2: + the second rr + :returns: (bool) true if equal otherwise false + """ + return _ldns.ldns_rr_compare_ds(self,rr2) + #parameters: const ldns_rr *,const ldns_rr *, + #retvals: bool + + def compare_no_rdata(self,rr2): + """compares two rrs, up to the rdata. + + :param rr2: + the second one + :returns: (int) 0 if equal -1 if rr1 comes before rr2 +1 if rr2 comes before rr1 + """ + return _ldns.ldns_rr_compare_no_rdata(self,rr2) + #parameters: const ldns_rr *,const ldns_rr *, + #retvals: int + + def dnskey_algorithm(self): + """returns the algorithm of a LDNS_RR_TYPE_DNSKEY rr + + :returns: (ldns_rdf \*) a ldns_rdf* with the algorithm or NULL on failure + """ + return _ldns._ldns_rr_dnskey_algorithm(self) + #parameters: const ldns_rr *, + #retvals: ldns_rdf * + + def dnskey_flags(self): + """returns the flags of a LDNS_RR_TYPE_DNSKEY rr + + :returns: (ldns_rdf \*) a ldns_rdf* with the flags or NULL on failure + """ + return _ldns._ldns_rr_dnskey_flags(self) + #parameters: const ldns_rr *, + #retvals: ldns_rdf * + + def dnskey_key(self): + """returns the key data of a LDNS_RR_TYPE_DNSKEY rr + + :returns: (ldns_rdf \*) a ldns_rdf* with the key data or NULL on failure + """ + return _ldns._ldns_rr_dnskey_key(self) + #parameters: const ldns_rr *, + #retvals: ldns_rdf * + + def dnskey_key_size(self): + """get the length of the keydata in bits + + :returns: (size_t) the keysize in bits + """ + return _ldns.ldns_rr_dnskey_key_size(self) + #parameters: const ldns_rr *, + #retvals: size_t + + def dnskey_protocol(self): + """returns the protocol of a LDNS_RR_TYPE_DNSKEY rr + + :returns: (ldns_rdf \*) a ldns_rdf* with the protocol or NULL on failure + """ + return _ldns._ldns_rr_dnskey_protocol(self) + #parameters: const ldns_rr *, + #retvals: ldns_rdf * + + def dnskey_set_algorithm(self,f): + """sets the algorithm of a LDNS_RR_TYPE_DNSKEY rr + + :param f: + the algorithm to set + :returns: (bool) true on success, false otherwise + """ + return _ldns._ldns_rr_dnskey_set_algorithm(self,f) + #parameters: ldns_rr *,ldns_rdf *, + #retvals: bool + + def dnskey_set_flags(self,f): + """sets the flags of a LDNS_RR_TYPE_DNSKEY rr + + :param f: + the flags to set + :returns: (bool) true on success, false otherwise + """ + return _ldns._ldns_rr_dnskey_set_flags(self,f) + #parameters: ldns_rr *,ldns_rdf *, + #retvals: bool + + def dnskey_set_key(self,f): + """sets the key data of a LDNS_RR_TYPE_DNSKEY rr + + :param f: + the key data to set + :returns: (bool) true on success, false otherwise + """ + return _ldns._ldns_rr_dnskey_set_key(self,f) + #parameters: ldns_rr *,ldns_rdf *, + #retvals: bool + + def dnskey_set_protocol(self,f): + """sets the protocol of a LDNS_RR_TYPE_DNSKEY rr + + :param f: + the protocol to set + :returns: (bool) true on success, false otherwise + """ + return _ldns._ldns_rr_dnskey_set_protocol(self,f) + #parameters: ldns_rr *,ldns_rdf *, + #retvals: bool + + def get_class(self): + """returns the class of the rr. + + :returns: (ldns_rr_class) the class of the rr + """ + return _ldns.ldns_rr_get_class(self) + #parameters: const ldns_rr *, + #retvals: ldns_rr_class + + def get_type(self): + """returns the type of the rr. + + :returns: (ldns_rr_type) the type of the rr + """ + return _ldns.ldns_rr_get_type(self) + #parameters: const ldns_rr *, + #retvals: ldns_rr_type + + def label_count(self): + """counts the number of labels of the ownername. + + :returns: (uint8_t) the number of labels + """ + return _ldns.ldns_rr_label_count(self) + #parameters: ldns_rr *, + #retvals: uint8_t + + def mx_exchange(self): + """returns the mx host of a LDNS_RR_TYPE_MX rr + + :returns: (ldns_rdf \*) a ldns_rdf* with the name of the MX host or NULL on failure + """ + return _ldns._ldns_rr_mx_exchange(self) + #parameters: const ldns_rr *, + #retvals: ldns_rdf * + + def mx_preference(self): + """returns the mx pref. + + of a LDNS_RR_TYPE_MX rr + + :returns: (ldns_rdf \*) a ldns_rdf* with the preference or NULL on failure + """ + return _ldns._ldns_rr_mx_preference(self) + #parameters: const ldns_rr *, + #retvals: ldns_rdf * + + def ns_nsdname(self): + """returns the name of a LDNS_RR_TYPE_NS rr + + :returns: (ldns_rdf \*) a ldns_rdf* with the name or NULL on failure + """ + return _ldns._ldns_rr_ns_nsdname(self) + #parameters: const ldns_rr *, + #retvals: ldns_rdf * + + def owner(self): + """returns the owner name of an rr structure. + + :returns: (ldns_rdf \*) ldns_rdf * + """ + return _ldns._ldns_rr_owner(self) + #parameters: const ldns_rr *, + #retvals: ldns_rdf * + + def pop_rdf(self): + """removes a rd_field member, it will be popped from the last position. + + :returns: (ldns_rdf \*) rdf which was popped (null if nothing) + """ + return _ldns.ldns_rr_pop_rdf(self) + #parameters: ldns_rr *, + #retvals: ldns_rdf * + + def push_rdf(self,f): + """sets rd_field member, it will be placed in the next available spot. + + :param f: + :returns: (bool) bool + """ + return _ldns._ldns_rr_push_rdf(self,f) + #parameters: ldns_rr *,const ldns_rdf *, + #retvals: bool + + def rd_count(self): + """returns the rd_count of an rr structure. + + :returns: (size_t) the rd count of the rr + """ + return _ldns.ldns_rr_rd_count(self) + #parameters: const ldns_rr *, + #retvals: size_t + + def rdf(self,nr): + """returns the rdata field member counter. + + :param nr: + the number of the rdf to return + :returns: (ldns_rdf \*) ldns_rdf * + """ + return _ldns._ldns_rr_rdf(self,nr) + #parameters: const ldns_rr *,size_t, + #retvals: ldns_rdf * + + def rrsig_algorithm(self): + """returns the algorithm of a LDNS_RR_TYPE_RRSIG RR + + :returns: (ldns_rdf \*) a ldns_rdf* with the algorithm or NULL on failure + """ + return _ldns._ldns_rr_rrsig_algorithm(self) + #parameters: const ldns_rr *, + #retvals: ldns_rdf * + + def rrsig_expiration(self): + """returns the expiration time of a LDNS_RR_TYPE_RRSIG RR + + :returns: (ldns_rdf \*) a ldns_rdf* with the expiration time or NULL on failure + """ + return _ldns._ldns_rr_rrsig_expiration(self) + #parameters: const ldns_rr *, + #retvals: ldns_rdf * + + def rrsig_inception(self): + """returns the inception time of a LDNS_RR_TYPE_RRSIG RR + + :returns: (ldns_rdf \*) a ldns_rdf* with the inception time or NULL on failure + """ + return _ldns._ldns_rr_rrsig_inception(self) + #parameters: const ldns_rr *, + #retvals: ldns_rdf * + + def rrsig_keytag(self): + """returns the keytag of a LDNS_RR_TYPE_RRSIG RR + + :returns: (ldns_rdf \*) a ldns_rdf* with the keytag or NULL on failure + """ + return _ldns._ldns_rr_rrsig_keytag(self) + #parameters: const ldns_rr *, + #retvals: ldns_rdf * + + def rrsig_labels(self): + """returns the number of labels of a LDNS_RR_TYPE_RRSIG RR + + :returns: (ldns_rdf \*) a ldns_rdf* with the number of labels or NULL on failure + """ + return _ldns._ldns_rr_rrsig_labels(self) + #parameters: const ldns_rr *, + #retvals: ldns_rdf * + + def rrsig_origttl(self): + """returns the original TTL of a LDNS_RR_TYPE_RRSIG RR + + :returns: (ldns_rdf \*) a ldns_rdf* with the original TTL or NULL on failure + """ + return _ldns._ldns_rr_rrsig_origttl(self) + #parameters: const ldns_rr *, + #retvals: ldns_rdf * + + def rrsig_set_algorithm(self,f): + """sets the algorithm of a LDNS_RR_TYPE_RRSIG rr + + :param f: + the algorithm to set + :returns: (bool) true on success, false otherwise + """ + return _ldns._ldns_rr_rrsig_set_algorithm(self,f) + #parameters: ldns_rr *,ldns_rdf *, + #retvals: bool + + def rrsig_set_expiration(self,f): + """sets the expireation date of a LDNS_RR_TYPE_RRSIG rr + + :param f: + the expireation date to set + :returns: (bool) true on success, false otherwise + """ + return _ldns._ldns_rr_rrsig_set_expiration(self,f) + #parameters: ldns_rr *,ldns_rdf *, + #retvals: bool + + def rrsig_set_inception(self,f): + """sets the inception date of a LDNS_RR_TYPE_RRSIG rr + + :param f: + the inception date to set + :returns: (bool) true on success, false otherwise + """ + return _ldns._ldns_rr_rrsig_set_inception(self,f) + #parameters: ldns_rr *,ldns_rdf *, + #retvals: bool + + def rrsig_set_keytag(self,f): + """sets the keytag of a LDNS_RR_TYPE_RRSIG rr + + :param f: + the keytag to set + :returns: (bool) true on success, false otherwise + """ + return _ldns._ldns_rr_rrsig_set_keytag(self,f) + #parameters: ldns_rr *,ldns_rdf *, + #retvals: bool + + def rrsig_set_labels(self,f): + """sets the number of labels of a LDNS_RR_TYPE_RRSIG rr + + :param f: + the number of labels to set + :returns: (bool) true on success, false otherwise + """ + return _ldns._ldns_rr_rrsig_set_labels(self,f) + #parameters: ldns_rr *,ldns_rdf *, + #retvals: bool + + def rrsig_set_origttl(self,f): + """sets the original TTL of a LDNS_RR_TYPE_RRSIG rr + + :param f: + the original TTL to set + :returns: (bool) true on success, false otherwise + """ + return _ldns._ldns_rr_rrsig_set_origttl(self,f) + #parameters: ldns_rr *,ldns_rdf *, + #retvals: bool + + def rrsig_set_sig(self,f): + """sets the signature data of a LDNS_RR_TYPE_RRSIG rr + + :param f: + the signature data to set + :returns: (bool) true on success, false otherwise + """ + return _ldns._ldns_rr_rrsig_set_sig(self,f) + #parameters: ldns_rr *,ldns_rdf *, + #retvals: bool + + def rrsig_set_signame(self,f): + """sets the signers name of a LDNS_RR_TYPE_RRSIG rr + + :param f: + the signers name to set + :returns: (bool) true on success, false otherwise + """ + return _ldns._ldns_rr_rrsig_set_signame(self,f) + #parameters: ldns_rr *,ldns_rdf *, + #retvals: bool + + def rrsig_set_typecovered(self,f): + """sets the typecovered of a LDNS_RR_TYPE_RRSIG rr + + :param f: + the typecovered to set + :returns: (bool) true on success, false otherwise + """ + return _ldns._ldns_rr_rrsig_set_typecovered(self,f) + #parameters: ldns_rr *,ldns_rdf *, + #retvals: bool + + def rrsig_sig(self): + """returns the signature data of a LDNS_RR_TYPE_RRSIG RR + + :returns: (ldns_rdf \*) a ldns_rdf* with the signature data or NULL on failure + """ + return _ldns._ldns_rr_rrsig_sig(self) + #parameters: const ldns_rr *, + #retvals: ldns_rdf * + + def rrsig_signame(self): + """returns the signers name of a LDNS_RR_TYPE_RRSIG RR + + :returns: (ldns_rdf \*) a ldns_rdf* with the signers name or NULL on failure + """ + return _ldns._ldns_rr_rrsig_signame(self) + #parameters: const ldns_rr *, + #retvals: ldns_rdf * + + def rrsig_typecovered(self): + """returns the type covered of a LDNS_RR_TYPE_RRSIG rr + + :returns: (ldns_rdf \*) a ldns_rdf* with the type covered or NULL on failure + """ + return _ldns._ldns_rr_rrsig_typecovered(self) + #parameters: const ldns_rr *, + #retvals: ldns_rdf * + + def set_class(self,rr_class): + """sets the class in the rr. + + :param rr_class: + set to this class + """ + _ldns.ldns_rr_set_class(self,rr_class) + #parameters: ldns_rr *,ldns_rr_class, + #retvals: + + def set_owner(self,owner): + """sets the owner in the rr structure. + + :param owner: + """ + _ldns._ldns_rr_set_owner(self,owner) + #parameters: ldns_rr *,ldns_rdf *, + #retvals: + + def set_rd_count(self,count): + """sets the rd_count in the rr. + + :param count: + set to this count + """ + _ldns.ldns_rr_set_rd_count(self,count) + #parameters: ldns_rr *,size_t, + #retvals: + + def set_rdf(self,f,position): + """sets a rdf member, it will be set on the position given. + + The old value is returned, like pop. + + :param f: + :param position: + the position the set the rdf + :returns: (ldns_rdf \*) the old value in the rr, NULL on failyre + """ + return _ldns._ldns_rr_set_rdf(self,f,position) + #parameters: ldns_rr *,const ldns_rdf *,size_t, + #retvals: ldns_rdf * + + def set_ttl(self,ttl): + """sets the ttl in the rr structure. + + :param ttl: + set to this ttl + """ + _ldns.ldns_rr_set_ttl(self,ttl) + #parameters: ldns_rr *,uint32_t, + #retvals: + + def set_type(self,rr_type): + """sets the type in the rr. + + :param rr_type: + set to this type + """ + _ldns.ldns_rr_set_type(self,rr_type) + #parameters: ldns_rr *,ldns_rr_type, + #retvals: + + def ttl(self): + """returns the ttl of an rr structure. + + :returns: (uint32_t) the ttl of the rr + """ + return _ldns.ldns_rr_ttl(self) + #parameters: const ldns_rr *, + #retvals: uint32_t + + def uncompressed_size(self): + """calculates the uncompressed size of an RR. + + :returns: (size_t) size of the rr + """ + return _ldns.ldns_rr_uncompressed_size(self) + #parameters: const ldns_rr *, + #retvals: size_t + + #_LDNS_RR_METHODS# + %} +} + +%nodefaultctor ldns_struct_rr_list; //no default constructor & destructor +%nodefaultdtor ldns_struct_rr_list; + +%ignore ldns_struct_rr_list::_rrs; + +%newobject ldns_rr_list_clone; +%newobject ldns_rr_list_pop_rr; +%newobject ldns_rr_list_pop_rr_list; +%newobject ldns_rr_list_pop_rrset; +%newobject ldns_rr_list_rr; +%newobject ldns_rr_list_new; +%delobject ldns_rr_list_deep_free; +%delobject ldns_rr_list_free; + +%rename(ldns_rr_list) ldns_struct_rr_list; +#ifdef LDNS_DEBUG +%rename(__ldns_rr_list_deep_free) ldns_rr_list_deep_free; +%rename(__ldns_rr_list_free) ldns_rr_list_free; +%inline %{ +void _ldns_rr_list_free(ldns_rr_list* r) { + printf("******** LDNS_RR_LIST deep free 0x%lX ************\n", (long unsigned int)r); + ldns_rr_list_deep_free(r); +} +%} +#else +%rename(_ldns_rr_list_deep_free) ldns_rr_list_deep_free; +%rename(_ldns_rr_list_free) ldns_rr_list_free; +#endif + +/* clone data on push */ + +%rename(__ldns_rr_list_push_rr) ldns_rr_list_push_rr; +%inline %{ +void _ldns_rr_list_push_rr(ldns_rr_list* r, ldns_rr *rr) { + ldns_rr_list_push_rr(r, ldns_rr_clone(rr)); +} +%} + +%rename(__ldns_rr_list_push_rr_list) ldns_rr_list_push_rr_list; +%inline %{ +void _ldns_rr_list_push_rr_list(ldns_rr_list* r, ldns_rr_list *r2) { + ldns_rr_list_push_rr_list(r, ldns_rr_list_clone(r2)); +} +%} + +%rename(__ldns_rr_list_cat) ldns_rr_list_cat; +%inline %{ +void _ldns_rr_list_cat(ldns_rr_list* r, ldns_rr_list *r2) { + ldns_rr_list_cat(r, ldns_rr_list_clone(r2)); +} +%} + + +/* clone data on pull */ + +%newobject _ldns_rr_list_rr; + +%rename(__ldns_rr_list_rr) ldns_rr_list_rr; +%inline %{ +ldns_rr* _ldns_rr_list_rr(ldns_rr_list* r, int i) { + return ldns_rr_clone(ldns_rr_list_rr(r, i)); +} +%} + +%newobject ldns_rr_list2str; + +%rename(__ldns_rr_list_owner) ldns_rr_list_owner; +%inline %{ +ldns_rdf* _ldns_rr_list_owner(ldns_rr_list* r) { + return ldns_rdf_clone(ldns_rr_list_owner(r)); +} +%} + + + +%feature("docstring") ldns_struct_rr_list "List of Resource Records. + +This class contains a list of RR's (see :class:`ldns.ldns_rr`). +" + +%extend ldns_struct_rr_list { + + %pythoncode %{ + def __init__(self): + self.this = _ldns.ldns_rr_list_new() + if not self.this: + raise Exception("Can't create new RR_LIST") + + __swig_destroy__ = _ldns._ldns_rr_list_deep_free + + #LDNS_RR_LIST_CONSTRUCTORS_# + @staticmethod + def new_frm_file(filename="/etc/hosts", raiseException=True): + """Creates an RR List object from a file content + + Goes through a file and returns a rr_list containing all the defined hosts in there. + + :param filename: the filename to use + :returns: RR List object or None. If the object can't be created and raiseException is True, an exception occurs. + + **Usage** + >>> alist = ldns.ldns_rr_list.new_frm_file() + >>> print alist + localhost. 3600 IN A 127.0.0.1 + ... + + """ + rr = _ldns.ldns_get_rr_list_hosts_frm_file(filename) + if (not rr) and (raiseException): raise Exception("Can't create RR List, error: %d" % status) + return rr + #_LDNS_RR_LIST_CONSTRUCTORS# + + def __str__(self): + """converts a list of resource records to presentation format""" + return _ldns.ldns_rr_list2str(self) + + def print_to_file(self,output): + """print a rr_list to output param[in] output the fd to print to param[in] list the rr_list to print""" + _ldns.ldns_rr_list_print(output,self) + + + def to_canonical(self): + """converts each dname in each rr in a rr_list to its canonical form.""" + _ldns.ldns_rr_list2canonical(self) + #parameters: ldns_rr_list *, + #retvals: + + def rrs(self): + """returns the list of rr records.""" + for i in range(0,self.rr_count()): + yield self.rr(i) + + def is_rrset(self): + """checks if an rr_list is a rrset.""" + return _ldns.ldns_is_rrset(self) + + def __cmp__(self,rrl2): + """compares two rr listss. + + :param rrl2: + the second one + :returns: (int) 0 if equal -1 if this list comes before rrl2 +1 if rrl2 comes before this list + """ + return _ldns.ldns_rr_list_compare(self,rrl2) + + def write_to_buffer(self, buffer): + """Copies the rr_list data to the buffer in wire format. + + :param buffer: output buffer to append the result to + :returns: (ldns_status) ldns_status + """ + return _ldns.ldns_rr_list2buffer_wire(buffer,self) + + #LDNS_RR_LIST_METHODS_# + def cat(self,right): + """concatenates two ldns_rr_lists together. + + This modifies rr list (to extend it and add the pointers from right). + + :param right: + the rightside + :returns: (bool) a left with right concatenated to it + """ + return _ldns._ldns_rr_list_cat(self,right) + #parameters: ldns_rr_list *,ldns_rr_list *, + #retvals: bool + + def cat_clone(self,right): + """concatenates two ldns_rr_lists together, but makes clones of the rr's (instead of pointer copying). + + :param right: + the rightside + :returns: (ldns_rr_list \*) a new rr_list with leftside/rightside concatenated + """ + return _ldns.ldns_rr_list_cat_clone(self,right) + #parameters: ldns_rr_list *,ldns_rr_list *, + #retvals: ldns_rr_list * + + def clone(self): + """clones an rrlist. + + :returns: (ldns_rr_list \*) the cloned rr list + """ + return _ldns.ldns_rr_list_clone(self) + #parameters: const ldns_rr_list *, + #retvals: ldns_rr_list * + + def contains_rr(self,rr): + """returns true if the given rr is one of the rrs in the list, or if it is equal to one + + :param rr: + the rr to check + :returns: (bool) true if rr_list contains rr, false otherwise + """ + return _ldns.ldns_rr_list_contains_rr(self,rr) + #parameters: const ldns_rr_list *,ldns_rr *, + #retvals: bool + + def owner(self): + """Returns the owner domain name rdf of the first element of the RR If there are no elements present, NULL is returned. + + :returns: (ldns_rdf \*) dname of the first element, or NULL if the list is empty + """ + return _ldns._ldns_rr_list_owner(self) + #parameters: const ldns_rr_list *, + #retvals: ldns_rdf * + + def pop_rr(self): + """pops the last rr from an rrlist. + + :returns: (ldns_rr \*) NULL if nothing to pop. Otherwise the popped RR + """ + rr = _ldns.ldns_rr_list_pop_rr(self) + #if hasattr(self, "_python_rr_refs") and rr in self._python_rr_refs: + # self._python_rr_refs.remove(rr) + return rr + #parameters: ldns_rr_list *, + #retvals: ldns_rr * + + def pop_rr_list(self,size): + """pops an rr_list of size s from an rrlist. + + :param size: + the number of rr's to pop + :returns: (ldns_rr_list \*) NULL if nothing to pop. Otherwise the popped rr_list + """ + return _ldns.ldns_rr_list_pop_rr_list(self,size) + #parameters: ldns_rr_list *,size_t, + #retvals: ldns_rr_list * + + def pop_rrset(self): + """pops the first rrset from the list, the list must be sorted, so that all rr's from each rrset are next to each other + + :returns: (ldns_rr_list \*) + """ + return _ldns.ldns_rr_list_pop_rrset(self) + #parameters: ldns_rr_list *, + #retvals: ldns_rr_list * + + def push_rr(self,rr): + """pushes an rr to an rrlist. + + :param rr: + the rr to push + :returns: (bool) false on error, otherwise true + """ + #if hasattr(self, "_python_rr_refs"): + # self._python_rr_refs.add(rr) + #else: + # self._python_rr_refs = set([rr]) + return _ldns._ldns_rr_list_push_rr(self,rr) + #parameters: ldns_rr_list *,const ldns_rr *, + #retvals: bool + + def push_rr_list(self,push_list): + """pushes an rr_list to an rrlist. + + :param push_list: + the rr_list to push + :returns: (bool) false on error, otherwise true + """ + return _ldns._ldns_rr_list_push_rr_list(self,push_list) + #parameters: ldns_rr_list *,const ldns_rr_list *, + #retvals: bool + + def rr(self,nr): + """returns a specific rr of an rrlist. + + :param nr: + return this rr + :returns: (ldns_rr \*) the rr at position nr + """ + return _ldns._ldns_rr_list_rr(self,nr) + #parameters: const ldns_rr_list *,size_t, + #retvals: ldns_rr * + + def rr_count(self): + """returns the number of rr's in an rr_list. + + :returns: (size_t) the number of rr's + """ + return _ldns.ldns_rr_list_rr_count(self) + #parameters: const ldns_rr_list *, + #retvals: size_t + + def set_rr(self,r,count): + """set a rr on a specific index in a ldns_rr_list + + :param r: + the rr to set + :param count: + index into the rr_list + :returns: (ldns_rr \*) the old rr which was stored in the rr_list, or NULL is the index was too large set a specific rr + """ + return _ldns.ldns_rr_list_set_rr(self,r,count) + #parameters: ldns_rr_list *,const ldns_rr *,size_t, + #retvals: ldns_rr * + + def set_rr_count(self,count): + """sets the number of rr's in an rr_list. + + :param count: + the number of rr in this list + """ + _ldns.ldns_rr_list_set_rr_count(self,count) + #parameters: ldns_rr_list *,size_t, + #retvals: + + def sort(self): + """sorts an rr_list (canonical wire format). + + the sorting is done inband. + """ + _ldns.ldns_rr_list_sort(self) + #parameters: ldns_rr_list *, + #retvals: + + def subtype_by_rdf(self,r,pos): + """Return the rr_list which matches the rdf at position field. + + Think type-covered stuff for RRSIG + + :param r: + the rdf to use for the comparison + :param pos: + at which position can we find the rdf + :returns: (ldns_rr_list \*) a new rr list with only the RRs that match + """ + return _ldns.ldns_rr_list_subtype_by_rdf(self,r,pos) + #parameters: ldns_rr_list *,ldns_rdf *,size_t, + #retvals: ldns_rr_list * + + def type(self): + """Returns the type of the first element of the RR If there are no elements present, 0 is returned (LDNS_RR_TYPE_A). + + :returns: (ldns_rr_type) rr_type of the first element, or 0 if the list is empty + """ + return _ldns.ldns_rr_list_type(self) + #parameters: const ldns_rr_list *, + #retvals: ldns_rr_type + #_LDNS_RR_LIST_METHODS# + %} +} + +%newobject ldns_rr_descript; + +%nodefaultctor ldns_struct_rr_descriptor; //no default constructor & destructor +%nodefaultdtor ldns_struct_rr_descriptor; +%rename(ldns_rr_descriptor) ldns_struct_rr_descriptor; + + + + +%feature("docstring") ldns_struct_rr_descriptor "Resource Record descriptor +This structure contains, for all rr types, the rdata fields that are defined." + +%extend ldns_struct_rr_descriptor { + %pythoncode %{ + def __init__(self): + raise Exception("This class can't be created directly. Please use: ldns_rr_descript") + #LDNS_RR_DESCRIPTOR_METHODS_# + def field_type(self,field): + """returns the rdf type for the given rdata field number of the rr type for the given descriptor. + + :param field: + the field number + :returns: (ldns_rdf_type) the rdf type for the field + """ + return _ldns.ldns_rr_descriptor_field_type(self,field) + #parameters: const ldns_rr_descriptor *,size_t, + #retvals: ldns_rdf_type + + def maximum(self): + """returns the maximum number of rdata fields of the rr type this descriptor describes. + + :returns: (size_t) the maximum number of rdata fields + """ + return _ldns.ldns_rr_descriptor_maximum(self) + #parameters: const ldns_rr_descriptor *, + #retvals: size_t + + def minimum(self): + """returns the minimum number of rdata fields of the rr type this descriptor describes. + + :returns: (size_t) the minimum number of rdata fields + """ + return _ldns.ldns_rr_descriptor_minimum(self) + #parameters: const ldns_rr_descriptor *, + #retvals: size_t + + #_LDNS_RR_DESCRIPTOR_METHODS# + %} +} + +/* + +rrsig checking wrappers + + copying of rr pointers into the good_keys list leads to double free + problems, therefore we provide two options - either ignore the keys + or get list of indexes of the keys. The latter allows fetching of the + keys later on from the original key set +*/ + +%rename(__ldns_verify_rrsig_keylist) ldns_verify_rrsig_keylist; +%inline %{ +ldns_status ldns_verify_rrsig_keylist_status_only(ldns_rr_list *rrset, + ldns_rr *rrsig, + const ldns_rr_list *keys) { + ldns_rr_list *good_keys = ldns_rr_list_new(); + ldns_status status = ldns_verify_rrsig_keylist(rrset, rrsig, keys, good_keys); + ldns_rr_list_free(good_keys); + return status; +} +%} + +%rename(__ldns_verify_rrsig_keylist) ldns_verify_rrsig_keylist; +%inline %{ +PyObject* ldns_verify_rrsig_keylist_(ldns_rr_list *rrset, + ldns_rr *rrsig, + const ldns_rr_list *keys) { + PyObject* tuple; + PyObject* keylist; + ldns_rr_list *good_keys = ldns_rr_list_new(); + ldns_status status = ldns_verify_rrsig_keylist(rrset, rrsig, keys, good_keys); + + tuple = PyTuple_New(2); + PyTuple_SetItem(tuple, 0, SWIG_From_int(status)); + keylist = PyList_New(0); + if (status == LDNS_STATUS_OK) { + unsigned int i; + for (i = 0; i < ldns_rr_list_rr_count(keys); i++) + if (ldns_rr_list_contains_rr(good_keys, ldns_rr_list_rr(keys, i))) + PyList_Append(keylist, SWIG_From_int(i)); + } + PyTuple_SetItem(tuple, 1, keylist); + ldns_rr_list_free(good_keys); + return tuple; + } +%} + + +%rename(__ldns_verify_rrsig_keylist_notime) ldns_verify_rrsig_keylist_notime; +%inline %{ +ldns_status ldns_verify_rrsig_keylist_notime_status_only(ldns_rr_list *rrset, + ldns_rr *rrsig, + const ldns_rr_list *keys) { + ldns_rr_list *good_keys = ldns_rr_list_new(); + ldns_status status = ldns_verify_rrsig_keylist_notime(rrset, rrsig, keys, good_keys); + ldns_rr_list_free(good_keys); + return status; +} +%} + +%rename(__ldns_verify_rrsig_keylist_notime) ldns_verify_rrsig_keylist_notime; +%inline %{ +PyObject* ldns_verify_rrsig_keylist_notime_(ldns_rr_list *rrset, + ldns_rr *rrsig, + const ldns_rr_list *keys) { + PyObject* tuple; + PyObject* keylist; + ldns_rr_list *good_keys = ldns_rr_list_new(); + ldns_status status = ldns_verify_rrsig_keylist_notime(rrset, rrsig, keys, good_keys); + + tuple = PyTuple_New(2); + PyTuple_SetItem(tuple, 0, SWIG_From_int(status)); + keylist = PyList_New(0); + if (status == LDNS_STATUS_OK) { + unsigned int i; + for (i = 0; i < ldns_rr_list_rr_count(keys); i++) + if (ldns_rr_list_contains_rr(good_keys, ldns_rr_list_rr(keys, i))) + PyList_Append(keylist, SWIG_From_int(i)); + } + PyTuple_SetItem(tuple, 1, keylist); + ldns_rr_list_free(good_keys); + return tuple; + } +%} + +/* -- end of rrsig checking wrappers */ + diff --git a/contrib/python/ldns_zone.i b/contrib/python/ldns_zone.i new file mode 100644 index 000000000000..2afdd9693094 --- /dev/null +++ b/contrib/python/ldns_zone.i @@ -0,0 +1,298 @@ +/****************************************************************************** + * ldns_zone.i: LDNS zone class + * + * Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz) + * Karel Slany (slany AT fit.vutbr.cz) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the organization nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************/ + +%typemap(in,numinputs=0,noblock=1) (ldns_zone **) +{ + ldns_zone *$1_zone; + $1 = &$1_zone; +} + +/* result generation */ +%typemap(argout,noblock=1) (ldns_zone **) +{ + $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(SWIG_as_voidptr($1_zone), SWIGTYPE_p_ldns_struct_zone, SWIG_POINTER_OWN | 0 )); +} + +%nodefaultctor ldns_struct_zone; //no default constructor & destructor +%nodefaultdtor ldns_struct_zone; + +%newobject ldns_zone_new_frm_fp; +%newobject ldns_zone_new_frm_fp_l; +%newobject ldns_zone_new; +%delobject ldns_zone_free; +%delobject ldns_zone_deep_free; +%delobject ldns_zone_push_rr; +%delobject ldns_zone_push_rr_list; + +%ignore ldns_struct_zone::_soa; +%ignore ldns_struct_zone::_rrs; + +%rename(ldns_zone) ldns_struct_zone; + +#ifdef LDNS_DEBUG +%rename(__ldns_zone_free) ldns_zone_free; +%rename(__ldns_zone_deep_free) ldns_zone_deep_free; +%inline %{ +void _ldns_zone_free (ldns_zone* z) { + printf("******** LDNS_ZONE free 0x%lX ************\n", (long unsigned int)z); + ldns_zone_deep_free(z); +} +%} +#else +%rename(__ldns_zone_free) ldns_zone_free; +%rename(_ldns_zone_free) ldns_zone_deep_free; +#endif +%feature("docstring") ldns_struct_zone "Zone definitions + +**Usage** + +This class is able to read and parse the content of zone file by doing: + +>>> import ldns +>>> zone = ldns.ldns_zone.new_frm_fp(open(\"zone.txt\",\"r\"), None, 0, ldns.LDNS_RR_CLASS_IN) +>>> print zone.soa() +example. 600 IN SOA example. admin.example. 2008022501 28800 7200 604800 18000 +>>> print zone.rrs() +example. 600 IN MX 10 mail.example. +example. 600 IN NS ns1.example. +example. 600 IN NS ns2.example. +example. 600 IN A 192.168.1.1 + +The ``zone.txt`` file contains the following records:: + + $ORIGIN example. + $TTL 600 + + example. IN SOA example. admin.example. ( + 2008022501 ; serial + 28800 ; refresh (8 hours) + 7200 ; retry (2 hours) + 604800 ; expire (1 week) + 18000 ; minimum (5 hours) + ) + + @ IN MX 10 mail.example. + @ IN NS ns1 + @ IN NS ns2 + @ IN A 192.168.1.1 +" + +%extend ldns_struct_zone { + + %pythoncode %{ + def __init__(self): + self.this = _ldns.ldns_zone_new() + if not self.this: + raise Exception("Can't create zone.") + + __swig_destroy__ = _ldns._ldns_zone_free + + def __str__(self): + return str(self.soa()) + "\n" + str(self.rrs()) + + def print_to_file(self,output): + """Prints the data in the zone to the given file stream (in presentation format).""" + _ldns.ldns_zone_print(output,self) + #parameters: FILE *,const ldns_zone *, + + #LDNS_ZONE_CONSTRUCTORS_# + @staticmethod + def new_frm_fp(file, origin, ttl, rr_class=_ldns.LDNS_RR_CLASS_IN, raiseException=True): + """Creates a new zone object from given file pointer + + :param file: a file object + :param origin: (ldns_rdf) the zones' origin + :param ttl: default ttl to use + :param rr_class: efault class to use (IN) + :param raiseException: if True, an exception occurs in case a zone instance can't be created + :returns: zone instance or None. If an instance can't be created and raiseException is True, an exception occurs. + """ + status, zone = _ldns.ldns_zone_new_frm_fp(file, origin, ttl, rr_class) + if status != LDNS_STATUS_OK: + if (raiseException): raise Exception("Can't create zone, error: %s (%d)" % (_ldns.ldns_get_errorstr_by_id(status),status)) + return None + return zone + + @staticmethod + def new_frm_fp_l(file, origin, ttl, rr_class, raiseException=True): + """Create a new zone from a file, keep track of the line numbering + + :param file: a file object + :param origin: (ldns_rdf) the zones' origin + :param ttl: default ttl to use + :param rr_class: efault class to use (IN) + :param raiseException: if True, an exception occurs in case a zone instance can't be created + :returns: + * zone - zone instance or None. If an instance can't be created and raiseException is True, an exception occurs. + + * line - used for error msg, to get to the line number + """ + status, zone = _ldns.ldns_zone_new_frm_fp_l(file, line) + if status != LDNS_STATUS_OK: + if (raiseException): raise Exception("Can't create zone, error: %d" % status) + return None + return zone + #_LDNS_ZONE_CONSTRUCTORS# + + def sign(self,key_list): + """Signs the zone, and returns a newly allocated signed zone. + + :param key_list: + list of keys to sign with + :returns: (ldns_zone \*) signed zone + """ + return _ldns.ldns_zone_sign(self,key_list) + #parameters: const ldns_zone *,ldns_key_list *, + #retvals: ldns_zone * + + def sign_nsec3(self,key_list,algorithm,flags,iterations,salt_length,salt): + """Signs the zone with NSEC3, and returns a newly allocated signed zone. + + :param key_list: + list of keys to sign with + :param algorithm: + the NSEC3 hashing algorithm to use + :param flags: + NSEC3 flags + :param iterations: + the number of NSEC3 hash iterations to use + :param salt_length: + the length (in octets) of the NSEC3 salt + :param salt: + the NSEC3 salt data + :returns: (ldns_zone \*) signed zone + """ + return _ldns.ldns_zone_sign_nsec3(self,key_list,algorithm,flags,iterations,salt_length,salt) + #parameters: ldns_zone *,ldns_key_list *,uint8_t,uint8_t,uint16_t,uint8_t,uint8_t *, + #retvals: ldns_zone * + + #LDNS_ZONE_METHODS_# + def glue_rr_list(self): + """Retrieve all resource records from the zone that are glue records. + + The resulting list does are pointer references to the zone's data. + + Due to the current zone implementation (as a list of rr's), this function is extremely slow. Another (probably better) way to do this is to use an ldns_dnssec_zone structure and the mark_glue function + + :returns: (ldns_rr_list \*) the rr_list with the glue + """ + return _ldns.ldns_zone_glue_rr_list(self) + #parameters: const ldns_zone *, + #retvals: ldns_rr_list * + + def push_rr(self,rr): + """push an single rr to a zone structure. + + This function use pointer copying, so the rr_list structure inside z is modified! + + :param rr: + the rr to add + :returns: (bool) a true on succes otherwise falsed + """ + return _ldns.ldns_zone_push_rr(self,rr) + #parameters: ldns_zone *,ldns_rr *, + #retvals: bool + + def push_rr_list(self,list): + """push an rrlist to a zone structure. + + This function use pointer copying, so the rr_list structure inside z is modified! + + :param list: + the list to add + :returns: (bool) a true on succes otherwise falsed + """ + return _ldns.ldns_zone_push_rr_list(self,list) + #parameters: ldns_zone *,ldns_rr_list *, + #retvals: bool + + def rr_count(self): + """Returns the number of resource records in the zone, NOT counting the SOA record. + + :returns: (size_t) the number of rr's in the zone + """ + return _ldns.ldns_zone_rr_count(self) + #parameters: const ldns_zone *, + #retvals: size_t + + def rrs(self): + """Get a list of a zone's content. + + Note that the SOA isn't included in this list. You need to get the with ldns_zone_soa. + + :returns: (ldns_rr_list \*) the rrs from this zone + """ + return _ldns.ldns_zone_rrs(self) + #parameters: const ldns_zone *, + #retvals: ldns_rr_list * + + def set_rrs(self,rrlist): + """Set the zone's contents. + + :param rrlist: + the rrlist to use + """ + _ldns.ldns_zone_set_rrs(self,rrlist) + #parameters: ldns_zone *,ldns_rr_list *, + #retvals: + + def set_soa(self,soa): + """Set the zone's soa record. + + :param soa: + the soa to set + """ + _ldns.ldns_zone_set_soa(self,soa) + #parameters: ldns_zone *,ldns_rr *, + #retvals: + + def soa(self): + """Return the soa record of a zone. + + :returns: (ldns_rr \*) the soa record in the zone + """ + return _ldns.ldns_zone_soa(self) + #parameters: const ldns_zone *, + #retvals: ldns_rr * + + def sort(self): + """Sort the rrs in a zone, with the current impl. + + this is slow + """ + _ldns.ldns_zone_sort(self) + #parameters: ldns_zone *, + #retvals: + + #_LDNS_ZONE_METHODS# + %} +} |
