fix: populate ldns submodule and add autotools to LDNS build stage

- Re-cloned zonemaster-ldns with --recurse-submodules so the bundled
  ldns C library source (including Changelog and configure.ac) is present
- Added autoconf, automake, libtool to Dockerfile.backend ldns-build stage
  so libtoolize + autoreconf can generate ldns/configure during make

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-21 08:33:38 +02:00
parent 8d4eaa1489
commit eaaa8f6a11
541 changed files with 138189 additions and 0 deletions

View File

@@ -0,0 +1,92 @@
1.6.17 2014-01-10
* Added ldns_rdf.data_as_bytearray(). The method returns a bytearray object
containing rdf data.
* Changed the behaviour of ldns_resolver.trusted_key() in order to prevent
memory corruption and leaks.
* Fixed memory leaks when destroying ldns_resolver.
* Removed ldns_pkt.section_count(), ldns_resolver.set_searchlist_count()
because it is marked static in the library.
* Added ldns_pkt.new(), ldns_resolver.new().
* Marked as returning new object ldns_pkt.get_section_clone(),
ldns_resolver.get_addr_by_name(), ldns_resolver.get_name_by_addr(),
ldns_resolver.search().
* Added push cloning for ldns_pkt.safe_push_rr(),
ldns_pkt.safe_push_rr_list(), ldns_pkt.set_additional(),
ldns_pkt.set_answer(), ldns_pkt.set_answerfrom(),
ldns_pkt.set_authority(), ldns_pkt.set_edns_data(),
ldns_pkt.set_question(), ldns_pkt.set_tsig(),
ldns_resolver.set_dnssec_anchors(), ldns_resolver.set_domain().
* Added pull cloning for ldns_pkt.answerfrom(), ldns_pkt.edns_data(),
ldns_pkt.tsig(), ldns_resolver.axfr_last_pkt(),
ldns_resolver.dnssec_anchors(), ldns_resolver.domain(),
ldns_resolver.tsig_algorithm(), ldns_resolver.tsig_keydata(),
ldns_resolver.tsig_keyname().
* Method ldns_rdf.reverse() now throws an exception when not applied
on dname rdfs. This is to prevent assertion fails in ldns' C code.
1.6.16 2012-11-13
* Fix typo in ldns_struct_pkt.opcode2str
1.6.14 2012-10-23
* Added rich comparison methods for ldns_dname, ldns_rdf, ldns_rr and
ldns_rr_list classes.
* Added deprecation warnings into ldns_rr.new_frm_fp() and
ldns_rr.new_frm_fp_l() and others.
* Fixed ldns_rr.set_rdf(), which may cause memory leaks, because it
returns new objects (in the scope of Python). Also it leaked memory,
when the call was not successful.
* Fixed ldns_get_rr_list_hosts_frm_file, marked as newobject.
* Fixed ldns_rr_list.cat() to return bool as mentioned in documentation.
* Fixed ldns_rr_list_cat_clone, marked as newobject.
* Fixed ldns_rr_list.new_frm_file(). Exception argument was invalid.
* Fixed ldns_rr_list.push_rr() to return bool as mentioned in
documentation.
* Fixed ldns_rr_list.push_rr_list() to return bool as mentioned in
documentation.
* Fixed ldns_rr_list.set_rr(), which caused memory corruption, double free
problems and memory leaks. (The wrapper used original function instead
of its push cloned variant which was missing.)
* Fixed ldns_rr_list.set_rr_count(), added python exception raise in order
to avoid assertion failure.
* Fixed ldns_rr_list.subtype_by_rdf(), marked as newobject.
* Added ldns_rr.to_canonical(), ldns_rr.is_question(),
ldns_rr.type_by_name(), ldns_rr.class_by_name(), ldns_rr_list.new(),
ldns_rr.set_question().
* Modified ldns_rr_list.owner() and ldns_rr.owner(), now returns ldns_dname.
* Fixed assertion failures for several methods when receiving incorrect but
syntactically valid arguments (i.e., ldns_rr.a_address(),
ldns_rr.dnskey_algorithm(), ldns_rr.dnskey_flags(),
ldns_rr.dnskey_key(), ldns_rr.dnskey_protocol(),
ldns_rr.mx_exchange(), ldns_rr.mx_preference(), ldns_rr.ns_nsdname(),
ldns_rr.owner(), ldns_rr.rdf(), ldns_rr.rrsig_algorithm(),
ldns_rr.rrsig_expiration(), ldns_rr.rrsig_inception(),
ldns_rr.rrsig_keytag(), ldns_rr.rrsig_labels(), ldns_rr.rrsig_origttl(),
ldns_rr.rrsig_sig(), ldns_rr.rrsig_signame(),
ldns_rr.rrsig_typecovered(), ldns_rr_list.owner(), ldns_rr_list.rr())
* Fixed ldns_rr.a_address(), which was asserting when called
on non A or AAAA type rr. Now returns None when fails.
* Added scripts for testing the basic functionality of the ldns_rr,
ldns_rr_descriptor and ldns_rr_list class code.
* Improved documentation of ldns_rr, ldns_rr_descriptor and ldns_rr_list.
* Fixed automatic conversion from Python string to ldns_rdf and
ldns_dname. Caused memory corruption when using Python 3.
* The Python 3 wrapper code now raises TypeError instead of ValueError
when receiving a non FILE * argument when it should be a FILE *.
* Fixed wrong handling of _ldns_rr_list_free() and
_ldns_rr_list_deep_free() when compiling with LDNS_DEBUG directive.
* Fixed malfunctioning ldns.ldns_rdf_new_frm_fp_l().
* Fixed malfunctioning ldns_drf.absolute() and ldns_dname.absolute().
* Marked several functions related to ldns_rdf and ldns_buffer as
returning new objects.
* Method operating on ldns_dnames and returning dname ldns_rdfs now
return ldns_dname instances.
* Improved documentation of ldns_buffer, ldns_rdf and ldns_dname
classes.
* Methods ldns_buffer.available() and ldns_buffer.available_at() now
return bool types as described in the documentation.
* Added scripts for testing the basic functionality of the ldns_buffer,
ldns_rdf, ldns_dname class code.
* Added deprecation warnings to ldns_rdf methods operating on dname
rdfs. The user is encouraged to converts dname ldns_rdfs to
ldns_dnames.
* Extended ldns_dname constructor to accept ldns_rdfs containing dnames.

View File

@@ -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.

View File

@@ -0,0 +1,110 @@
# 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.
.PHONY: help clean testenv test doc te bw bw3 sw sw3
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " testenv to make test environment and run bash "
@echo " useful 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/libldns.so.1: ../../Makefile
$(MAKE) -C ../..
clean:
rm -rf examples/ldns
rm -f _ldns.so ldns_wrapper.o
$(MAKE) -C ../.. clean
testenv: ../../.libs/libldns.so.1 _ldns.so
rm -rf examples/ldns
cd examples && mkdir ldns && ln -s ../../ldns.py ldns/__init__.py && ln -s ../../../../.libs/_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 -rf examples/ldns
test: ../../.libs/libldns.so.1 _ldns.so examples/test_buffer.py examples/test_rdf.py examples/test_dname.py examples/test_rr.py examples/test_pkt.py examples/test_resolver.py
@rm -rf examples/ldns
@cd examples && mkdir ldns && ln -s ../../ldns.py ldns/__init__.py && ln -s ../../../../.libs/_ldns.so ldns/_ldns.so && ln -s ../../../../.libs/libldns.so.1 ldns/libldns.so.1
@cd examples && LD_LIBRARY_PATH=ldns ./test_buffer.py 2>/dev/null
@cd examples && LD_LIBRARY_PATH=ldns ./test_rdf.py 2>/dev/null
@cd examples && LD_LIBRARY_PATH=ldns ./test_dname.py 2>/dev/null
@cd examples && LD_LIBRARY_PATH=ldns ./test_rr.py 2>/dev/null
@cd examples && LD_LIBRARY_PATH=ldns ./test_pkt.py 2>/dev/null
@cd examples && LD_LIBRARY_PATH=ldns ./test_resolver.py 2>/dev/null
@rm -rf examples/ldns
doc: ../../.libs/libldns.so.1 _ldns.so
echo @VERSION_MAJOR@
rm -f _ldns.so
ln -s ../../.libs/_ldns.so
$(MAKE) -C docs html
rm -f _ldns.so
# For development only:
# Test environment, does not build the wrapper from dependencies.
te:
rm -rf examples/ldns
cd examples && mkdir ldns && ln -s ../../ldns.py ldns/__init__.py && ln -s ../../../../.libs/_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 -rf examples/ldns
# Builds Python 2 wrapper from present wrapper C code.
bw:
gcc -c ldns_wrapper.c -O9 -fPIC -I../.. -I../../ldns -I/usr/include/python2.7 -I. -o ldns_wrapper.o
mkdir -p ../../.libs
ld -shared ldns_wrapper.o -L../../.libs -lldns -o ../../.libs/_ldns.so
# Builds Python 3 wrapper from present wrapper C code.
bw3:
gcc -c ldns_wrapper.c -O9 -fPIC -I../.. -I../../ldns -I/usr/include/python3.2 -I. -o ldns_wrapper.o
mkdir -p ../../.libs
ld -shared ldns_wrapper.o -L../../.libs -ldns -o ../../.libs/_ldns.so
# Builds Python 2 wrapper from interface file.
sw: ldns.i
swig -python -o ldns_wrapper.c -I../.. ldns.i
$(MAKE) bw
# Builds Python 3 wrapper from interface file.
sw3: ldns.i
swig -python -py3 -DPY3 -o ldns_wrapper.c -I../.. ldns.i
$(MAKE) bw3

View File

@@ -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."

View File

@@ -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-2013, 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.6'
# The full version, including alpha/beta/rc tags.
release = '1.6.17'
# 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

View File

@@ -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 simpler 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

View File

@@ -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")

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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 read and parsed. This can be done using :class:`ldns.ldns_zone` class.
2. In the second step, the private and public key is read and public key is inserted into zone (as DNSKEY).
3. In the last step, the DNSSEC zone instance 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 successful, the content of DNSSEC zone is written to a file.

View File

@@ -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*

View File

@@ -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`

View File

@@ -0,0 +1,72 @@
Installation
===================================
**Prerequisites**
SWIG 1.3 and GNU make are required to build modules for Python 2.4 and higher
(but lower than 3). In order to build modules for Python 3.2 or higher,
SWIG in version 2.0.4 or higher is required.
Note that Python 3.0 and 3.1 are not supported.
In order to build this documentation the Sphinx Python documentation generator
is required.
**Download**
The latest source codes can be downloaded from `here`_.
.. _here: http://nlnetlabs.nl/projects/ldns/
**Compiling**
After downloading the source code archive (this example uses
ldns-1.6.13.tar.gz), pyLDNS can be enabled and compiled by typing::
> tar -xzf ldns-1.6.13.tar.gz
> cd ldns-1.6.13
> ./configure --with-pyldns
> make
You need GNU make to compile pyLDNS; SWIG and Python development libraries to
compile the extension module.
**Selecting Target Python Interpreter**
By default, the pyLDNS module builds for the default Python interpreter (i.e.,
the Python interpreter which can be accessed by just typing ``python`` in
the command line). If you desire to build the pyLDNS module for a different
Python version then you must specify the desired Python version by setting
the ``PYTHON_VERSION`` variable during the configure phase::
> PYTHON_VERSION=3.2 ./configure --with-pyldns
> make
By default the pyLDNS compiles from sources for a single Python interpreter.
Remember to execute scripts requiring pyLDNS in those Python interpreters which
have pyLDNS installed.
**Testing**
If the compilation is successful, you can test the python LDNS extension module
by executing the commands::
> cd contrib/python
> make testenv
> ./ldns-mx.py
Again, remember to use the Python interpreter version which the pyLDNS module
has been compiled with.
The commands will start a new shell, in which several symbolic links will be
set-up. When you exit the shell, then symbolic links will be deleted.
In ``contrib/python/examples`` several simple Python scripts utilising pyLDNS
can be found. These scripts demonstrate the capabilities of the LDNS library.
**Installation**
To install the libraries and it's extensions type::
> cd ldns-1.6.13
> make install

View File

@@ -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`).

View File

@@ -0,0 +1,11 @@
Class ldns_buffer
================================
.. automodule:: ldns
Class ldns_buffer
------------------------------
.. autoclass:: ldns_buffer
:members:
:undoc-members:

View File

@@ -0,0 +1,11 @@
Class ldns_dname
================================
.. automodule:: ldns
Class ldns_dname
------------------------------
.. autoclass:: ldns_dname
:members:
:undoc-members:

View File

@@ -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:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
Class ldns_key
================================
.. automodule:: ldns
Class ldns_key
------------------------------
.. autoclass:: ldns_key
:members:
:undoc-members:

View File

@@ -0,0 +1,11 @@
Class ldns_key_list
================================
.. automodule:: ldns
Class ldns_key_list
------------------------------
.. autoclass:: ldns_key_list
:members:
:undoc-members:

View File

@@ -0,0 +1,11 @@
Class ldns_pkt
================================
.. automodule:: ldns
Class ldns_pkt
------------------------------
.. autoclass:: ldns_pkt
:members:
:undoc-members:

View File

@@ -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_HIP,
* 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

View File

@@ -0,0 +1,13 @@
Class ldns_resolver
================================
.. automodule:: ldns
Class ldns_resolver
------------------------------
.. autoclass:: ldns_resolver
:members:
:undoc-members:

View File

@@ -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:

View File

@@ -0,0 +1,11 @@
Class ldns_rr_list
================================
.. automodule:: ldns
Class ldns_rr_list
------------------------------
.. autoclass:: ldns_rr_list
:members:
:undoc-members:

View File

@@ -0,0 +1,11 @@
Class ldns_zone
================================
.. automodule:: ldns
Class ldns_zone
------------------------------
.. autoclass:: ldns_zone
:members:
:undoc-members:

View File

@@ -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

View File

@@ -0,0 +1,8 @@
#!/usr/bin/python
import ldns
buf = ldns.ldns_buffer(1024)
buf.printf("Test buffer")
print buf

View File

@@ -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"

View File

@@ -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

View File

@@ -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/urandom","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)

View File

@@ -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

View File

@@ -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

View File

@@ -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())

View File

@@ -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

View File

@@ -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"))

View File

@@ -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

View File

@@ -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()

View File

@@ -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

View File

@@ -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()

View File

@@ -0,0 +1,8 @@
#!/usr/bin/python
import ldns
buf = ldns.ldns_buffer(1024)
buf.printf("Test buffer")
print(buf)

View File

@@ -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")

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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()))

View File

@@ -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)

View File

@@ -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), end=" ")
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"))

View File

@@ -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

View File

@@ -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()

View File

@@ -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)

View File

@@ -0,0 +1,843 @@
#!/usr/bin/env python
#
# ldns_buffer testing script.
#
# Do not use constructs that differ between Python 2 and 3.
# Use write on stdout or stderr.
#
import ldns
import sys
import os
import inspect
class_name = "ldns_buffer"
method_name = None
error_detected = False
def set_error():
"""
Writes an error message and sets error flag.
"""
global class_name
global method_name
global error_detected
error_detected = True
sys.stderr.write("(line %d): malfunctioning method %s.\n" % \
(inspect.currentframe().f_back.f_lineno, method_name))
# Buffer creation.
capacity = 1024
#if not error_detected:
if True:
method_name = "ldns_buffer.__init__()"
try:
buf = ldns.ldns_buffer(1024)
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_buffer.__str__()"
buf.printf("abcedf")
try:
string = buf.__str__()
except:
set_error()
if not isinstance(string, str):
# Should be string.
set_error()
buf.clear()
#if not error_detected:
if True:
method_name = "ldns_buffer.at()"
try:
ret = buf.at(512)
except:
set_error()
try:
# Must raise TypeError.
ret = buf.at("")
set_error()
except TypeError:
pass
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_buffer.available()"
try:
ret = buf.available(capacity)
except:
set_error()
if not isinstance(ret, bool):
# Should be bool.
set_error()
if not buf.available(capacity):
# Should return True.
set_error()
if buf.available(capacity + 1):
# Should return False.
set_error()
try:
# Must raise TypeError.
ret = buf.available("")
set_error()
except TypeError:
pass
except:
set_error()
# try:
# # Must raise ValueError.
# ret = buf.available("")
# set_error()
# except ValueError:
# pass
# except:
# set_error()
#if not error_detected:
if True:
method_name = "ldns_buffer.available_at()"
try:
ret = buf.available_at(512, capacity - 512)
except:
set_error()
if not isinstance(ret, bool):
# Should be bool.
set_error()
if not buf.available_at(512, capacity - 512):
# Should return True.
set_error()
if buf.available_at(512, capacity - 512 + 1):
# Should return False.
set_error()
try:
# Must raise TypeError.
ret = buf.available_at("", 1)
set_error()
except TypeError:
pass
except:
set_error()
try:
# Must raise TypeError.
ret = buf.available_at(1, "")
set_error()
except TypeError:
pass
except:
set_error()
# try:
# # Must raise ValueError.
# ret = buf.available_at(-1, 512)
# set_error()
# except ValueError:
# pass
# except:
# set_error()
# try:
# # Must raise ValueError.
# ret = buf.available_at(512, -1)
# set_error()
# except ValueError:
# pass
# except:
# set_error()
#if not error_detected:
if True:
method_name = "ldns_buffer.begin()"
try:
ret = buf.begin()
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_buffer.capacity()"
try:
ret = buf.capacity()
except:
set_error()
if (not isinstance(ret, int)) and (not isinstance(ret, long)):
# Should be int.
set_error()
#if not error_detected:
if True:
method_name = "ldns_buffer.clear()"
try:
buf.clear()
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_buffer.copy()"
sys.stderr.write("%s not tested.\n" % (method_name))
# buf2 = ldns.ldns_buffer(10)
# buf2.printf("abcdef")
# try:
# buf.copy(buf2)
# print buf.capacity()
# print buf2.capacity()
# except:
# set_error()
# buf.printf("2")
# print buf
#if not error_detected:
if True:
method_name = "ldns_buffer.current()"
try:
ret = buf.current()
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_buffer.end()"
try:
ret = buf.end()
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_buffer.export()"
sys.stderr.write("%s not tested.\n" % (method_name))
#if not error_detected:
if True:
method_name = "ldns_buffer.flip()"
buf.printf("abcdef")
try:
buf.flip()
except:
set_error()
# if buf.remaining() != capacity:
# # Should be at beginning.
# set_error()
buf.clear()
#if not error_detected:
if True:
method_name = "ldns_buffer.getc()"
buf.printf("a")
buf.rewind()
try:
ret = buf.getc()
except:
set_error()
if ret != ord("a"):
set_error()
# Test return value for -1
buf.clear()
#if not error_detected:
if True:
method_name = "ldns_buffer.invariant()"
try:
buf.invariant()
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_buffer.limit()"
try:
ret = buf.limit()
except:
set_error()
if ret != capacity:
set_error()
#if not error_detected:
if True:
method_name = "ldns_buffer.position()"
try:
ret = buf.position()
except:
set_error()
if (not isinstance(ret, int)) and (not isinstance(ret, long)):
set_error()
#if not error_detected:
if True:
method_name = "ldns_buffer.printf()"
try:
ret = buf.printf("abcdef")
except:
set_error()
if not isinstance(ret, int):
set_error()
try:
ret = buf.printf(10)
set_error()
except TypeError:
pass
except:
set_error()
buf.clear()
#if not error_detected:
if True:
method_name = "ldns_buffer.read()"
sys.stderr.write("%s not tested.\n" % (method_name))
#if not error_detected:
if True:
method_name = "ldns_buffer.read_at()"
sys.stderr.write("%s not tested.\n" % (method_name))
#if not error_detected:
if True:
method_name = "ldns_buffer.read_u16()"
buf.printf("aac")
buf.rewind()
try:
ret = buf.read_u16()
except:
set_error()
if (not isinstance(ret, int)) and (not isinstance(ret, long)):
set_error()
if ret != (ord("a") * 0x0101):
set_error()
buf.clear()
#if not error_detected:
if True:
method_name = "ldns_buffer.read_u16_at()"
buf.printf("abbc")
try:
ret = buf.read_u16_at(1)
except:
set_error()
if (not isinstance(ret, int)) and (not isinstance(ret, long)):
set_error()
if ret != (ord("b") * 0x0101):
set_error()
try:
ret = buf.read_u16_at("")
set_error()
except TypeError:
pass
except:
set_error()
# try:
# ret = buf.read_u16_at(-1)
# set_error()
# except ValueError:
# pass
# except:
# set_error()
buf.clear()
#if not error_detected:
if True:
method_name = "ldns_buffer.read_u32()"
buf.printf("aaaac")
buf.rewind()
try:
ret = buf.read_u32()
except:
set_error()
if not isinstance(ret, int):
set_error()
if ret != (ord("a") * 0x01010101):
set_error()
buf.clear()
#if not error_detected:
if True:
method_name = "ldns_buffer.read_u32_at()"
buf.printf("abbbbc")
try:
ret = buf.read_u32_at(1)
except:
set_error()
if not isinstance(ret, int):
set_error()
if ret != (ord("b") * 0x01010101):
set_error()
try:
ret = buf.read_u32_at("")
set_error()
except TypeError:
pass
except:
set_error()
# try:
# ret = buf.read_u32_at(-1)
# set_error()
# except ValueError:
# pass
# except:
# set_error()
buf.clear()
#if not error_detected:
if True:
method_name = "ldns_buffer.read_u8()"
buf.printf("ac")
buf.rewind()
try:
ret = buf.read_u8()
except:
set_error()
if (not isinstance(ret, int)) and (not isinstance(ret, long)):
set_error()
if ret != ord("a"):
set_error()
buf.clear()
#if not error_detected:
if True:
method_name = "ldns_buffer.read_u8_at()"
buf.printf("abc")
try:
ret = buf.read_u8_at(1)
except:
set_error()
if (not isinstance(ret, int)) and (not isinstance(ret, long)):
set_error()
if ret != ord("b"):
set_error()
try:
ret = buf.read_u8_at("")
set_error()
except TypeError:
pass
except:
set_error()
# try:
# ret = buf.read_u8_at(-1)
# set_error()
# except ValueError:
# pass
# except:
# set_error()
buf.clear()
#if not error_detected:
if True:
method_name = "ldns_buffer.remaining()"
buf.printf("abcdef")
try:
ret = buf.remaining()
except:
set_error()
if (not isinstance(ret, int)) and (not isinstance(ret, long)):
set_error()
if ret != (capacity - 6):
set_error()
buf.clear()
#if not error_detected:
if True:
method_name = "ldns_buffer.remaining_at()"
buf.printf("abcdef")
try:
ret = buf.remaining_at(1)
except:
set_error()
if (not isinstance(ret, int)) and (not isinstance(ret, long)):
set_error()
if ret != (capacity - 1):
set_error()
try:
ret = buf.remaining_at("")
set_error()
except TypeError:
pass
except:
set_error()
# try:
# ret = buf.remaining_at(-1)
# set_error()
# except ValueError:
# pass
# except:
# set_error()
buf.clear()
#if not error_detected:
if True:
method_name = "ldns_buffer.reserve()"
buf2 = ldns.ldns_buffer(512)
try:
ret = buf2.reserve(1024)
except:
set_error()
if not isinstance(ret, bool):
set_error()
try:
ret = buf2.reserve("")
set_error()
except TypeError:
pass
except:
set_error()
# try:
# ret = buf2.reserve(-1)
# set_error()
# except ValueError:
# pass
# except:
# set_error()
#if not error_detected:
if True:
method_name = "ldns_buffer.rewind()"
buf.printf("abcdef")
try:
buf.rewind()
except:
set_error()
if buf.position() != 0:
set_error()
buf.clear()
#if not error_detected:
if True:
method_name = "ldns_buffer.set_capacity()"
try:
ret = buf.set_capacity(capacity)
except:
set_error()
if not isinstance(ret, bool):
set_error()
try:
ret = buf.set_capacity("")
set_error()
except TypeError:
pass
except:
set_error()
# try:
# ret = buf.set_capacity(-1)
# set_error()
# except ValueError:
# pass
# except:
# set_error()
buf.clear()
#if not error_detected:
if True:
method_name = "ldns_buffer.set_limit()"
try:
buf.set_limit(0)
except:
set_error()
try:
buf.set_limit("")
set_error()
except TypeError:
pass
except:
set_error()
# try:
# buf.set_limit(-1)
# set_error()
# except ValueError:
# pass
# except:
# set_error()
buf.clear()
#if not error_detected:
if True:
method_name = "ldns_buffer.set_position()"
try:
buf.set_position(0)
except:
set_error()
try:
buf.set_position("")
except TypeError:
pass
except:
set_error()
# try:
# buf.set_position(-1)
# except ValueError:
# pass
# except:
# set_error()
buf.clear()
#if not error_detected:
if True:
method_name = "ldns_buffer.skip()"
try:
buf.skip(10)
except:
set_error()
try:
buf.skip(-1)
except:
set_error()
try:
buf.skip("")
set_error()
except TypeError:
pass
except:
set_error()
buf.clear()
#if not error_detected:
if True:
method_name = "ldns_buffer.status()"
try:
ret = buf.status()
except:
set_error()
# Returned status is an integer.
if not isinstance(ret, int):
set_error()
buf.clear()
#if not error_detected:
if True:
method_name = "ldns_buffer.status_ok()"
try:
ret = buf.status_ok()
except:
set_error()
if not isinstance(ret, bool):
set_error()
buf.clear()
#if not error_detected:
if True:
method_name = "ldns_buffer.write()"
sys.stderr.write("%s not tested.\n" % (method_name))
#if not error_detected:
if True:
method_name = "ldns_buffer.write_at()"
sys.stderr.write("%s not tested.\n" % (method_name))
#if not error_detected:
if True:
method_name = "ldns_buffer.write_string()"
try:
buf.write_string("abcdef")
except:
set_error()
# try:
# buf.write_sring(-1)
# set_error()
# except TypeError:
# pass
# except:
# set_error()
sys.stderr.write("%s not tested for parameter correctness.\n" % \
(method_name))
buf.clear()
#if not error_detected:
if True:
method_name = "ldns_buffer.write_string_at()"
sys.stderr.write("%s not tested.\n" % (method_name))
#if not error_detected:
if True:
method_name = "ldns_buffer.write_u16()"
try:
buf.write_u16(ord("b") * 0x0101)
except:
set_error()
try:
buf.write_u16("")
set_error()
except TypeError:
pass
except:
set_error()
buf.clear()
#if not error_detected:
if True:
method_name = "ldns_buffer.write_u16_at()"
buf.printf("a")
try:
buf.write_u16_at(1, ord("b") * 0x0101)
except:
set_error()
try:
buf.write_u16_at("", ord("b") * 0x0101)
set_error()
except TypeError:
pass
except:
set_error()
# try:
# buf.write_u16_at(-1, ord("b") * 0x0101)
# set_error()
# except ValueError:
# pass
# except:
# set_error()
try:
buf.write_u16_at(1, "")
set_error()
except TypeError:
pass
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_buffer.write_u32()"
try:
buf.write_u32(ord("b") * 0x01010101)
except:
set_error()
try:
buf.write_u32("")
set_error()
except TypeError:
pass
except:
set_error()
buf.clear()
#if not error_detected:
if True:
method_name = "ldns_buffer.write_u32_at()"
buf.printf("a")
try:
buf.write_u32_at(1, ord("b") * 0x01010101)
except:
set_error()
try:
buf.write_u32_at("", ord("b") * 0x01010101)
set_error()
except TypeError:
pass
except:
set_error()
# try:
# buf.write_u32_at(-1, ord("b") * 0x01010101)
# set_error()
# except ValueError:
# pass
# except:
# set_error()
try:
buf.write_u32_at(1, "")
set_error()
except TypeError:
pass
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_buffer.write_u8()"
try:
buf.write_u8(ord("b"))
except:
set_error()
try:
buf.write_u8("")
set_error()
except TypeError:
pass
except:
set_error()
buf.clear()
#if not error_detected:
if True:
method_name = "ldns_buffer.write_u8_at()"
buf.printf("a")
try:
buf.write_u8_at(1, ord("b"))
except:
set_error()
try:
buf.write_u8_at("", ord("b"))
set_error()
except TypeError:
pass
except:
set_error()
# try:
# buf.write_u8_at(-1, ord("b"))
# set_error()
# except ValueError:
# pass
# except:
# set_error()
try:
buf.write_u8_at(1, "")
set_error()
except TypeError:
pass
except:
set_error()
if not error_detected:
sys.stdout.write("%s: passed.\n" % (os.path.basename(__file__)))
else:
sys.stdout.write("%s: errors detected.\n" % (os.path.basename(__file__)))
sys.exit(1)

View File

@@ -0,0 +1,474 @@
#!/usr/bin/env python
#
# ldns_dname testing script.
#
# Do not use constructs that differ between Python 2 and 3.
# Use write on stdout or stderr.
#
import ldns
import sys
import os
import inspect
class_name = "ldns_dname"
method_name = None
error_detected = False
temp_fname = "tmp_dname.txt"
def set_error():
"""
Writes an error message and sets error flag.
"""
global class_name
global method_name
global error_detected
error_detected = True
sys.stderr.write("(line %d): malfunctioning method %s.\n" % \
(inspect.currentframe().f_back.f_lineno, method_name))
#if not error_detected:
if True:
method_name = class_name + ".__init__()"
rdf1 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "test.nic.cz.")
rdf2 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_A, "217.31.205.50")
try:
dname = ldns.ldns_dname("www.nic.cz.")
if not isinstance(dname, ldns.ldns_dname):
set_error()
except:
set_error()
#
# Error when printing a dname which was created from an empty string.
# Must find out why.
#
try:
dname = ldns.ldns_dname(rdf1)
if not isinstance(dname, ldns.ldns_dname):
set_error()
except:
set_error()
# Test whether rdf1 and dname independent.
dname.cat(dname)
if dname.__str__() == rdf1.__str__():
set_error()
# Test whether rdf1 and dname are dependent.
dname = ldns.ldns_dname(rdf1, clone=False)
dname.cat(dname)
if dname.__str__() != rdf1.__str__():
set_error()
# Test whether constructs from non-dname rdfs.
try:
dname = ldns.ldns_dname(rdf2)
set_error()
except TypeError:
pass
except:
set_error()
try:
dname = ldns.ldns_dname(1)
set_error()
except TypeError:
pass
except:
set_error()
#if not error_detected:
if True:
method_name = class_name + ".[comparison operators]"
dn1 = ldns.ldns_dname("a.test")
dn2 = ldns.ldns_dname("b.test")
try:
ret = dn1 < dn2
if not isinstance(ret, bool):
set_error()
if ret != True:
set_error()
except:
set_error()
try:
ret = dn2 < dn1
if not isinstance(ret, bool):
set_error()
if ret != False:
set_error()
except:
set_error()
try:
ret = dn1 <= dn2
if not isinstance(ret, bool):
set_error()
if ret != True:
set_error()
except:
set_error()
try:
ret = dn2 <= dn1
if not isinstance(ret, bool):
set_error()
if ret != False:
set_error()
except:
set_error()
try:
ret = dn1 == dn2
if not isinstance(ret, bool):
set_error()
if ret != False:
set_error()
except:
set_error()
try:
ret = dn1 == dn1
if not isinstance(ret, bool):
set_error()
if ret != True:
set_error()
except:
set_error()
try:
ret = dn1 != dn2
if not isinstance(ret, bool):
set_error()
if ret != True:
set_error()
except:
set_error()
try:
ret = dn1 != dn1
if not isinstance(ret, bool):
set_error()
if ret != False:
set_error()
except:
set_error()
try:
ret = dn1 > dn2
if not isinstance(ret, bool):
set_error()
if ret != False:
set_error()
except:
set_error()
try:
ret = dn2 > dn1
if not isinstance(ret, bool):
set_error()
if ret != True:
set_error()
except:
set_error()
try:
ret = dn1 >= dn2
if not isinstance(ret, bool):
set_error()
if ret != False:
set_error()
except:
set_error()
try:
ret = dn2 >= dn1
if not isinstance(ret, bool):
set_error()
if ret != True:
set_error()
except:
set_error()
#if not error_detected:
if True:
method_name = class_name + ".absolute()"
dname = ldns.ldns_dname("www.nic.cz.")
try:
ret = dname.absolute()
if not isinstance(ret, bool):
set_error()
if ret != True:
set_error()
except:
set_error()
#if not error_detected:
if True:
method_name = class_name + ".cat()"
rdf1 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "test.nic.cz.")
rdf2 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_A, "217.31.205.50")
dname = ldns.ldns_dname("www.nic.cz.")
try:
ret = dname.cat(dname)
if ret != ldns.LDNS_STATUS_OK:
set_error()
if dname.__str__() != "www.nic.cz.www.nic.cz.":
set_error()
except:
set_error()
try:
ret = dname.cat(rdf1)
if ret != ldns.LDNS_STATUS_OK:
set_error()
if dname.__str__() != "www.nic.cz.www.nic.cz.test.nic.cz.":
set_error()
except:
set_error()
try:
ret = dname.cat(rdf2)
if ret == ldns.LDNS_STATUS_OK:
set_error()
except:
set_error()
try:
ret = dname.cat("")
set_error()
except TypeError:
pass
except:
set_error()
#if not error_detected:
if True:
method_name = class_name + ".cat_clone()"
rdf1 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "test.nic.cz.")
rdf2 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_A, "217.31.205.50")
dname = ldns.ldns_dname("www.nic.cz.")
try:
ret = dname.cat_clone(dname)
if not isinstance(ret, ldns.ldns_dname):
set_error()
if ret.__str__() != "www.nic.cz.www.nic.cz.":
set_error()
except:
set_error()
try:
ret = dname.cat_clone(rdf1)
if not isinstance(ret, ldns.ldns_dname):
set_error()
if ret.__str__() != "www.nic.cz.test.nic.cz.":
set_error()
except:
set_error()
try:
ret = dname.cat_clone(rdf2)
if ret != None:
set_error()
except:
set_error()
try:
ret = dname.cat_clone("")
except TypeError:
pass
except:
set_error()
#if not error_detected:
if True:
method_name = class_name + ".interval()"
dn1 = ldns.ldns_dname("a.ns.nic.cz.")
dn2 = ldns.ldns_dname("b.ns.nic.cz.")
dn3 = ldns.ldns_dname("c.ns.nic.cz.")
try:
ret = dn1.interval(dn2, dn3)
if ret != -1:
set_error()
except:
set_error()
try:
ret = dn2.interval(dn1, dn3)
if ret != 1:
set_error()
except:
set_error()
rdf4 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "d.ns.nic.cz.")
rdf5 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_A, "194.0.12.1")
try:
ret = dn1.interval(dn2, rdf4)
if ret != -1:
set_error()
except:
set_error()
try:
ret = dn2.interval(dn1, rdf4)
if ret != 1:
set_error()
except:
set_error()
try:
ret = dn1.interval(dn2, rdf5)
set_error()
except Exception:
pass
except:
set_error()
try:
ret = dn1.interval(dn2, "")
set_error()
except TypeError:
pass
except:
set_error()
#if not error_detected:
if True:
method_name = class_name + ".is_subdomain()"
dn1 = ldns.ldns_dname("nic.cz.")
dn2 = ldns.ldns_dname("www.nic.cz.")
rdf3 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "www.nic.cz.")
try:
ret = dn1.is_subdomain(dn2)
if not isinstance(ret, bool):
set_error()
if ret == True:
set_error()
ret = dn2.is_subdomain(dn1)
if ret != True:
set_error()
except:
set_error()
try:
ret = dn1.is_subdomain(rdf3)
if not isinstance(ret, bool):
set_error()
if ret == True:
set_error()
except:
set_error()
rdf4 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_A, "194.0.12.1")
try:
ret = dn1.is_subdomain(rdf4)
if ret != False:
set_error()
except:
set_error()
try:
ret = dn1.is_subdomain("")
set_error()
except TypeError:
pass
except:
set_error()
#if not error_detected:
if True:
method_name = class_name + ".label()"
dn = ldns.ldns_dname("nic.cz.")
try:
ret = dn.label(0)
if not isinstance(ret, ldns.ldns_dname):
set_error()
except:
set_error()
try:
ret = dn.label(10)
if ret != None:
set_error()
except:
set_error()
try:
ret = dn.label("")
except TypeError:
pass
except:
set_error()
#if not error_detected:
if True:
method_name = class_name + ".label_count()"
dn = ldns.ldns_dname("www.nic.cz.")
try:
ret = dn.label_count()
if (not isinstance(ret, int)) and (not isinstance(ret, long)):
set_error()
if ret != 3:
set_error()
except:
set_error()
#if not error_detected:
if True:
method_name = class_name + ".left_chop()"
dn = ldns.ldns_dname("www.nic.cz.")
try:
ret = dn.left_chop()
if not isinstance(ret, ldns.ldns_dname):
set_error()
except:
set_error()
#if not error_detected:
if True:
method_name = class_name + ".make_canonical()"
dn = ldns.ldns_dname("WWW.NIC.CZ.")
try:
dn.make_canonical()
if dn.__str__() != "www.nic.cz.":
set_error()
except:
set_error()
#if not error_detected:
if True:
method_name = class_name + ".new_frm_rdf()"
# Tested via constructor call.
#if not error_detected:
if True:
method_name = class_name + ".new_frm_str()"
# Tested via constructor call.
#if not error_detected:
if True:
method_name = class_name + ".reverse()"
dn = ldns.ldns_dname("www.nic.cz.")
try:
ret = dn.reverse()
if not isinstance(ret, ldns.ldns_dname):
set_error()
if ret.__str__() != "cz.nic.www.":
set_error()
except:
set_error()
#if not error_detected:
if True:
method_name = class_name + ".write_to_buffer()"
dn = ldns.ldns_dname("www.nic.cz.")
buf = ldns.ldns_buffer(1024)
try:
ret = dn.write_to_buffer(buf)
if ret != ldns.LDNS_STATUS_OK:
set_error()
if buf.position() != 12:
set_error()
except:
set_error()
try:
ret = dn.write_to_buffer("")
except TypeError:
pass
except:
set_error()
if not error_detected:
sys.stdout.write("%s: passed.\n" % (os.path.basename(__file__)))
else:
sys.stdout.write("%s: errors detected.\n" % (os.path.basename(__file__)))
sys.exit(1)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,820 @@
#!/usr/bin/env python
#
# ldns_rdf testing script.
#
# Do not use constructs that differ between Python 2 and 3.
# Use write on stdout or stderr.
#
import ldns
import sys
import os
import inspect
class_name = "ldns_rdf"
method_name = None
error_detected = False
temp_fname = "tmp_rdf.txt"
def set_error():
"""
Writes an error message and sets error flag.
"""
global class_name
global method_name
global error_detected
error_detected = True
sys.stderr.write("(line %d): malfunctioning method %s.\n" % \
(inspect.currentframe().f_back.f_lineno, method_name))
#if not error_detected:
if True:
method_name = class_name + ".__init__()"
try:
# Should raise an Exception
rdf = ldns.ldns_rdf()
set_error()
except Exception as e:
pass
#if not error_detected:
if True:
method_name = class_name + ".[comparison operators]"
rdf1 = ldns.ldns_rdf.new_frm_str("0.0.0.0", ldns.LDNS_RDF_TYPE_A)
rdf2 = ldns.ldns_rdf.new_frm_str("1.1.1.1", ldns.LDNS_RDF_TYPE_A)
try:
ret = rdf1 < rdf2
if not isinstance(ret, bool):
set_error()
if ret != True:
set_error()
except:
set_error()
try:
ret = rdf2 < rdf1
if not isinstance(ret, bool):
set_error()
if ret != False:
set_error()
except:
set_error()
try:
ret = rdf1 <= rdf2
if not isinstance(ret, bool):
set_error()
if ret != True:
set_error()
except:
set_error()
try:
ret = rdf2 <= rdf1
if not isinstance(ret, bool):
set_error()
if ret != False:
set_error()
except:
set_error()
try:
ret = rdf1 == rdf2
if not isinstance(ret, bool):
set_error()
if ret != False:
set_error()
except:
set_error()
try:
ret = rdf1 == rdf1
if not isinstance(ret, bool):
set_error()
if ret != True:
set_error()
except:
set_error()
try:
ret = rdf1 != rdf2
if not isinstance(ret, bool):
set_error()
if ret != True:
set_error()
except:
set_error()
try:
ret = rdf1 != rdf1
if not isinstance(ret, bool):
set_error()
if ret != False:
set_error()
except:
set_error()
try:
ret = rdf1 > rdf2
if not isinstance(ret, bool):
set_error()
if ret != False:
set_error()
except:
set_error()
try:
ret = rdf2 > rdf1
if not isinstance(ret, bool):
set_error()
if ret != True:
set_error()
except:
set_error()
try:
ret = rdf1 >= rdf2
if not isinstance(ret, bool):
set_error()
if ret != False:
set_error()
except:
set_error()
try:
ret = rdf2 >= rdf1
if not isinstance(ret, bool):
set_error()
if ret != True:
set_error()
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_rdf_new()"
sys.stderr.write("%s not tested.\n" % (method_name))
#if not error_detected:
if True:
method_name = "ldns_rdf_new_frm_data()"
sys.stderr.write("%s not tested.\n" % (method_name))
#if not error_detected:
if True:
method_name = "ldns_rdf_new_frm_str()"
try:
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "www.nic.cz")
except:
set_error()
try:
rdf = ldns.ldns_rdf_new_frm_str("", "www.nic.cz")
et_error()
except TypeError:
pass
except:
set_error()
try:
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, 1)
except TypeError:
pass
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_rdf_new_frm_fp()"
f = open(temp_fname, "w")
f.write("217.31.205.50")
f.close()
f = open(temp_fname, "r")
try:
status, rdf = ldns.ldns_rdf_new_frm_fp(ldns.LDNS_RDF_TYPE_A, f)
if status != ldns.LDNS_STATUS_OK:
set_error()
if rdf == None:
set_error()
except:
set_error()
try:
# Reading past file end.
status, rdf = ldns.ldns_rdf_new_frm_fp(ldns.LDNS_RDF_TYPE_AAAA, f)
if status == ldns.LDNS_STATUS_OK:
set_error()
if rdf != None:
set_error()
except:
set_error()
f.close()
f = open(temp_fname, "r")
try:
status, rdf = ldns.ldns_rdf_new_frm_fp(ldns.LDNS_RDF_TYPE_AAAA, f)
if status != ldns.LDNS_STATUS_OK:
set_error()
if rdf != None:
set_error()
except:
set_error()
f.close()
os.remove(temp_fname)
try:
status, rdf = ldns.ldns_rdf_new_frm_fp("", f)
except TypeError:
pass
except:
set_error()
try:
status, rdf = ldns.ldns_rdf_new_frm_fp(ldns.LDNS_RDF_TYPE_AAAA, "")
except TypeError:
pass
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_rdf_new_frm_fp_l()"
f = open(temp_fname, "w")
f.write("217.31.205.50\n194.0.12.1")
f.close()
f = open(temp_fname, "r")
try:
status, rdf, line = ldns.ldns_rdf_new_frm_fp_l(ldns.LDNS_RDF_TYPE_A, f)
if status != ldns.LDNS_STATUS_OK:
set_error()
if rdf == None:
set_error()
except:
set_error()
try:
status, rdf, line = ldns.ldns_rdf_new_frm_fp_l(ldns.LDNS_RDF_TYPE_A, f)
if status != ldns.LDNS_STATUS_OK:
set_error()
if rdf == None:
set_error()
except:
set_error()
try:
# Reading past file end.
status, rdf, line = ldns.ldns_rdf_new_frm_fp_l(ldns.LDNS_RDF_TYPE_A, f)
if status == ldns.LDNS_STATUS_OK:
set_error()
if rdf != None:
set_error()
except:
set_error()
f.close()
os.remove(temp_fname)
try:
status, rdf = ldns.ldns_rdf_new_frm_fp_l("", f)
except TypeError:
pass
except:
set_error()
try:
status, rdf = ldns.ldns_rdf_new_frm_fp_l(ldns.LDNS_RDF_TYPE_AAAA, "")
except TypeError:
pass
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_drf.absolute()"
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "www.nic.cz.")
try:
ret = rdf.absolute()
if not isinstance(ret, bool):
set_error()
if not ret:
set_error()
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_rdf.address_reverse()"
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_A, "194.0.12.1")
try:
ret = rdf.address_reverse()
if ret == None:
set_error()
except:
set_error()
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_AAAA, "::1")
try:
ret = rdf.address_reverse()
if ret == None:
set_error()
except:
set_error()
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "www.nic.cz.")
try:
ret = rdf.address_reverse()
if ret != None:
set_error()
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_rdf.cat()"
rdf1 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "www.nic")
rdf2 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "cz.")
try:
ret = rdf1.cat(rdf2)
if ret != ldns.LDNS_STATUS_OK:
set_error()
except:
set_error()
rdf1 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "www.nic.")
rdf2 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_A, "127.0.0.1")
try:
ret = rdf1.cat(rdf2)
if ret == ldns.LDNS_STATUS_OK:
set_error()
except:
set_error()
try:
ret = rdf2.cat(rdf1)
if ret == ldns.LDNS_STATUS_OK:
set_error()
except:
set_error()
try:
ret = rdf2.cat("")
set_error()
except TypeError:
pass
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_rdf.cat_clone()"
rdf1 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "www.nic")
rdf2 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "cz.")
try:
ret = rdf1.cat_clone(rdf2)
if ret == None:
set_error()
except:
set_error()
rdf1 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "www.nic.")
rdf2 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_A, "127.0.0.1")
try:
ret = rdf1.cat_clone(rdf2)
if ret != None:
set_error()
except:
set_error()
try:
ret = rdf2.cat_clone(rdf1)
if ret != None:
set_error()
except:
set_error()
try:
ret = rdf2.cat_clone("")
set_error()
except TypeError:
pass
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_rdf.clone()"
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "www.nic.cz.")
try:
ret = rdf.clone()
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_rdf.data()"
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "www.nic.cz.")
try:
ret = rdf.data()
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_rdf.data_as_bytearray()"
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "www.nic.cz.")
try:
ret = rdf.data_as_bytearray()
if not isinstance(ret, bytearray):
set_error()
if len(ret) != 12:
set_error()
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_rdf.dname_compare()"
rdf1 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "www.nic.cz.")
rdf2 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "nic.cz.")
try:
ret = rdf1.dname_compare(rdf2)
if ret != 1:
set_error()
except:
set_error()
try:
ret = rdf2.dname_compare(rdf1)
if ret != -1:
set_error()
except:
set_error()
try:
ret = rdf1.dname_compare(rdf1)
if ret != 0:
set_error()
except:
set_error()
rdf1 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "www.nic.cz.")
rdf2 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_A, "127.0.0.1")
try:
ret = rdf1.dname_compare(rdf2)
set_error()
except Exception:
pass
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_rdf.dname_new_frm_str()"
try:
rdf = ldns.ldns_rdf.dname_new_frm_str("www.nic.cz.")
if rdf == None:
set_error()
except:
set_error()
try:
rdf = ldns.ldns_rdf.dname_new_frm_str("")
if rdf != None:
set_error()
except:
set_error()
try:
rdf = ldns.ldns_rdf.dname_new_frm_str(1)
set_error()
except TypeError:
pass
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_rdf.get_type()"
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "www.nic.cz.")
try:
ret = rdf.get_type()
if not isinstance(ret, int):
set_error()
if ret != ldns.LDNS_RDF_TYPE_DNAME:
set_error()
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_rdf.get_type_str()"
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "www.nic.cz.")
try:
ret = rdf.get_type_str()
if not isinstance(ret, str):
set_error()
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_rdf.interval()"
rdf1 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "a.ns.nic.cz.")
rdf2 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "b.ns.nic.cz.")
rdf3 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "c.ns.nic.cz.")
try:
ret = rdf1.interval(rdf2, rdf3)
if ret != -1:
set_error()
except:
set_error()
try:
ret = rdf2.interval(rdf1, rdf3)
if ret != 1:
set_error()
except:
set_error()
rdf1 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_A, "194.0.12.1")
rdf2 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "b.ns.nic.cz.")
rdf3 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "c.ns.nic.cz.")
try:
ret = rdf1.interval(rdf2, rdf3)
set_error()
except Exception:
pass
except:
set_error()
try:
ret = rdf2.interval("", rdf3)
set_error()
except TypeError:
pass
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_rdf.is_subdomain()"
rdf1 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "nic.cz.")
rdf2 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "www.nic.cz.")
try:
ret = rdf1.is_subdomain(rdf2)
if not isinstance(ret, bool):
set_error()
if ret == True:
set_error()
ret = rdf2.is_subdomain(rdf1)
if ret != True:
set_error()
except:
set_error()
rdf1 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_A, "194.0.12.1")
rdf2 = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "www.nic.cz.")
try:
ret = rdf1.is_subdomain(rdf2)
if ret != False:
set_error()
except:
set_error()
try:
ret = rdf2.is_subdomain(rdf1)
if ret != False:
set_error()
except:
set_error()
try:
ret = rdf2.is_subdomain("")
set_error()
except TypeError:
pass
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_rdf.label()"
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "www.nic.cz.")
try:
ret = rdf.label(0)
if not isinstance(ret, ldns.ldns_rdf):
set_error()
except:
set_error()
try:
ret = rdf.label(10)
if ret != None:
set_error()
except:
set_error()
try:
ret = rdf.label("")
except TypeError:
pass
except:
set_error()
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_A, "127.0.0.1")
try:
ret = rdf.label(0)
if ret != None:
set_error()
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_rdf.label_count()"
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "www.nic.cz.")
try:
ret = rdf.label_count()
if (not isinstance(ret, int)) and (not isinstance(ret, long)):
set_error()
if ret != 3:
set_error()
except:
set_error()
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_A, "127.0.0.1")
try:
ret = rdf.label_count()
if (not isinstance(ret, int)) and (not isinstance(ret, long)):
set_error()
if ret != 0:
set_error()
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_rdf.left_chop()"
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "www.nic.cz.")
try:
ret = rdf.left_chop()
if not isinstance(ret, ldns.ldns_rdf):
set_error()
except:
set_error()
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_A, "127.0.0.1")
try:
ret = rdf.left_chop()
if ret != None:
set_error()
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_rdf.make_canonical()"
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "WWW.NIC.CZ.")
try:
rdf.make_canonical()
if rdf.__str__() != "www.nic.cz.":
set_error()
except:
set_error()
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_A, "127.0.0.1")
try:
rdf.make_canonical()
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_rdf.new_frm_str()"
try:
rdf = ldns.ldns_rdf.new_frm_str("www.nic.cz.", ldns.LDNS_RDF_TYPE_DNAME)
except:
set_error()
try:
rdf = ldns.ldns_rdf.new_frm_str("www.nic.cz.", ldns.LDNS_RDF_TYPE_AAAA)
set_error()
except Exception:
pass
except:
set_error()
try:
rdf = ldns.ldns_rdf.new_frm_str("www.nic.cz.", ldns.LDNS_RDF_TYPE_AAAA, raiseException = False)
if rdf != None:
set_error()
except:
set_error()
try:
rdf = ldns.ldns_rdf.new_frm_str("", "www.nic.cz")
et_error()
except TypeError:
pass
except:
set_error()
try:
rdf = ldns.ldns_rdf.new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, 1)
except TypeError:
pass
except:
set_error()
#if not error_detected:
if True:
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_A, "127.0.0.1")
f = open(temp_fname, "w")
try:
rdf.print_to_file(f)
except:
set_error()
f.close()
f = open(temp_fname, "r")
if f.read() != "127.0.0.1":
set_error()
f.close()
os.remove(temp_fname)
#if not error_detected:
if True:
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "www.nic.cz.")
try:
ret = rdf.reverse()
if not isinstance(ret, ldns.ldns_rdf):
set_error()
if ret.__str__() != "cz.nic.www.":
set_error()
except:
set_error()
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_A, "127.0.0.1")
try:
ret = rdf.reverse()
set_error()
except Exception:
pass
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_rdf.set_data()"
sys.stderr.write("%s not tested.\n" % (method_name))
#if not error_detected:
if True:
method_name = "ldns_rdf.set_size()"
sys.stderr.write("%s not tested.\n" % (method_name))
#if not error_detected:
if True:
method_name = "ldns_rdf.set_type()"
sys.stderr.write("%s not tested.\n" % (method_name))
#if not error_detected:
if True:
method_name = "ldns_rdf.size()"
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "www.nic.cz.")
try:
ret = rdf.size()
if ret != 12:
set_error()
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_rdf.write_to_buffer()"
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "www.nic.cz.")
buf = ldns.ldns_buffer(1024)
try:
ret = rdf.write_to_buffer(buf)
if ret != ldns.LDNS_STATUS_OK:
set_error()
if buf.position() != 12:
set_error()
except:
set_error()
try:
ret = rdf.write_to_buffer("")
except TypeError:
pass
except:
set_error()
#if not error_detected:
if True:
method_name = "ldns_rdf.write_to_buffer_canonical()"
rdf = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_DNAME, "WWW.NIC.CZ.")
buf = ldns.ldns_buffer(1024)
try:
ret = rdf.write_to_buffer_canonical(buf)
if ret != ldns.LDNS_STATUS_OK:
set_error()
if buf.position() != 12:
set_error()
except:
set_error()
try:
ret = rdf.write_to_buffer_canonical("")
except TypeError:
pass
except:
set_error()
if not error_detected:
sys.stdout.write("%s: passed.\n" % (os.path.basename(__file__)))
else:
sys.stdout.write("%s: errors detected.\n" % (os.path.basename(__file__)))
sys.exit(1)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -0,0 +1,121 @@
/*
* 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) {
/* The generated wrapper function raises TypeError on mismatching types. */
SWIG_exception_fail(SWIG_TypeError, "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""'");
}
}

View File

@@ -0,0 +1,469 @@
/*
* 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"
/* ========================================================================= */
/* Preliminary Python code. */
/* ========================================================================= */
%pythoncode
%{
#
# Use and don't ignore DeprecationWarning and
# PendingDeprecationWarning.
#
import warnings
warnings.filterwarnings("module", category=DeprecationWarning)
warnings.filterwarnings("module", category=PendingDeprecationWarning)
%}
/* Tell SWIG how to handle ssize_t as input parameter. */
%typemap(in, noblock=1) (ssize_t)
{
int $1_res = 0;
long val;
$1_res = SWIG_AsVal_long($input, &val);
if (!SWIG_IsOK($1_res)) {
SWIG_exception_fail(SWIG_ArgError($1_res), "in method '"
"$symname" "', argument " "$argnum" " of type '"
"$type""'");
}
$1 = val;
}
%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;
%immutable ldns_tsig_credentials_struct::algorithm;
%immutable ldns_tsig_credentials_struct::keyname;
%immutable ldns_tsig_credentials_struct::keydata;
//*_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"
%include <ldns/rr.h>
%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/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_(FILE *fp, uint32_t default_ttl, ldns_rdf* origin, ldns_rdf* prev)
//returns tuple (status, ldns_rr, ttl, origin, prev)
{
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(pp_rr, fp, p_defttl, pp_origin, pp_prev);
PyObject* tuple;
tuple = PyTuple_New(5);
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(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_frm_fp_l_(FILE *fp, uint32_t default_ttl, ldns_rdf* origin, ldns_rdf* prev)
//returns tuple (status, ldns_rr, line, 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;
}
PyObject* ldns_pkt2wire_(const ldns_pkt *pkt)
//returns tuple (status, result)
{
PyObject *resultobj = 0;
uint8_t *arg1 = NULL;
size_t arg3;
ldns_status result;
PyObject* tuple;
result = (ldns_status)ldns_pkt2wire(&arg1,pkt,&arg3);
tuple = PyTuple_New(2);
PyTuple_SetItem(tuple, 0, SWIG_From_int(result));
if (result == LDNS_STATUS_OK)
PyTuple_SetItem(tuple, 1, SWIG_FromCharPtrAndSize((char *)arg1, arg3));
else {
Py_INCREF(Py_None);
PyTuple_SetItem(tuple, 1, Py_None);
}
LDNS_FREE(arg1);
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_pkt2wire(data):
return _ldns.ldns_pkt2wire_(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
%}

View File

@@ -0,0 +1,726 @@
/******************************************************************************
* 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.
*****************************************************************************/
/* ========================================================================= */
/* SWIG setting and definitions. */
/* ========================================================================= */
/* Creates a temporary instance of (ldns_buffer *). */
%typemap(in, numinputs=0, noblock=1) (ldns_buffer **)
{
ldns_buffer *$1_buf;
$1 = &$1_buf;
}
/* Result generation, appends (ldns_buffer *) after the result. */
%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));
}
/*
* Limit the number of arguments to 2 and deal with variable
* number of arguments in the Python way.
*/
%varargs(2, char *arg = NULL) ldns_buffer_printf;
%nodefaultctor ldns_struct_buffer; /* No default constructor. */
%nodefaultdtor ldns_struct_buffer; /* No default destructor. */
%newobject ldns_buffer_new;
%newobject ldns_dname_new_frm_data;
%delobject ldns_buffer_free;
%rename(ldns_buffer) ldns_struct_buffer;
%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;
%ignore ldns_buffer_new_frm_data;
/* ========================================================================= */
/* Debugging related code. */
/* ========================================================================= */
#ifdef LDNS_DEBUG
%rename(__ldns_buffer_free) ldns_buffer_free;
%inline
%{
/*!
* @brief Frees the buffer and print a message.
*/
void _ldns_buffer_free (ldns_buffer* b)
{
printf("******** LDNS_BUFFER free 0x%lX ************\n",
(long unsigned int) b);
ldns_buffer_free(b);
}
%}
#else /* !LDNS_DEBUG */
%rename(_ldns_buffer_free) ldns_buffer_free;
#endif /* LDNS_DEBUG */
/* ========================================================================= */
/* Added C code. */
/* ========================================================================= */
/* None. */
/* ========================================================================= */
/* Encapsulating Python code. */
/* ========================================================================= */
%feature("docstring") "LDNS buffer."
%extend ldns_struct_buffer {
%pythoncode
%{
def __init__(self, capacity):
"""
Creates a new buffer with the specified capacity.
:param capacity: Number of bytes to allocate for the buffer.
:type capacity: integer
:throws TypeError: When `capacity` of non-integer type.
:return: (:class:`ldns_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: string
"""
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().
:return: (integer) 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
:type at: positive integer
:throws TypeError: When `at` of non-integer type.
:return: (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 whether the buffer has count bytes available at
the current position.
:param count: How much is available.
:type count: integer
:throws TypeError: When `count` of non-integer type.
:return: (bool) True or False.
"""
return _ldns.ldns_buffer_available(self, count) != 0
#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 that
enough space is available!
:param at: Indicated position.
:type at: positive integer
:param count: How much is available.
:type count: positive integer
:throws TypeError: When `at` or `count` of non-integer type.
:return: (bool) True or False.
"""
return _ldns.ldns_buffer_available_at(self, at, count) != 0
#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).
:return: (uint8_t \*) 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.
:return: (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: Source buffer.
:type bfrom: :class:`ldns_buffer`
:throws TypeError: When `bfrom` of non-:class:`ldns_buffer`
type.
"""
_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.
:return: (uint8_t \*) A 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).
:return: (uint8_t \*) 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 freeing the result.
:return: (void \*) Void pointer.
"""
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):
"""
Performs no action.
In debugging mode this method performs a buffer settings
check. It asserts if something is wrong.
"""
_ldns.ldns_buffer_invariant(self)
#parameters: ldns_buffer *,
def limit(self):
"""
Returns the maximum size of the buffer.
:return: (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).
:return: (size_t) The current position.
"""
return _ldns.ldns_buffer_position(self)
#parameters: ldns_buffer *,
#retvals: size_t
def printf(self, string, *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 string: A string to be written.
:type string: string
:throws: TypeError when `string` not a string.
:return: (int) Number of written characters or -1 on failure.
"""
data = string % 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: Target buffer to copy to.
:type data: void \*
:param count: The length of the data to copy.
:type count: size_t
"""
_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 reading.
:type at: size_t
:param data: Target buffer to copy to.
:type data: void \*
:param count: The length of the data to copy.
:type count: size_t
"""
_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
from the buffer.
:return: (uint16_t) Word.
"""
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
from the buffer.
:param at: Position in the buffer.
:type at: positive integer
:throws TypeError: When `at` of non-integer type.
:return: (uint16_t) Word.
"""
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
from the buffer.
:return: (uint32_t) Double-word.
"""
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
from the buffer.
:param at: Position in the buffer.
:type at: positive integer
:throws TypeError: When `at` of non-integer type.
:return: (uint32_t) Double-word.
"""
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 from the buffer.
:return: (uint8_t) A byte (not a character).
"""
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 from the buffer.
:param at: The position in the buffer.
:type at: positive integer
:throws TypeError: When `at` of non-integer type.
:return: (uint8_t) Byte value.
"""
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.
:return: (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.
:type at: positive integer
:throws TypeError: When `at` of non-integer type.
:return: (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 that the 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.
:type amount: positive integer
:throws TypeError: When `amount` of non-integer type.
:return: (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.
:type capacity: positive integer
:throws TypeError: When `capacity` of non-integer type.
:return: (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
then the position is set to the limit.
:param limit: The new limit.
:type limit: positive integer
:throws TypeError: When `limit` of non-integer type.
"""
_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.
:type mark: positive integer
:throws TypeError: When `mark` of non-integer type.
"""
_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.
:type count: integer
:throws TypeError: When `count` of non-integer type.
"""
_ldns.ldns_buffer_skip(self, count)
#parameters: ldns_buffer *, ssize_t,
#retvals:
def status(self):
"""
Returns the status of the buffer.
:return: (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.
:return: (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.
:type data: void \*
:param count: The length of the data to write.
:type count: size_t
"""
_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
by `at`.
: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, string):
"""
Copies the given (null-delimited) string to the current
position into the buffer.
:param string: The string to write.
:type string: string
:throws TypeError: When `string` not a string.
"""
_ldns.ldns_buffer_write_string(self,string)
#parameters: ldns_buffer *,const char *,
#retvals:
def write_string_at(self, at, string):
"""
Copies the given (null-delimited) string to the specified
position `at` into the buffer.
:param at: The position in the buffer.
:type at: positive integer
:param string: The string to write.
:type string: string
:throws TypeError: When types mismatch.
"""
_ldns.ldns_buffer_write_string_at(self, at, string)
#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 word to write.
:type data: uint16_t
:throws TypeError: When `data` of non-integer type.
"""
_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.
:type at: positive integer
:param data: The word to write.
:type data: uint16_t
:throws TypeError: When `at` or `data` of non-integer type.
"""
_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 double-word to write.
:type data: uint32_t
:throws TypeError: When `data` of non-integer type.
"""
_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.
:type at: positive integer
:param data: The double-word to write.
:type data: uint32_t
:throws TypeError: When `at` or `data` of non-integer type.
"""
_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 byte to write.
:type data: uint8_t
:throws TypeError: When `data` of non-integer type.
"""
_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.
:type at: positive integer
:param data: The byte to write.
:type data: uint8_t
:throws TypeError: When `at` or `data` of non-integer type.
"""
_ldns.ldns_buffer_write_u8_at(self,at,data)
#parameters: ldns_buffer *,size_t,uint8_t,
#retvals:
#
# _LDNS_BUFFER_METHODS
#
%}
}

View File

@@ -0,0 +1,625 @@
/******************************************************************************
* 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.
*****************************************************************************/
/* ========================================================================= */
/* SWIG setting and definitions. */
/* ========================================================================= */
/*
* Not here (with the exception of functions defined in this C code section),
* must be set in ldns_rdf.i.
*/
/* ========================================================================= */
/* Debugging related code. */
/* ========================================================================= */
/*
* Not here (with the exception of functions defined in this C code section),
* must be set in ldns_rdf.i.
*/
/* ========================================================================= */
/* Added C code. */
/* ========================================================================= */
/* None */
/* ========================================================================= */
/* Encapsulating Python code. */
/* ========================================================================= */
%pythoncode
%{
class ldns_dname(ldns_rdf):
"""
Domain name.
This class contains methods to read and manipulate domain name drfs.
Domain names are stored in :class:`ldns_rdf` structures,
with the type LDNS_RDF_TYPE_DNAME. This class encapsulates such
rdfs.
**Usage**
>>> import ldns
>>> 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 sub-domain of", dn1
>>> if dn1.is_subdomain(dn2): print dn1, "is sub-domain of", dn2
test.nic.cz. is sub-domain of nic.cz.
The following two examples show the creation of :class:`ldns_dname`
from :class:`ldns_rdf`. The first shows the creation of
:class:`ldns_dname` instance which is independent of the original
`rdf`.
>>> import ldns
>>> rdf = ldns.ldns_rdf.new_frm_str("a.ns.nic.cz", ldns.LDNS_RDF_TYPE_DNAME)
>>> dn = ldns.ldns_dname(rdf)
>>> print dn
a.ns.nic.cz.
The latter shows the wrapping of a :class:`ldns_rdf` onto
a :class:`ldns_dname` without the creation of a copy.
>>> import ldns
>>> dn = ldns.ldns_dname(ldns.ldns_rdf.new_frm_str("a.ns.nic.cz", ldns.LDNS_RDF_TYPE_DNAME), clone=False)
>>> print dn
a.ns.nic.cz.
"""
def __init__(self, initialiser, clone=True):
"""
Creates a new dname rdf from a string or :class:`ldns_rdf`.
:param initialiser: string or :class:`ldns_rdf`
:type initialiser: string or :class:`ldns_rdf` containing
a dname
:param clone: Whether to clone or directly grab the parameter.
:type clone: bool
:throws TypeError: When `initialiser` of invalid type.
"""
if isinstance(initialiser, ldns_rdf) and \
(initialiser.get_type() == _ldns.LDNS_RDF_TYPE_DNAME):
if clone == True:
self.this = _ldns.ldns_rdf_clone(initialiser)
else:
self.this = initialiser
else:
self.this = _ldns.ldns_dname_new_frm_str(initialiser)
#
# LDNS_DNAME_CONSTRUCTORS_
#
@staticmethod
def new_frm_str(string):
"""
Creates a new dname rdf instance from a string.
This static method is equivalent to using default
:class:`ldns_dname` constructor.
:param string: String to use.
:type string: string
:throws TypeError: When `string` not a string.
:return: (:class:`ldns_dname`) dname rdf.
"""
return ldns_dname(string)
@staticmethod
def new_frm_rdf(rdf, clone=True):
"""
Creates a new dname rdf instance from a dname :class:`ldns_rdf`.
This static method is equivalent to using the default
:class:`ldns_dname` constructor.
:param rdf: A dname :class:`ldns_rdf`.
:type rdf: :class:`ldns_rdf`
:throws TypeError: When `rdf` of inappropriate type.
:param clone: Whether to create a clone or to wrap present
instance.
:type clone: bool
:return: (:class:`ldns_dname`) dname rdf.
"""
return ldns_dname(rdf, clone=clone)
#
# _LDNS_DNAME_CONSTRUCTORS
#
def write_to_buffer(self, buffer):
"""
Copies the dname data to the buffer in wire format.
:param buffer: Buffer to append the result to.
:type param: :class:`ldns_buffer`
:throws TypeError: When `buffer` of non-:class:`ldns_buffer`
type.
:return: (ldns_status) ldns_status
"""
return _ldns.ldns_dname2buffer_wire(buffer, self)
#parameters: ldns_buffer *, const ldns_rdf *,
#retvals: ldns_status
#
# LDNS_DNAME_METHODS_
#
def absolute(self):
"""
Checks whether the given dname string is absolute (i.e.,
ends with a '.').
:return: (bool) True or False
"""
string = self.__str__()
return _ldns.ldns_dname_str_absolute(string) != 0
def make_canonical(self):
"""
Put a dname into canonical format (i.e., convert to lower case).
"""
_ldns.ldns_dname2canonical(self)
def __cmp__(self, other):
"""
Compares two dname rdf according to the algorithm for
ordering in RFC4034 Section 6.
:param other: The second dname rdf to compare.
:type other: :class:`ldns_dname`
:throws TypeError: When `other` of invalid type.
:return: (int) -1, 0 or 1 if self comes before other,
self is equal or self comes after other respectively.
.. note::
The type checking of parameter `other` is benevolent.
It allows also to pass a dname :class:`ldns_rdf` object.
This will probably change in future.
"""
#
# The wrapped function generates asserts instead of setting
# error status. They cannot be caught from Python so a check
# is necessary.
#
if (not isinstance(other, ldns_dname)) and \
isinstance(other, ldns_rdf) and \
other.get_type() == _ldns.LDNS_RDF_TYPE_DNAME:
warnings.warn("The ldns_dname.__cmp__() method will" +
" drop the possibility to compare ldns_rdf." +
" Convert arguments to ldns_dname.",
PendingDeprecationWarning, stacklevel=2)
if not isinstance(other, ldns_rdf):
raise TypeError("Parameter must be derived from ldns_rdf.")
if (other.get_type() != _ldns.LDNS_RDF_TYPE_DNAME):
raise Exception("Operands must be ldns_dname.")
return _ldns.ldns_dname_compare(self, other)
def __lt__(self, other):
"""
Compares two dname rdf according to the algorithm for
ordering in RFC4034 Section 6.
:param other: The second dname rdf to compare.
:type other: :class:`ldns_dname`
:throws TypeError: When `other` of invalid type.
:return: (bool) True when `self` is less than 'other'.
.. note::
The type checking of parameter `other` is benevolent.
It allows also to pass a dname :class:`ldns_rdf` object.
This will probably change in future.
"""
#
# The wrapped function generates asserts instead of setting
# error status. They cannot be caught from Python so a check
# is necessary.
#
if (not isinstance(other, ldns_dname)) and \
isinstance(other, ldns_rdf) and \
other.get_type() == _ldns.LDNS_RDF_TYPE_DNAME:
warnings.warn("The ldns_dname.__lt__() method will" +
" drop the possibility to compare ldns_rdf." +
" Convert arguments to ldns_dname.",
PendingDeprecationWarning, stacklevel=2)
if not isinstance(other, ldns_rdf):
raise TypeError("Parameter must be derived from ldns_rdf.")
if (other.get_type() != _ldns.LDNS_RDF_TYPE_DNAME):
raise Exception("Operands must be ldns_dname.")
return _ldns.ldns_dname_compare(self, other) == -1
def __le__(self, other):
"""
Compares two dname rdf according to the algorithm for
ordering in RFC4034 Section 6.
:param other: The second dname rdf to compare.
:type other: :class:`ldns_dname`
:throws TypeError: When `other` of invalid type.
:return: (bool) True when `self` is less than or equal to
'other'.
.. note::
The type checking of parameter `other` is benevolent.
It allows also to pass a dname :class:`ldns_rdf` object.
This will probably change in future.
"""
#
# The wrapped function generates asserts instead of setting
# error status. They cannot be caught from Python so a check
# is necessary.
#
if (not isinstance(other, ldns_dname)) and \
isinstance(other, ldns_rdf) and \
other.get_type() == _ldns.LDNS_RDF_TYPE_DNAME:
warnings.warn("The ldns_dname.__le__() method will" +
" drop the possibility to compare ldns_rdf." +
" Convert arguments to ldns_dname.",
PendingDeprecationWarning, stacklevel=2)
if not isinstance(other, ldns_rdf):
raise TypeError("Parameter must be derived from ldns_rdf.")
if (other.get_type() != _ldns.LDNS_RDF_TYPE_DNAME):
raise Exception("Operands must be ldns_dname.")
return _ldns.ldns_dname_compare(self, other) != 1
def __eq__(self, other):
"""
Compares two dname rdf according to the algorithm for
ordering in RFC4034 Section 6.
:param other: The second dname rdf to compare.
:type other: :class:`ldns_dname`
:throws TypeError: When `other` of invalid type.
:return: (bool) True when `self` is equal to 'other'.
.. note::
The type checking of parameter `other` is benevolent.
It allows also to pass a dname :class:`ldns_rdf` object.
This will probably change in future.
"""
#
# The wrapped function generates asserts instead of setting
# error status. They cannot be caught from Python so a check
# is necessary.
#
if (not isinstance(other, ldns_dname)) and \
isinstance(other, ldns_rdf) and \
other.get_type() == _ldns.LDNS_RDF_TYPE_DNAME:
warnings.warn("The ldns_dname.__eq__() method will" +
" drop the possibility to compare ldns_rdf." +
" Convert arguments to ldns_dname.",
PendingDeprecationWarning, stacklevel=2)
if not isinstance(other, ldns_rdf):
raise TypeError("Parameter must be derived from ldns_rdf.")
if (other.get_type() != _ldns.LDNS_RDF_TYPE_DNAME):
raise Exception("Operands must be ldns_dname.")
return _ldns.ldns_dname_compare(self, other) == 0
def __ne__(self, other):
"""
Compares two dname rdf according to the algorithm for
ordering in RFC4034 Section 6.
:param other: The second dname rdf to compare.
:type other: :class:`ldns_dname`
:throws TypeError: When `other` of invalid type.
:return: (bool) True when `self` is not equal to 'other'.
.. note::
The type checking of parameter `other` is benevolent.
It allows also to pass a dname :class:`ldns_rdf` object.
This will probably change in future.
"""
#
# The wrapped function generates asserts instead of setting
# error status. They cannot be caught from Python so a check
# is necessary.
#
if (not isinstance(other, ldns_dname)) and \
isinstance(other, ldns_rdf) and \
other.get_type() == _ldns.LDNS_RDF_TYPE_DNAME:
warnings.warn("The ldns_dname.__ne__() method will" +
" drop the possibility to compare ldns_rdf." +
" Convert arguments to ldns_dname.",
PendingDeprecationWarning, stacklevel=2)
if not isinstance(other, ldns_rdf):
raise TypeError("Parameter must be derived from ldns_rdf.")
if (other.get_type() != _ldns.LDNS_RDF_TYPE_DNAME):
raise Exception("Operands must be ldns_dname.")
return _ldns.ldns_dname_compare(self, other) != 0
def __gt__(self, other):
"""
Compares two dname rdf according to the algorithm for
ordering in RFC4034 Section 6.
:param other: The second dname rdf to compare.
:type other: :class:`ldns_dname`
:throws TypeError: When `other` of invalid type.
:return: (bool) True when `self` is greater than 'other'.
.. note::
The type checking of parameter `other` is benevolent.
It allows also to pass a dname :class:`ldns_rdf` object.
This will probably change in future.
"""
#
# The wrapped function generates asserts instead of setting
# error status. They cannot be caught from Python so a check
# is necessary.
#
if (not isinstance(other, ldns_dname)) and \
isinstance(other, ldns_rdf) and \
other.get_type() == _ldns.LDNS_RDF_TYPE_DNAME:
warnings.warn("The ldns_dname.__gt__() method will" +
" drop the possibility to compare ldns_rdf." +
" Convert arguments to ldns_dname.",
PendingDeprecationWarning, stacklevel=2)
if not isinstance(other, ldns_rdf):
raise TypeError("Parameter must be derived from ldns_rdf.")
if (other.get_type() != _ldns.LDNS_RDF_TYPE_DNAME):
raise Exception("Operands must be ldns_dname.")
return _ldns.ldns_dname_compare(self, other) == 1
def __ge__(self, other):
"""
Compares two dname rdf according to the algorithm for
ordering in RFC4034 Section 6.
:param other: The second dname rdf to compare.
:type other: :class:`ldns_dname`
:throws TypeError: When `other` of invalid type.
:return: (bool) True when `self` is greater than or equal to
'other'.
.. note::
The type checking of parameter `other` is benevolent.
It allows also to pass a dname :class:`ldns_rdf` object.
This will probably change in future.
"""
#
# The wrapped function generates asserts instead of setting
# error status. They cannot be caught from Python so a check
# is necessary.
#
if (not isinstance(other, ldns_dname)) and \
isinstance(other, ldns_rdf) and \
other.get_type() == _ldns.LDNS_RDF_TYPE_DNAME:
warnings.warn("The ldns_dname.__ge__() method will" +
" drop the possibility to compare ldns_rdf." +
" Convert arguments to ldns_dname.",
PendingDeprecationWarning, stacklevel=2)
if not isinstance(other, ldns_rdf):
raise TypeError("Parameter must be derived from ldns_rdf.")
if (other.get_type() != _ldns.LDNS_RDF_TYPE_DNAME):
raise Exception("Operands must be ldns_dname.")
return _ldns.ldns_dname_compare(self, other) != -1
def cat(self, rd2):
"""
Concatenates rd2 after this dname (`rd2` is copied,
`this` dname is modified).
:param rd2: The right-hand side.
:type rd2: :class:`ldns_dname`
:throws TypeError: When `rd2` of invalid type.
:return: (ldns_status) LDNS_STATUS_OK on success
.. note::
The type checking of parameter `rd2` is benevolent.
It allows also to pass a dname :class:`ldns_rdf` object.
This will probably change in future.
"""
if (not isinstance(rd2, ldns_dname)) and \
isinstance(rd2, ldns_rdf) and \
rd2.get_type() == _ldns.LDNS_RDF_TYPE_DNAME:
warnings.warn("The ldns_dname.cat() method will" +
" drop the support of ldns_rdf." +
" Convert arguments to ldns_dname.",
PendingDeprecationWarning, stacklevel=2)
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 right-hand side.
:type rd2: :class:`ldns_dname`
:throws TypeError: When `rd2` of invalid type.
:return: (:class:`ldns_dname`) A new rdf with
left-hand side + right-hand side content None when
error.
.. note::
The type checking of parameter `rd2` is benevolent.
It allows also to pass a dname :class:`ldns_rdf` object.
This will probably change in future.
"""
if (not isinstance(rd2, ldns_dname)) and \
isinstance(rd2, ldns_rdf) and \
rd2.get_type() == _ldns.LDNS_RDF_TYPE_DNAME:
warnings.warn("The ldns_dname.cat_clone() method will" +
" drop the support of ldns_rdf." +
" Convert arguments to ldns_dname.",
PendingDeprecationWarning, stacklevel=2)
ret = _ldns.ldns_dname_cat_clone(self, rd2)
if ret != None:
ret = ldns_dname(ret, clone=False)
return ret
#parameters: const ldns_rdf *, const ldns_rdf *,
#retvals: ldns_rdf *
def interval(self, middle, next):
"""
Check whether `middle` lays in the interval defined by
`this` and `next` (`this` <= `middle` < `next`).
This method is useful for nsec checking.
:param middle: The dname to check.
:type middle: :class:`ldns_dname`
:param next: The boundary.
:type next: :class:`ldns_dname`
:throws TypeError: When `middle` or `next` of
non-:class:`ldns_rdf` type.
:throws Exception: When non-dname rdfs compared.
:return: (int) 0 on error or unknown,
-1 when middle is in the interval, 1 when not.
.. note::
The type checking of parameters is benevolent.
It allows also to pass a dname :class:`ldns_rdf` object.
This will probably change in future.
"""
#
# The wrapped function generates asserts instead of setting
# error status. They cannot be caught from Python so a check
# is necessary.
#
if (not isinstance(middle, ldns_rdf)) or \
(not isinstance(next, ldns_rdf)):
raise TypeError("Parameters must be derived from ldns_dname.")
if (self.get_type() != _ldns.LDNS_RDF_TYPE_DNAME) or \
(middle.get_type() != _ldns.LDNS_RDF_TYPE_DNAME) or \
(next.get_type() != _ldns.LDNS_RDF_TYPE_DNAME):
raise Exception("All operands must be dname rdfs.")
if (not isinstance(middle, ldns_dname)) or \
(not isinstance(next, ldns_dname)):
warnings.warn("The ldns_dname.interval() method will" +
" drop the possibility to compare ldns_rdf." +
" Convert arguments to ldns_dname.",
PendingDeprecationWarning, stacklevel=2)
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 whether the name of the instance falls under
`parent` (i.e., is a sub-domain of `parent`).
This function will return false if the given dnames are equal.
:param parent: The parent's name.
:type parent: :class:`ldns_dname`
:throws TypeError: When `parent` of non-:class:`ldns_rdf`
or derived type.
:return: (bool) True if `this` falls under `parent`, otherwise
False.
.. note::
The type checking of parameters is benevolent.
It allows also to pass a dname :class:`ldns_rdf` object.
This will probably change in future.
"""
if (not isinstance(parent, ldns_dname)) and \
isinstance(parent, ldns_rdf) and \
parent.get_type() == _ldns.LDNS_RDF_TYPE_DNAME:
warnings.warn("The ldns_dname.is_subdomain() method will" +
" drop the support of ldns_rdf." +
" Convert arguments to ldns_dname.",
PendingDeprecationWarning, stacklevel=2)
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 retrieve a specific label.
The labels are numbered starting from 0 (left most).
:param labelpos: Index of the label. (Labels are numbered
0, which is the left most.)
:type labelpos: integer
:throws TypeError: When `labelpos` of non-integer type.
:return: (:class:`ldns_dname`) A new rdf with the label
as name or None on error.
"""
ret = _ldns.ldns_dname_label(self, labelpos)
if ret != None:
ret = ldns_dname(ret, clone=False)
return ret
#parameters: const ldns_rdf *, uint8_t,
#retvals: ldns_rdf *
def label_count(self):
"""
Counts the number of labels.
:return: (uint8_t) the number of labels. Will return 0
if not a dname.
"""
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.
(e.g., wwww.nlnetlabs.nl, becomes nlnetlabs.nl)
:return: (:class:`ldns_dname`) The remaining dname or None
when error.
"""
return ldns_dname(_ldns.ldns_dname_left_chop(self), clone=False)
#parameters: const ldns_rdf *,
#retvals: ldns_rdf *
def reverse(self):
"""
Returns a clone of the given dname with the labels reversed.
:return: (:class:`ldns_dname`) A clone of the dname with
the labels reversed.
"""
return ldns_dname(_ldns.ldns_dname_reverse(self), clone=False)
#parameters: const ldns_rdf *,
#retvals: ldns_rdf *
#
# _LDNS_DNAME_METHODS
#
%}

View File

@@ -0,0 +1,457 @@
/******************************************************************************
* 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 instance 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);
}
ldns_status ldns_dnssec_zone_add_rr_(ldns_dnssec_zone *zone, ldns_rr *rr)
{
ldns_rr *new_rr;
ldns_status status;
new_rr = ldns_rr_clone(rr);
/*
* A clone of the RR is created to be stored in the DNSSEC zone.
* The Python engine frees a RR object as soon it's reference count
* reaches zero. The code must avoid double freeing or accessing of freed
* memory.
*/
status = ldns_dnssec_zone_add_rr(zone, new_rr);
if (status != LDNS_STATUS_OK) {
ldns_rr_free(new_rr);
}
return status;
}
%}
%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#
%}
}

View File

@@ -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 ));
}
%typemap(argout) ldns_rdf *r "Py_INCREF($input);"
%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 output
: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 expiration 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 count
"""
_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#
%}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,949 @@
/******************************************************************************
* ldns_rdf.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.
*****************************************************************************/
/* ========================================================================= */
/* SWIG setting and definitions. */
/* ========================================================================= */
/* Creates a temporary instance of (ldns_rdf *). */
%typemap(in, numinputs=0, noblock=1) (ldns_rdf **)
{
ldns_rdf *$1_rdf = NULL;
$1 = &$1_rdf;
}
/* Result generation, appends (ldns_rdf *) after the result. */
%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));
}
#if SWIG_VERSION < 0x040200
/*
* Automatic conversion of const (ldns_rdf *) parameter from string.
* Argument default value.
*/
%typemap(arginit, noblock=1) const ldns_rdf *
{
#if SWIG_VERSION >= 0x040200
PyObject *$1_bytes = NULL;
#else
char *$1_str = NULL;
#endif
}
/*
* Automatic conversion of const (ldns_rdf *) parameter from string.
* Preparation of arguments.
*/
%typemap(in, noblock=1) const ldns_rdf * (void* argp, $1_ltype tmp = 0, int res)
{
if (Python_str_Check($input)) {
const char *argstr;
#if SWIG_VERSION >= 0x040200
argstr = SWIG_PyUnicode_AsUTF8AndSize($input, NULL, &$1_bytes);
#else
$1_str = SWIG_Python_str_AsChar($input);
argstr = $1_str;
#endif
if (argstr == NULL) {
%argument_fail(SWIG_TypeError, "char *", $symname, $argnum);
}
tmp = ldns_dname_new_frm_str(argstr);
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;
}
}
/*
* Automatic conversion of const (ldns_rdf *) parameter from string.
* Freeing of allocated memory (in Python 3 when daling with strings).
*/
%typemap(freearg, noblock=1) const ldns_rdf *
{
#if SWIG_VERSION >= 0x040200
if ($1_bytes != NULL) {
/* Is not NULL only when a conversion form string occurred. */
Py_XDECREF($1_bytes);
}
#else
if ($1_str != NULL) {
/* Is not NULL only when a conversion form string occurred. */
SWIG_Python_str_DelForPy3($1_str); /* Is a empty macro for Python < 3. */
}
#endif
}
#else
/*
* Automatic conversion of const (ldns_rdf *) parameter from string.
* Argument default value.
*/
%typemap(arginit, noblock=1) const ldns_rdf *
{
PyObject *$1_bytes = NULL;
}
/*
* Automatic conversion of const (ldns_rdf *) parameter from string.
* Preparation of arguments.
*/
%typemap(in, noblock=1) const ldns_rdf * (void* argp, $1_ltype tmp = 0, int res)
{
if (Python_str_Check($input)) {
const char *$1_str = SWIG_PyUnicode_AsUTF8AndSize($input, NULL, &$1_bytes);
if ($1_str == NULL) {
%argument_fail(SWIG_TypeError, "char *", $symname, $argnum);
}
tmp = ldns_dname_new_frm_str($1_str);
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;
}
}
/*
* Automatic conversion of const (ldns_rdf *) parameter from string.
* Freeing of allocated memory (it's a no op unless compiling for some older versions of the Python stable ABI).
*/
%typemap(freearg, noblock=1) const ldns_rdf *
{
Py_XDECREF($1_bytes);
}
#endif
%nodefaultctor ldns_struct_rdf; /* No default constructor. */
%nodefaultdtor ldns_struct_rdf; /* No default destructor. */
/*
* This file must contain all %newobject and %delobject tags also for
* ldns_dname. This is because the ldns_dname is a derived class from ldns_rdf.
*/
%newobject ldns_rdf_new;
%newobject ldns_rdf_new_frm_str;
%newobject ldns_rdf_new_frm_data;
%newobject ldns_rdf_address_reverse;
%newobject ldns_rdf_clone;
%newobject ldns_rdf2str;
%newobject ldns_dname_new;
%newobject ldns_dname_new_frm_str;
%newobject ldns_dname_new_frm_data;
%newobject ldns_dname_cat_clone;
%newobject ldns_dname_label;
%newobject ldns_dname_left_chop;
%newobject ldns_dname_reverse;
%delobject ldns_rdf_deep_free;
%delobject ldns_rdf_free;
/*
* Should the ldns_rdf_new() also be marked as deleting its data parameter?
*/
%delobject ldns_rdf_set_data; /* Because data are directly coupled into rdf. */
%rename(ldns_rdf) ldns_struct_rdf;
/* ========================================================================= */
/* Debugging related code. */
/* ========================================================================= */
#ifdef LDNS_DEBUG
%rename(__ldns_rdf_deep_free) ldns_rdf_deep_free;
%rename(__ldns_rdf_free) ldns_rdf_free;
%inline
%{
/*!
* @brief Prints information about deallocated rdf and deallocates.
*/
void _ldns_rdf_deep_free (ldns_rdf *r)
{
printf("******** LDNS_RDF deep free 0x%lX ************\n",
(long unsigned int) r);
ldns_rdf_deep_free(r);
}
/*!
* @brief Prints information about deallocated rdf and deallocates.
*/
void _ldns_rdf_free (ldns_rdf* r)
{
printf("******** LDNS_RDF free 0x%lX ************\n",
(long unsigned int) r);
ldns_rdf_free(r);
}
%}
#else /* !LDNS_DEBUG */
%rename(_ldns_rdf_deep_free) ldns_rdf_deep_free;
%rename(_ldns_rdf_free) ldns_rdf_free;
#endif /* LDNS_DEBUG */
/* ========================================================================= */
/* Added C code. */
/* ========================================================================= */
%inline
%{
/*!
* @brief returns a human readable string containing rdf type.
*/
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_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_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_PERIOD: return "PERIOD";
case LDNS_RDF_TYPE_TSIGTIME: return "TSIGTIME";
case LDNS_RDF_TYPE_HIP: return "HIP";
case LDNS_RDF_TYPE_INT16_DATA: return "INT16_DATA";
case LDNS_RDF_TYPE_SERVICE: return "SERVICE";
case LDNS_RDF_TYPE_LOC: return "LOC";
case LDNS_RDF_TYPE_WKS: return "WKS";
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_NSEC3_SALT: return "NSEC3_SALT";
case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER:
return "NSEC3_NEXT_OWNER";
case LDNS_RDF_TYPE_ILNP64: return "ILNP64";
case LDNS_RDF_TYPE_EUI48: return "EUI48";
case LDNS_RDF_TYPE_EUI64: return "EUI64";
case LDNS_RDF_TYPE_TAG: return "TAG";
case LDNS_RDF_TYPE_LONG_STR: return "LONG_STR";
case LDNS_RDF_TYPE_AMTRELAY: return "AMTRELAY";
case LDNS_RDF_TYPE_SVCPARAMS: return "SVCPARAMS";
case LDNS_RDF_TYPE_CERTIFICATE_USAGE:
return "CERTIFICATE_USAGE";
case LDNS_RDF_TYPE_SELECTOR: return "SELECTOR";
case LDNS_RDF_TYPE_MATCHING_TYPE:
return "MATCHING_TYPE";
}
}
return 0;
}
%}
%inline
%{
/*!
* @brief Returns the rdf data organised into a list of bytes.
*/
PyObject * ldns_rdf_data_as_bytearray(const ldns_rdf *rdf)
{
Py_ssize_t len;
uint8_t *data;
assert(rdf != NULL);
len = ldns_rdf_size(rdf);
data = ldns_rdf_data(rdf);
return PyByteArray_FromStringAndSize((char *) data, len);
}
%}
/* ========================================================================= */
/* Encapsulating Python code. */
/* ========================================================================= */
%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):
"""
Cannot be created directly from Python.
"""
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(string, rr_type, raiseException = True):
"""
Creates a new rdf from a string of a given type.
:param string: string to use
:type string: string
:param rr_type: The type of the rdf. See predefined `RDF_TYPE_`
constants.
:type rr_type: integer
:param raiseException: If True, an exception occurs in case
a RDF object can't be created.
:type raiseException: bool
:throws TypeError: When parameters of mismatching types.
:throws Exception: When raiseException set and rdf couldn't
be created.
:return: :class:`ldns_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, string)
if (not rr) and raiseException:
raise Exception("Can't create query packet")
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 rdfs on their wire formats.
(To order dnames according to rfc4034, use ldns_dname_compare.)
:param other: The second one RDF.
:type other: :class:`ldns_rdf`
:throws TypeError: When `other` of non-:class:`ldns_rdf` type.
:return: (int) -1, 0 or 1 if self comes before other,
is equal or self comes after other respectively.
"""
return _ldns.ldns_rdf_compare(self, other)
def __lt__(self, other):
"""
Compares two rdfs on their formats.
:param other: The socond one RDF.
:type other: :class:`ldns_rdf`
:throws TypeError: When `other` of non-:class:`ldns_rdf` type.
:return: (bool) True when `self` is less than 'other'.
"""
return _ldns.ldns_rdf_compare(self, other) == -1
def __le__(self, other):
"""
Compares two rdfs on their formats.
:param other: The socond one RDF.
:type other: :class:`ldns_rdf`
:throws TypeError: When `other` of non-:class:`ldns_rdf` type.
:return: (bool) True when `self` is less than or equal to
'other'.
"""
return _ldns.ldns_rdf_compare(self, other) != 1
def __eq__(self, other):
"""
Compares two rdfs on their formats.
:param other: The socond one RDF.
:type other: :class:`ldns_rdf`
:throws TypeError: When `other` of non-:class:`ldns_rdf` type.
:return: (bool) True when `self` is equal to 'other'.
"""
return _ldns.ldns_rdf_compare(self, other) == 0
def __ne__(self, other):
"""
Compares two rdfs on their formats.
:param other: The socond one RDF.
:type other: :class:`ldns_rdf`
:throws TypeError: When `other` of non-:class:`ldns_rdf` type.
:return: (bool) True when `self` is not equal to 'other'.
"""
return _ldns.ldns_rdf_compare(self, other) != 0
def __gt__(self, other):
"""
Compares two rdfs on their formats.
:param other: The socond one RDF.
:type other: :class:`ldns_rdf`
:throws TypeError: When `other` of non-:class:`ldns_rdf` type.
:return: (bool) True when `self` is greater than 'other'.
"""
return _ldns.ldns_rdf_compare(self, other) == 1
def __ge__(self, other):
"""
Compares two rdfs on their formats.
:param other: The socond one RDF.
:type other: :class:`ldns_rdf`
:throws TypeError: When `other` of non-:class:`ldns_rdf` type.
:return: (bool) True when `self` is greater than or equal to
'other'.
"""
return _ldns.ldns_rdf_compare(self, other) != -1
def print_to_file(self, output):
"""
Prints the data in the rdata field to the given `output` file
stream (in presentation format).
"""
_ldns.ldns_rdf_print(output, self)
def get_type_str(self):
"""
Returns the type of the rdf as a human readable string.
:return: String containing rdf type.
"""
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 rdf to.
:type param: :class:`ldns_buffer`
:throws TypeError: When `buffer` of non-:class:`ldns_buffer`
type.
:return: (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 converted
to lower case during the conversion.
:param buffer: LDNS buffer.
:type buffer: :class:`ldns_buffer`
:throws TypeError: When `buffer` of non-:class:`ldns_buffer`
type.
:return: (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!
:return: (:class:`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 are copied.
:return: (:class:`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.
:return: (uint8_t \*) uint8_t* pointer to the rdf's data.
"""
return _ldns.ldns_rdf_data(self)
#parameters: const ldns_rdf *,
#retvals: uint8_t *
def data_as_bytearray(self):
"""
Returns the data of the rdf as a bytearray.
:return: (bytearray) Bytearray containing the rdf data.
"""
return _ldns.ldns_rdf_data_as_bytearray(self)
#parameters: const ldns_rdf *,
#retvals: bytearray
def get_type(self):
"""
Returns the type of the rdf.
We need to prepend the prefix get_ here to prevent conflict
with the rdf_type TYPE.
:return: (ldns_rdf_type) Identifier of the type.
"""
return _ldns.ldns_rdf_get_type(self)
#parameters: const ldns_rdf *,
#retvals: ldns_rdf_type
def set_data(self, data):
"""
Sets the data portion of the rdf.
The data are not copied, but are assigned to the rdf,
`data` are decoupled from the Python engine.
:param data: Data to be set.
:type data: void \*
"""
_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.
:type size: integer
:throws TypeError: When size of non-integer type.
"""
_ldns.ldns_rdf_set_size(self,size)
#parameters: ldns_rdf *,size_t,
#retvals:
def set_type(self, atype):
"""
Sets the type of the rdf.
:param atype: rdf type
:type atype: integer
:throws TypeError: When atype of non-integer type.
"""
_ldns.ldns_rdf_set_type(self, atype)
#parameters: ldns_rdf *, ldns_rdf_type,
#retvals:
def size(self):
"""
Returns the size of the rdf.
:return: (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(string):
"""
Creates a new dname rdf instance from a given string.
This static method is equivalent to using of default
:class:`ldns_rdf` constructor.
:parameter string: String to use.
:type string: string
:throws TypeError: When not a string used.
:return: :class:`ldns_rdf` or None if error.
.. warning::
It is scheduled to be deprecated and removed. Use
:class:`ldns_dname` constructor instead.
"""
warnings.warn("The ldns_rdf.dname_new_frm_str() method is" +
" scheduled to be deprecated in future releases." +
" Use ldns_dname constructor instead.",
PendingDeprecationWarning, stacklevel=2)
return _ldns.ldns_dname_new_frm_str(string)
def absolute(self):
"""
Checks whether the given dname string is absolute
(i.e., ends with a '.').
:return: (bool) True or False
.. note::
This method was malfunctioning in ldns-1.3.16 and also
possibly earlier.
.. warning::
It is scheduled to be deprecated and removed. Convert
:class:`ldns_rdf` to :class:`ldns_dname` to use the method.
"""
warnings.warn("The ldns_rdf.absolute() method is scheduled" +
" to be deprecated in future releases." +
" Convert the ldns_rdf to ldns_dname and the use its" +
" methods.", PendingDeprecationWarning, stacklevel=2)
if self.get_type() == _ldns.LDNS_RDF_TYPE_DNAME:
string = self.__str__()
return _ldns.ldns_dname_str_absolute(string) != 0
else:
return False
def make_canonical(self):
"""
Put a dname into canonical format (i.e., convert to lower case).
Performs no action if not a dname.
.. warning::
This method is scheduled to be deprecated and removed.
Convert :class:`ldns_rdf` to :class:`ldns_dname` to use
the method.
"""
warnings.warn("The ldns_rdf.make_canonical() method is scheduled" +
" to be deprecated in future releases." +
" Convert the ldns_rdf to ldns_dname and the use its" +
" methods.", PendingDeprecationWarning, stacklevel=2)
_ldns.ldns_dname2canonical(self)
def dname_compare(self, other):
"""
Compares two dname rdf according to the algorithm
for ordering in RFC4034 Section 6.
:param other: The second dname rdf to compare.
:type other: :class:`ldns_rdf`
:throws TypeError: When not a :class:`ldns_rdf` used.
:throws Exception: When not dnames compared.
:return: (int) -1, 0 or 1 if `self` comes before `other`,
`self` is equal or `self` comes after `other` respectively.
.. warning::
It is scheduled to be deprecated and removed. Convert
:class:`ldns_rdf` to :class:`ldns_dname`.
"""
warnings.warn("The ldns_rdf.dname_compare() method is" +
" scheduled to be deprecated in future releases." +
" Convert the ldns_rdf to ldns_dname and the use its" +
" methods.", PendingDeprecationWarning, stacklevel=2)
#
# The wrapped function generates asserts instead of setting
# error status. They cannot be caught from Python so a check
# is necessary.
#
if not isinstance(other, ldns_rdf):
raise TypeError("Parameter must be derived from ldns_rdf.")
if (self.get_type() != _ldns.LDNS_RDF_TYPE_DNAME) or \
(other.get_type() != _ldns.LDNS_RDF_TYPE_DNAME):
raise Exception("Both operands must be dname rdfs.")
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 right-hand side.
:type rd2: :class:`ldns_rdf`
:throws TypeError: When `rd2` of non-:class:`ldns_rdf` or
non-:class:`ldns_dname` type.
:return: (ldns_status) LDNS_STATUS_OK on success.
.. warning::
It is scheduled to be deprecated and removed. Convert
:class:`ldns_rdf` to :class:`ldns_dname`.
"""
warnings.warn("The ldns_rdf.cat() method is scheduled" +
" to be deprecated in future releases." +
" Convert the ldns_rdf to ldns_dname and the use its" +
" methods.", PendingDeprecationWarning, stacklevel=2)
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 right-hand side.
:type rd2: :class:`ldns_rdf`
:throws TypeError: When `rd2` of non-:class:`ldns_rdf` or
non-:class:`ldns_dname` type.
:return: (:class:`ldns_rdf`) A new rdf with
left-hand side + right-hand side content None when
error.
.. warning::
It is scheduled to be deprecated and removed. Convert
:class:`ldns_rdf` to :class:`ldns_dname`.
"""
warnings.warn("The ldns_rdf.cat_clone() method is scheduled" +
" to be deprecated in future releases." +
" Convert the ldns_rdf to ldns_dname and the use its" +
" methods.", PendingDeprecationWarning, stacklevel=2)
return _ldns.ldns_dname_cat_clone(self, rd2)
#parameters: const ldns_rdf *, const ldns_rdf *,
#retvals: ldns_rdf *
def interval(self, middle, next):
"""
Check whether the `middle` lays in the interval defined by
`this` and `next` (`this` <= `middle` < `next`).
This method is useful for nsec checking
:param middle: The dname to check.
:type middle: :class:`ldns_rdf`
:param next: The boundary.
:type next: :class:`ldns_rdf`
:throws TypeError: When `middle` or `next` of
non-:class:`ldns_rdf` type.
:throws Exception: When non-dname rdfs compared.
:return: (int) 0 on error or unknown,
-1 when middle is in the interval, 1 when not.
.. warning::
It is scheduled to be deprecated and removed. Convert
:class:`ldns_rdf` to :class:`ldns_dname`.
"""
warnings.warn("The ldns_rdf.interval() method is scheduled" +
" to be deprecated in future releases." +
" Convert the ldns_rdf to ldns_dname and the use its" +
" methods.", PendingDeprecationWarning, stacklevel=2)
#
# The wrapped function generates asserts instead of setting
# error status. They cannot be caught from Python so a check
# is necessary.
#
if (not isinstance(middle, ldns_rdf)) or \
(not isinstance(next, ldns_rdf)):
raise TypeError("Parameters must be derived from ldns_rdf.")
if (self.get_type() != _ldns.LDNS_RDF_TYPE_DNAME) or \
(middle.get_type() != _ldns.LDNS_RDF_TYPE_DNAME) or \
(next.get_type() != _ldns.LDNS_RDF_TYPE_DNAME):
raise Exception("All operands must be dname rdfs.")
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 whether the name of the given instance falls under
`parent` (i.e., is a sub-domain of `parent`).
This function will return False if the given dnames
are equal.
:param parent: The parent's name.
:type parent: :class:`ldns_rdf`
:throws TypeError: When `parent` of non-:class:`ldns_rdf` type.
:return: (bool) True if `this` falls under `parent`, otherwise
False.
.. warning::
It is scheduled to be deprecated and removed. Convert
:class:`ldns_rdf` to :class:`ldns_dname`.
"""
warnings.warn("The ldns_rdf.is_subdomain() method is scheduled" +
" to be deprecated in future releases." +
" Convert the ldns_rdf to ldns_dname and the use its" +
" methods.", PendingDeprecationWarning, stacklevel=2)
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: Index of the label. (Labels are numbered
0, which is the left most.)
:type labelpos: integer
:throws TypeError: When `labelpos` of non-integer type.
:return: (:class:`ldns_rdf`) A new rdf with the label
as name or None on error.
.. warning::
It is scheduled to be deprecated and removed. Convert
:class:`ldns_rdf` to :class:`ldns_dname`.
"""
warnings.warn("The ldns_rdf.label() method is scheduled" +
" to be deprecated in future releases." +
" Convert the ldns_rdf to ldns_dname and the use its" +
" methods.", PendingDeprecationWarning, stacklevel=2)
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.
:return: (uint8_t) The number of labels. Will return 0 if
not a dname.
.. warning::
It is scheduled to be deprecated and removed. Convert
:class:`ldns_rdf` to :class:`ldns_dname`.
"""
warnings.warn("The ldns_rdf.label_count() method is scheduled" +
" to be deprecated in future releases." +
" Convert the ldns_rdf to ldns_dname and the use its" +
" methods.", PendingDeprecationWarning, stacklevel=2)
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.
(e.g., wwww.nlnetlabs.nl, becomes nlnetlabs.nl)
:return: (:class:`ldns_rdf`) The remaining dname or None when
error.
.. warning::
It is scheduled to be deprecated and removed. Convert
:class:`ldns_rdf` to :class:`ldns_dname`.
"""
warnings.warn("The ldns_rdf.left_chop() method is scheduled" +
" to be deprecated in future releases." +
" Convert the ldns_rdf to ldns_dname and the use its" +
" methods.", PendingDeprecationWarning, stacklevel=2)
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.
When reversing non-dnames a "." (root name) dname is returned.
:throws Exception: When used on non-dname rdfs.
:return: (:class:`ldns_rdf`) Clone of the dname with the labels
reversed or ".".
.. warning::
It is scheduled to be deprecated and removed. Convert
:class:`ldns_rdf` to :class:`ldns_dname`.
"""
warnings.warn("The ldns_rdf.reverse() method is scheduled" +
" to be deprecated in future releases." +
" Convert the ldns_rdf to ldns_dname and the use its" +
" methods.", PendingDeprecationWarning, stacklevel=2)
if self.get_type() != _ldns.LDNS_RDF_TYPE_DNAME:
raise Exception("Operand must be a dname rdf.")
return _ldns.ldns_dname_reverse(self)
#parameters: const ldns_rdf *,
#retvals: ldns_rdf *
#
# _LDNS_RDF_METHODS
#
%}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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: Default 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: Default 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 success 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 success 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#
%}
}