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

@@ -7,8 +7,11 @@
FROM alpine:3.22 AS ldns-build FROM alpine:3.22 AS ldns-build
RUN apk add --no-cache \ RUN apk add --no-cache \
autoconf \
automake \
build-base \ build-base \
libidn2-dev \ libidn2-dev \
libtool \
make \ make \
openssl-dev \ openssl-dev \
perl-app-cpanminus \ perl-app-cpanminus \

View File

@@ -0,0 +1,2 @@
github: [NLnetLabs]
custom: ['https://nlnetlabs.nl/funding/']

View File

@@ -0,0 +1,137 @@
on:
push:
branches:
- '*'
tags-ignore:
- '*'
pull_request:
jobs:
linux:
name: Linux (Ubuntu)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
with:
submodules: recursive
- run: libtoolize -vci
- run: autoreconf -vfi
- run: ./configure
env:
CFLAGS: -g2 -O0 -fsanitize=address,undefined -fno-sanitize-recover
- run: make test
mac:
name: macOS
runs-on: macos-latest
steps:
- run: brew install automake libtool
- uses: actions/checkout@main
with:
submodules: recursive
- run: glibtoolize -vci
- run: autoreconf -vfi
# macOSs system OpenSSL (LibreSSL, actually) isnt meant for linking,
# and Homebrews# OpenSSL isnt CI-friendly. So build without OpenSSL.
- run: ./configure --without-ssl --disable-sha2 --disable-gost --disable-ecdsa --disable-dane
env:
CFLAGS: -g2 -O0 -fsanitize=address,undefined -fno-sanitize-recover
- run: make test
# Pending https://github.com/NLnetLabs/ldns/issues/197,
# only builds succeed here.
cygwin:
name: Cygwin
runs-on: windows-latest
steps:
- name: Make git ignore line breaks
run: git config --global core.autocrlf false
- name: Set up Cygwin
uses: cygwin/cygwin-install-action@master
with:
packages: make gcc-g++ bash libtool automake autoconf libssl-devel bind-utils
- uses: actions/checkout@main
with:
submodules: recursive
- shell: C:\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}'
name: Build
run: |
cd $GITHUB_WORKSPACE
libtoolize -vci
autoreconf -vfi
./configure
make
qemu-alpine:
name: Linux (Alpine, ${{ matrix.platform }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
platform:
- i386
- arm32v6
- arm32v7
- arm64v8
- s390x
steps:
- uses: actions/checkout@main
with:
submodules: recursive
- name: Get the qemu container
run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
- name: "${{ matrix.platform }}: Build and test"
run: docker run --rm --interactive --mount type=bind,source=$(pwd),target=/host ${{ matrix.platform }}/alpine sh -c "apk add make gcc libc-dev libtool automake autoconf openssl-dev m4 indent bash bind-tools && cd /host && libtoolize -vci && autoreconf -vfi && ./configure && make test"
# BSDs:
# name: ${{ matrix.os.dispname }} ${{ matrix.os.version }}
#
# runs-on: macos-latest
#
# strategy:
# fail-fast: false
# matrix:
# os:
# - name: freebsd
# dispname: FreeBSD
# version: '13.0'
# pkginstall: pkg install -y libtool automake bind-tools gmake gindent
# env:
# configure_args:
#
# # OpenBSD seems to require explicit auto* versions.
# - name: openbsd
# dispname: OpenBSD
# version: '7.1'
# pkginstall: pkg_add -v libtool gmake gindent automake-1.16.3 autoconf-2.71
# env: AUTOCONF_VERSION=2.71 AUTOMAKE_VERSION=1.16
# configure_args: --disable-dane-verify
#
# steps:
# - uses: actions/checkout@main
# with:
# submodules: recursive
# - name: Build and test on ${{ matrix.os.name }}
# uses: cross-platform-actions/action@master
# with:
# operating_system: ${{ matrix.os.name }}
# version: ${{ matrix.os.version }}
# shell: bash
# run: |
# export DUMMY12345=1 ${{ matrix.os.env }}
# sudo ${{ matrix.os.pkginstall }} || ${{ matrix.os.pkginstall }}
# libtoolize -vci
# autoreconf -vfi
# ./configure ${{ matrix.os.configure_args }}
# gmake test

214
zonemaster-ldns/ldns/.gitignore vendored Normal file
View File

@@ -0,0 +1,214 @@
/.libs/
.*.swp
*~
\#*\#
/_ldns.la
/Makefile
/aclocal.m4
/autom4te.cache/
/buffer.lo
/buffer.o
/compat/.libs/
/compat/b64_ntop.lo
/compat/b64_ntop.o
/compat/b64_pton.lo
/compat/b64_pton.o
/compat/strlcpy.o
/compat/strlcpy.lo
/compat/timegm.o
/compat/timegm.lo
/compile
/config.guess
/config.h
/config.log
/config.status
/config.sub
/configure
/contrib/python/ldns.py
/contrib/python/ldns_wrapper.c
/dane.lo
/dane.o
/dname.lo
/dname.o
/dnssec.lo
/dnssec.o
/dnssec_sign.lo
/dnssec_sign.o
/dnssec_verify.lo
/dnssec_verify.o
/dnssec_zone.lo
/dnssec_zone.o
/doc/ldns_manpages
/doc/man/
/drill/.libs/
/drill/chasetrace.lo
/drill/chasetrace.o
/drill/dnssec.lo
/drill/dnssec.o
/drill/drill
/drill/drill.1
/drill/drill.lo
/drill/drill.o
/drill/drill_util.lo
/drill/drill_util.o
/drill/error.lo
/drill/error.o
/drill/root.lo
/drill/root.o
/drill/securetrace.lo
/drill/securetrace.o
/drill/work.lo
/drill/work.o
/duration.lo
/duration.o
/error.lo
/error.o
/edns.lo
/edns.o
/examples/.libs/
/examples/ldns-chaos
/examples/ldns-chaos.lo
/examples/ldns-chaos.o
/examples/ldns-compare-zones
/examples/ldns-compare-zones.lo
/examples/ldns-compare-zones.o
/examples/ldns-dane
/examples/ldns-dane.1
/examples/ldns-dane.lo
/examples/ldns-dane.o
/examples/ldns-dpa
/examples/ldns-dpa.lo
/examples/ldns-dpa.o
/examples/ldns-gen-zone
/examples/ldns-gen-zone.lo
/examples/ldns-gen-zone.o
/examples/ldns-key2ds
/examples/ldns-key2ds.lo
/examples/ldns-key2ds.o
/examples/ldns-keyfetcher
/examples/ldns-keyfetcher.lo
/examples/ldns-keyfetcher.o
/examples/ldns-keygen
/examples/ldns-keygen.lo
/examples/ldns-keygen.o
/examples/ldns-mx
/examples/ldns-mx.lo
/examples/ldns-mx.o
/examples/ldns-notify
/examples/ldns-notify.lo
/examples/ldns-notify.o
/examples/ldns-nsec3-hash
/examples/ldns-nsec3-hash.lo
/examples/ldns-nsec3-hash.o
/examples/ldns-read-zone
/examples/ldns-read-zone.lo
/examples/ldns-read-zone.o
/examples/ldns-resolver
/examples/ldns-resolver.lo
/examples/ldns-resolver.o
/examples/ldns-revoke
/examples/ldns-revoke.lo
/examples/ldns-revoke.o
/examples/ldns-rrsig
/examples/ldns-rrsig.lo
/examples/ldns-rrsig.o
/examples/ldns-signzone
/examples/ldns-signzone.lo
/examples/ldns-signzone.o
/examples/ldns-test-edns
/examples/ldns-test-edns.lo
/examples/ldns-test-edns.o
/examples/ldns-testns
/examples/ldns-testns.lo
/examples/ldns-testns.o
/examples/ldns-testpkts.lo
/examples/ldns-testpkts.o
/examples/ldns-update
/examples/ldns-update.lo
/examples/ldns-update.o
/examples/ldns-verify-zone
/examples/ldns-verify-zone.1
/examples/ldns-verify-zone.lo
/examples/ldns-verify-zone.o
/examples/ldns-version
/examples/ldns-version.lo
/examples/ldns-version.o
/examples/ldns-walk
/examples/ldns-walk.lo
/examples/ldns-walk.o
/examples/ldns-zcat
/examples/ldns-zcat.lo
/examples/ldns-zcat.o
/examples/ldns-zsplit
/examples/ldns-zsplit.lo
/examples/ldns-zsplit.o
/examples/ldnsd
/examples/ldnsd.lo
/examples/ldnsd.o
/higher.lo
/higher.o
/host2str.lo
/host2str.o
/host2wire.lo
/host2wire.o
/include/
/install-sh
/keys.lo
/keys.o
/ldns/common.h
/ldns/config.h
/ldns/config.h.in
/ldns/net.h
/ldns/stamp-h1
/ldns/util.h
/ldns_wrapper.lo
/ldns_wrapper.o
/lib
/libdns.doxygen
/libldns.la
/libtool
/linktest
/linktest.lo
/linktest.o
/ltmain.sh
/m4/lt*.m4
/m4/libtool.m4
/missing
/net.lo
/net.o
/packaging/ldns-config
/packaging/libldns.pc
/packet.lo
/packet.o
/parse.lo
/parse.o
/radix.lo
/radix.o
/rbtree.lo
/rbtree.o
/rdata.lo
/rdata.o
/resolver.lo
/resolver.o
/rr.lo
/rr.o
/rr_functions.lo
/rr_functions.o
/sha1.lo
/sha1.o
/sha2.lo
/sha2.o
/str2host.lo
/str2host.o
/test/.done-*
/test/result.*
/tsig.lo
/tsig.o
/update.lo
/update.o
/util.lo
/util.o
/wire2host.lo
/wire2host.o
/zone.lo
/zone.o

6
zonemaster-ldns/ldns/.gitmodules vendored Normal file
View File

@@ -0,0 +1,6 @@
[submodule "contrib/DNS-LDNS"]
path = contrib/DNS-LDNS
url = https://github.com/erikoest/DNS-LDNS
[submodule "test/tpkg"]
path = test/tpkg
url = https://github.com/NLnetLabs/tpkg.git

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,26 @@
Copyright (c) 2005,2006, NLnetLabs
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 NLnetLabs 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.

File diff suppressed because it is too large Load Diff

108
zonemaster-ldns/ldns/README Normal file
View File

@@ -0,0 +1,108 @@
Contents:
REQUIREMENTS
INSTALLATION
libdns
examples
drill
INFORMATION FOR SPECIFIC OPERATING SYSTEMS
Mac OS X
Solaris
KNOWN ISSUES
pyldns
Your Support
Project page:
http://www.nlnetlabs.nl/ldns/
On that page you can also subscribe to the ldns mailing list.
* Development
ldns is mainly developed on Linux and FreeBSD. It is regularly tested to
compile on other systems like Solaris and Mac OS X.
REQUIREMENTS
- OpenSSL (Optional, but needed for features like DNSSEC)
- OpenSSL >= 0.9.7f for DANE support
- OpenSSL >= 1.0.0 for ECDSA and GOST support
- libpcap (Optional, but needed for examples/ldns-dpa)
- (GNU) libtool (in OSX, that's glibtool, not libtool)
- GNU make
INSTALLATION
1. Unpack the tarball
2. cd ldns-<VERSION>
3. ./configure --with-examples --with-drill
(optionally compile python bindings too with: --with-pyldns)
4. make
5. make install
* Building from repository
If you are building from the repository you will need to have (gnu)
autotools like libtool and autoreconf installed. A list of all the commands
needed to build everything can be found in README.git. Note that the actual
commands may be a little bit different on your machine. Most notably, you'll
need to run libtoolize (or glibtoolize). If you skip this step, you'll get
an error about missing config.sub.
* Developers
ldns is developed by the ldns team at NLnet Labs. This team currently
consists of:
o Willem Toorop
o Wouter Wijngaards
Former main developers:
o Jelte Jansen
o Miek Gieben
o Matthijs Mekking
* Credits
We have received patches from the following people, thanks!
o Bedrich Kosata
o Erik Rozendaal
o Håkan Olsson
o Jakob Schlyter
o Paul Wouters
o Simon Vallet
o Ondřej Surý
o Karel Slany
o Havard Eidnes
o Leo Baltus
o Dag-Erling Smørgrav
o Felipe Gasper
INFORMATION FOR SPECIFIC OPERATING SYSTEMS
MAC OS X
For MACOSX 10.4 and later, it seems that you have to set the
MACOSX_DEPLOYMENT_TARGET environment variable to 10.4 before running
make. Apparently it defaults to 10.1.
This appears to be a known problem in 10.2 to 10.4, see:
http://developer.apple.com/qa/qa2001/qa1233.html
for more information.
SOLARIS
In Solaris multi-architecture systems (which have both 32-bit and
64-bit support), it can be a bit taxing to convince the system to
compile in 64-bit mode. Jakob Schlyter has kindly contributed a build
script that sets the right build and link options. You can find it in
contrib/build-solaris.sh
KNOWN ISSUES
A complete list of currently known open issues can be found here:
https://github.com/NLnetLabs/ldns/issues
* pyldns
Compiling pyldns produces many ``unused parameter'' warnings. Those are
harmless and may safely be ignored.
Also, when building with SWIG older than 2.0.4, compiling
pyldns produces many ``missing initializer'' warnings. Those are harmless
too.

View File

@@ -0,0 +1,23 @@
# The ldns git repository can found at:
# git.nlnetlabs.nl/ldns/
# small list of commands to build all on a linux system
# libtoolize is needed for most other targets
# on Solaris, and other systems that may not have
# the default 'automake' and 'aclocal' script aliases,
# the correct versions may need to be set. On those
# systems, the 'autoreconf' line should be changed to:
# AUTOMAKE=automake-1.10 ACLOCAL=aclocal-1.10 autoreconf
# older versions of libtoolize do not support --install
# so you might need to remove that (with newer versions
# it is needed)
git submodule update --init
libtoolize -ci
autoreconf -fi
./configure --with-examples --with-drill # --with-pyldns --with-p5-dns-ldns
make
make doc # needs doxygen for the html pages
(cd pcat && autoreconf && ./configure && make)
(cd examples/nsd-test && autoreconf && ./configure && make)

View File

@@ -0,0 +1,8 @@
ldns - snapshot releases
Snapshot releases are not official released. They can be released to
interested parties for development.
Snapshots can be recognized from the date in the tar file name.
They should not be used for packaging in distributions.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,135 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_pkg_swig.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_PKG_SWIG([major.minor.micro], [action-if-found], [action-if-not-found])
#
# DESCRIPTION
#
# This macro searches for a SWIG installation on your system. If found,
# then SWIG is AC_SUBST'd; if not found, then $SWIG is empty. If SWIG is
# found, then SWIG_LIB is set to the SWIG library path, and AC_SUBST'd.
#
# You can use the optional first argument to check if the version of the
# available SWIG is greater than or equal to the value of the argument. It
# should have the format: N[.N[.N]] (N is a number between 0 and 999. Only
# the first N is mandatory.) If the version argument is given (e.g.
# 1.3.17), AX_PKG_SWIG checks that the swig package is this version number
# or higher.
#
# As usual, action-if-found is executed if SWIG is found, otherwise
# action-if-not-found is executed.
#
# In configure.in, use as:
#
# AX_PKG_SWIG(1.3.17, [], [ AC_MSG_ERROR([SWIG is required to build..]) ])
# AX_SWIG_ENABLE_CXX
# AX_SWIG_MULTI_MODULE_SUPPORT
# AX_SWIG_PYTHON
#
# LICENSE
#
# Copyright (c) 2008 Sebastian Huber <sebastian-huber@web.de>
# Copyright (c) 2008 Alan W. Irwin
# Copyright (c) 2008 Rafael Laboissiere <rafael@laboissiere.net>
# Copyright (c) 2008 Andrew Collier
# Copyright (c) 2011 Murray Cumming <murrayc@openismus.com>
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 13
AC_DEFUN([AX_PKG_SWIG],[
# Find path to the "swig" executable.
AC_PATH_PROGS([SWIG],[swig swig3.0 swig2.0])
if test -z "$SWIG" ; then
m4_ifval([$3],[$3],[:])
elif test -n "$1" ; then
AC_MSG_CHECKING([SWIG version])
[swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'`]
AC_MSG_RESULT([$swig_version])
if test -n "$swig_version" ; then
# Calculate the required version number components
[required=$1]
[required_major=`echo $required | sed 's/[^0-9].*//'`]
if test -z "$required_major" ; then
[required_major=0]
fi
[required=`echo $required | sed 's/[0-9]*[^0-9]//'`]
[required_minor=`echo $required | sed 's/[^0-9].*//'`]
if test -z "$required_minor" ; then
[required_minor=0]
fi
[required=`echo $required | sed 's/[0-9]*[^0-9]//'`]
[required_patch=`echo $required | sed 's/[^0-9].*//'`]
if test -z "$required_patch" ; then
[required_patch=0]
fi
# Calculate the available version number components
[available=$swig_version]
[available_major=`echo $available | sed 's/[^0-9].*//'`]
if test -z "$available_major" ; then
[available_major=0]
fi
[available=`echo $available | sed 's/[0-9]*[^0-9]//'`]
[available_minor=`echo $available | sed 's/[^0-9].*//'`]
if test -z "$available_minor" ; then
[available_minor=0]
fi
[available=`echo $available | sed 's/[0-9]*[^0-9]//'`]
[available_patch=`echo $available | sed 's/[^0-9].*//'`]
if test -z "$available_patch" ; then
[available_patch=0]
fi
# Convert the version tuple into a single number for easier comparison.
# Using base 100 should be safe since SWIG internally uses BCD values
# to encode its version number.
required_swig_vernum=`expr $required_major \* 10000 \
\+ $required_minor \* 100 \+ $required_patch`
available_swig_vernum=`expr $available_major \* 10000 \
\+ $available_minor \* 100 \+ $available_patch`
if test $available_swig_vernum -lt $required_swig_vernum; then
AC_MSG_WARN([SWIG version >= $1 is required. You have $swig_version.])
SWIG=''
m4_ifval([$3],[$3],[])
else
AC_MSG_CHECKING([for SWIG library])
SWIG_LIB=`$SWIG -swiglib`
AC_MSG_RESULT([$SWIG_LIB])
m4_ifval([$2],[$2],[])
fi
else
AC_MSG_WARN([cannot determine SWIG version])
SWIG=''
m4_ifval([$3],[$3],[])
fi
fi
AC_SUBST([SWIG_LIB])
])

View File

@@ -0,0 +1,416 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_python_devel.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_PYTHON_DEVEL([version])
#
# DESCRIPTION
#
# Note: Defines as a precious variable "PYTHON_VERSION". Don't override it
# in your configure.ac.
#
# This macro checks for Python and tries to get the include path to
# 'Python.h'. It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LIBS) output
# variables. It also exports $(PYTHON_EXTRA_LIBS) and
# $(PYTHON_EXTRA_LDFLAGS) for embedding Python in your code.
#
# You can search for some particular version of Python by passing a
# parameter to this macro, for example ">= '2.3.1'", or "== '2.4'". Please
# note that you *have* to pass also an operator along with the version to
# match, and pay special attention to the single quotes surrounding the
# version number. Don't use "PYTHON_VERSION" for this: that environment
# variable is declared as precious and thus reserved for the end-user.
#
# This macro should work for all versions of Python >= 2.1.0. As an end
# user, you can disable the check for the python version by setting the
# PYTHON_NOVERSIONCHECK environment variable to something else than the
# empty string.
#
# If you need to use this macro for an older Python version, please
# contact the authors. We're always open for feedback.
#
# LICENSE
#
# Copyright (c) 2009 Sebastian Huber <sebastian-huber@web.de>
# Copyright (c) 2009 Alan W. Irwin
# Copyright (c) 2009 Rafael Laboissiere <rafael@laboissiere.net>
# Copyright (c) 2009 Andrew Collier
# Copyright (c) 2009 Matteo Settenvini <matteo@member.fsf.org>
# Copyright (c) 2009 Horst Knorr <hk_classes@knoda.org>
# Copyright (c) 2013 Daniel Mullner <muellner@math.stanford.edu>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 32
AU_ALIAS([AC_PYTHON_DEVEL], [AX_PYTHON_DEVEL])
AC_DEFUN([AX_PYTHON_DEVEL],[
#
# Allow the use of a (user set) custom python version
#
AC_ARG_VAR([PYTHON_VERSION],[The installed Python
version to use, for example '2.3'. This string
will be appended to the Python interpreter
canonical name.])
AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]])
if test -z "$PYTHON"; then
AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path])
PYTHON_VERSION=""
fi
#
# Check for a version of Python >= 2.1.0
#
AC_MSG_CHECKING([for a version of Python >= '2.1.0'])
ac_supports_python_ver=`$PYTHON -c "import sys; \
ver = sys.version.split ()[[0]]; \
print (ver >= '2.1.0')"`
if test "$ac_supports_python_ver" != "True"; then
if test -z "$PYTHON_NOVERSIONCHECK"; then
AC_MSG_RESULT([no])
AC_MSG_FAILURE([
This version of the AC@&t@_PYTHON_DEVEL macro
doesn't work properly with versions of Python before
2.1.0. You may need to re-run configure, setting the
variables PYTHON_CPPFLAGS, PYTHON_LIBS, PYTHON_SITE_PKG,
PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
to something else than an empty string.
])
else
AC_MSG_RESULT([skip at user request])
fi
else
AC_MSG_RESULT([yes])
fi
#
# If the macro parameter ``version'' is set, honour it.
# A Python shim class, VPy, is used to implement correct version comparisons via
# string expressions, since e.g. a naive textual ">= 2.7.3" won't work for
# Python 2.7.10 (the ".1" being evaluated as less than ".3").
#
if test -n "$1"; then
AC_MSG_CHECKING([for a version of Python $1])
cat << EOF > ax_python_devel_vpy.py
class VPy:
def vtup(self, s):
return tuple(map(int, s.strip().replace("rc", ".").split(".")))
def __init__(self):
import sys
self.vpy = tuple(sys.version_info)
def __eq__(self, s):
return self.vpy == self.vtup(s)
def __ne__(self, s):
return self.vpy != self.vtup(s)
def __lt__(self, s):
return self.vpy < self.vtup(s)
def __gt__(self, s):
return self.vpy > self.vtup(s)
def __le__(self, s):
return self.vpy <= self.vtup(s)
def __ge__(self, s):
return self.vpy >= self.vtup(s)
EOF
ac_supports_python_ver=`$PYTHON -c "import ax_python_devel_vpy; \
ver = ax_python_devel_vpy.VPy(); \
print (ver $1)"`
rm -rf ax_python_devel_vpy*.py* __pycache__/ax_python_devel_vpy*.py*
if test "$ac_supports_python_ver" = "True"; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
AC_MSG_ERROR([this package requires Python $1.
If you have it installed, but it isn't the default Python
interpreter in your system path, please pass the PYTHON_VERSION
variable to configure. See ``configure --help'' for reference.
])
PYTHON_VERSION=""
fi
fi
#
# Check if you have distutils, else fail
#
AC_MSG_CHECKING([for the sysconfig Python package])
ac_sysconfig_result=`$PYTHON -c "import sysconfig" 2>&1`
if test $? -eq 0; then
AC_MSG_RESULT([yes])
IMPORT_SYSCONFIG="import sysconfig"
else
AC_MSG_RESULT([no])
AC_MSG_CHECKING([for the distutils Python package])
ac_sysconfig_result=`$PYTHON -c "from distutils import sysconfig" 2>&1`
if test $? -eq 0; then
AC_MSG_RESULT([yes])
IMPORT_SYSCONFIG="from distutils import sysconfig"
else
AC_MSG_ERROR([cannot import Python module "distutils".
Please check your Python installation. The error was:
$ac_sysconfig_result])
PYTHON_VERSION=""
fi
fi
#
# Check for Python include path
#
AC_MSG_CHECKING([for Python include path])
if test -z "$PYTHON_CPPFLAGS"; then
if test "$IMPORT_SYSCONFIG" = "import sysconfig"; then
# sysconfig module has different functions
python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \
print (sysconfig.get_path ('include'));"`
plat_python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \
print (sysconfig.get_path ('platinclude'));"`
else
# old distutils way
python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \
print (sysconfig.get_python_inc ());"`
plat_python_path=`$PYTHON -c "$IMPORT_SYSCONFIG; \
print (sysconfig.get_python_inc (plat_specific=1));"`
fi
if test -n "${python_path}"; then
if test "${plat_python_path}" != "${python_path}"; then
python_path="-I$python_path -I$plat_python_path"
else
python_path="-I$python_path"
fi
fi
PYTHON_CPPFLAGS=$python_path
fi
AC_MSG_RESULT([$PYTHON_CPPFLAGS])
AC_SUBST([PYTHON_CPPFLAGS])
#
# Check for Python library path
#
AC_MSG_CHECKING([for Python library path])
if test -z "$PYTHON_LIBS"; then
# (makes two attempts to ensure we've got a version number
# from the interpreter)
ac_python_version=`cat<<EOD | $PYTHON -
# join all versioning strings, on some systems
# major/minor numbers could be in different list elements
from sysconfig import *
e = get_config_var('VERSION')
if e is not None:
print(e)
EOD`
if test -z "$ac_python_version"; then
if test -n "$PYTHON_VERSION"; then
ac_python_version=$PYTHON_VERSION
else
ac_python_version=`$PYTHON -c "import sys; \
print ("%d.%d" % sys.version_info[[:2]])"`
fi
fi
# Make the versioning information available to the compiler
AC_DEFINE_UNQUOTED([HAVE_PYTHON], ["$ac_python_version"],
[If available, contains the Python version number currently in use.])
# First, the library directory:
ac_python_libdir=`cat<<EOD | $PYTHON -
# There should be only one
$IMPORT_SYSCONFIG
e = sysconfig.get_config_var('LIBDIR')
if e is not None:
print (e)
EOD`
# Now, for the library:
ac_python_library=`cat<<EOD | $PYTHON -
$IMPORT_SYSCONFIG
c = sysconfig.get_config_vars()
if 'LDVERSION' in c:
print ('python'+c[['LDVERSION']])
else:
print ('python'+c[['VERSION']])
EOD`
# This small piece shamelessly adapted from PostgreSQL python macro;
# credits goes to momjian, I think. I'd like to put the right name
# in the credits, if someone can point me in the right direction... ?
#
if test -n "$ac_python_libdir" -a -n "$ac_python_library"
then
# use the official shared library
ac_python_library=`echo "$ac_python_library" | sed "s/^lib//"`
PYTHON_LIBS="-L$ac_python_libdir -l$ac_python_library"
else
# old way: use libpython from python_configdir
ac_python_libdir=`$PYTHON -c \
"from sysconfig import get_python_lib as f; \
import os; \
print (os.path.join(f(plat_specific=1, standard_lib=1), 'config'));"`
PYTHON_LIBS="-L$ac_python_libdir -lpython$ac_python_version"
fi
if test -z "PYTHON_LIBS"; then
AC_MSG_ERROR([
Cannot determine location of your Python DSO. Please check it was installed with
dynamic libraries enabled, or try setting PYTHON_LIBS by hand.
])
fi
fi
AC_MSG_RESULT([$PYTHON_LIBS])
AC_SUBST([PYTHON_LIBS])
#
# Check for site packages
#
AC_MSG_CHECKING([for Python site-packages path])
if test -z "$PYTHON_SITE_PKG"; then
if test "$IMPORT_SYSCONFIG" = "import sysconfig"; then
PYTHON_SITE_PKG=`$PYTHON -c "
$IMPORT_SYSCONFIG;
if hasattr(sysconfig, 'get_default_scheme'):
scheme = sysconfig.get_default_scheme()
else:
scheme = sysconfig._get_default_scheme()
if scheme == 'posix_local':
# Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/
scheme = 'posix_prefix'
prefix = '$prefix'
if prefix == 'NONE':
prefix = '$ac_default_prefix'
sitedir = sysconfig.get_path('purelib', scheme, vars={'base': prefix})
print(sitedir)"`
else
# distutils.sysconfig way
PYTHON_SITE_PKG=`$PYTHON -c "$IMPORT_SYSCONFIG; \
print (sysconfig.get_python_lib(0,0));"`
fi
fi
AC_MSG_RESULT([$PYTHON_SITE_PKG])
AC_SUBST([PYTHON_SITE_PKG])
#
# Check for platform-specific site packages
#
AC_MSG_CHECKING([for Python platform specific site-packages path])
if test -z "$PYTHON_PLATFORM_SITE_PKG"; then
if test "$IMPORT_SYSCONFIG" = "import sysconfig"; then
PYTHON_PLATFORM_SITE_PKG=`$PYTHON -c "
$IMPORT_SYSCONFIG;
if hasattr(sysconfig, 'get_default_scheme'):
scheme = sysconfig.get_default_scheme()
else:
scheme = sysconfig._get_default_scheme()
if scheme == 'posix_local':
# Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/
scheme = 'posix_prefix'
prefix = '$prefix'
if prefix == 'NONE':
prefix = '$ac_default_prefix'
sitedir = sysconfig.get_path('platlib', scheme, vars={'platbase': prefix})
print(sitedir)"`
else
# distutils.sysconfig way
PYTHON_PLATFORM_SITE_PKG=`$PYTHON -c "$IMPORT_SYSCONFIG; \
print (sysconfig.get_python_lib(1,0));"`
fi
fi
AC_MSG_RESULT([$PYTHON_PLATFORM_SITE_PKG])
AC_SUBST([PYTHON_PLATFORM_SITE_PKG])
#
# libraries which must be linked in when embedding
#
AC_MSG_CHECKING(python extra libraries)
if test -z "$PYTHON_EXTRA_LIBS"; then
PYTHON_EXTRA_LIBS=`$PYTHON -c "$IMPORT_SYSCONFIG; \
conf = sysconfig.get_config_var; \
print (conf('LIBS') + ' ' + conf('SYSLIBS'))"`
fi
AC_MSG_RESULT([$PYTHON_EXTRA_LIBS])
AC_SUBST(PYTHON_EXTRA_LIBS)
#
# linking flags needed when embedding
#
AC_MSG_CHECKING(python extra linking flags)
if test -z "$PYTHON_EXTRA_LDFLAGS"; then
PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "$IMPORT_SYSCONFIG; \
conf = sysconfig.get_config_var; \
print (conf('LINKFORSHARED'))"`
fi
AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS])
AC_SUBST(PYTHON_EXTRA_LDFLAGS)
#
# final check to see if everything compiles alright
#
AC_MSG_CHECKING([consistency of all components of python development environment])
# save current global flags
ac_save_LIBS="$LIBS"
ac_save_LDFLAGS="$LDFLAGS"
ac_save_CPPFLAGS="$CPPFLAGS"
LIBS="$ac_save_LIBS $PYTHON_LIBS $PYTHON_EXTRA_LIBS"
LDFLAGS="$ac_save_LDFLAGS $PYTHON_EXTRA_LDFLAGS"
CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS"
AC_LANG_PUSH([C])
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[#include <Python.h>]],
[[Py_Initialize();]])
],[pythonexists=yes],[pythonexists=no])
AC_LANG_POP([C])
# turn back to default flags
CPPFLAGS="$ac_save_CPPFLAGS"
LIBS="$ac_save_LIBS"
LDFLAGS="$ac_save_LDFLAGS"
AC_MSG_RESULT([$pythonexists])
if test ! "x$pythonexists" = "xyes"; then
AC_MSG_FAILURE([
Could not link test program to Python. Maybe the main Python library has been
installed in some non-standard library path. If so, pass it to configure,
via the LIBS environment variable.
Example: ./configure LIBS="-L/usr/non-standard-path/python/lib"
============================================================================
ERROR!
You probably have to install the development version of the Python package
for your distribution. The exact name of this package varies among them.
============================================================================
])
PYTHON_VERSION=""
fi
#
# all done!
#
])

View File

@@ -0,0 +1,177 @@
/*
* buffer.c -- generic memory buffer .
*
* Copyright (c) 2001-2008, NLnet Labs. All rights reserved.
*
* See LICENSE for the license.
*
*/
#include <ldns/config.h>
#include <ldns/ldns.h>
#include <ldns/buffer.h>
ldns_buffer *
ldns_buffer_new(size_t capacity)
{
ldns_buffer *buffer = LDNS_MALLOC(ldns_buffer);
if (!buffer) {
return NULL;
}
buffer->_data = (uint8_t *) LDNS_XMALLOC(uint8_t, capacity);
if (!buffer->_data) {
LDNS_FREE(buffer);
return NULL;
}
buffer->_position = 0;
buffer->_limit = buffer->_capacity = capacity;
buffer->_fixed = 0;
buffer->_status = LDNS_STATUS_OK;
ldns_buffer_invariant(buffer);
return buffer;
}
void
ldns_buffer_new_frm_data(ldns_buffer *buffer, const void *data, size_t size)
{
assert(data != NULL);
buffer->_position = 0;
buffer->_limit = buffer->_capacity = size;
buffer->_fixed = 0;
buffer->_data = LDNS_XMALLOC(uint8_t, size);
if(!buffer->_data) {
buffer->_status = LDNS_STATUS_MEM_ERR;
return;
}
memcpy(buffer->_data, data, size);
buffer->_status = LDNS_STATUS_OK;
ldns_buffer_invariant(buffer);
}
bool
ldns_buffer_set_capacity(ldns_buffer *buffer, size_t capacity)
{
void *data;
ldns_buffer_invariant(buffer);
assert(buffer->_position <= capacity);
assert(!buffer->_fixed);
data = (uint8_t *) LDNS_XREALLOC(buffer->_data, uint8_t, capacity);
if (!data) {
buffer->_status = LDNS_STATUS_MEM_ERR;
return false;
} else {
buffer->_data = data;
buffer->_limit = buffer->_capacity = capacity;
return true;
}
}
bool
ldns_buffer_reserve(ldns_buffer *buffer, size_t amount)
{
ldns_buffer_invariant(buffer);
if (buffer->_capacity < buffer->_position + amount) {
size_t new_capacity = buffer->_capacity * 3 / 2;
if (new_capacity < buffer->_position + amount) {
new_capacity = buffer->_position + amount;
}
if (!ldns_buffer_set_capacity(buffer, new_capacity)) {
buffer->_status = LDNS_STATUS_MEM_ERR;
return false;
}
}
buffer->_limit = buffer->_capacity;
return true;
}
int
ldns_buffer_printf(ldns_buffer *buffer, const char *format, ...)
{
va_list args;
int written = 0;
size_t remaining;
if (ldns_buffer_status_ok(buffer)) {
ldns_buffer_invariant(buffer);
assert(buffer->_limit == buffer->_capacity);
remaining = ldns_buffer_remaining(buffer);
va_start(args, format);
written = vsnprintf((char *) ldns_buffer_current(buffer), remaining,
format, args);
va_end(args);
if (written == -1) {
buffer->_status = LDNS_STATUS_INTERNAL_ERR;
return -1;
} else if ((size_t) written >= remaining) {
if (!ldns_buffer_reserve(buffer, (size_t) written + 1)) {
buffer->_status = LDNS_STATUS_MEM_ERR;
return -1;
}
va_start(args, format);
written = vsnprintf((char *) ldns_buffer_current(buffer),
ldns_buffer_remaining(buffer), format, args);
va_end(args);
if (written == -1) {
buffer->_status = LDNS_STATUS_INTERNAL_ERR;
return -1;
}
}
buffer->_position += written;
}
return written;
}
void
ldns_buffer_free(ldns_buffer *buffer)
{
if (!buffer) {
return;
}
if (!buffer->_fixed)
LDNS_FREE(buffer->_data);
LDNS_FREE(buffer);
}
void *
ldns_buffer_export(ldns_buffer *buffer)
{
buffer->_fixed = 1;
return buffer->_data;
}
int
ldns_bgetc(ldns_buffer *buffer)
{
if (!ldns_buffer_available_at(buffer, buffer->_position, sizeof(uint8_t))) {
ldns_buffer_set_position(buffer, ldns_buffer_limit(buffer));
/* ldns_buffer_rewind(buffer);*/
return EOF;
}
return (int)ldns_buffer_read_u8(buffer);
}
void
ldns_buffer_copy(ldns_buffer* result, const ldns_buffer* from)
{
size_t tocopy = ldns_buffer_limit(from);
if(tocopy > ldns_buffer_capacity(result))
tocopy = ldns_buffer_capacity(result);
ldns_buffer_clear(result);
ldns_buffer_write(result, ldns_buffer_begin(from), tocopy);
ldns_buffer_flip(result);
}

View File

@@ -0,0 +1,16 @@
#ifdef HAVE_CONFIG_H
#include <ldns/config.h>
#endif
#ifdef HAVE_TIME_H
#include <time.h>
#endif
char *asctime_r(const struct tm *tm, char *buf)
{
/* no thread safety. */
char* result = asctime(tm);
if(buf && result)
strcpy(buf, result);
return result;
}

View File

@@ -0,0 +1,185 @@
/*
* Copyright (c) 1996, 1998 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/*
* Portions Copyright (c) 1995 by International Business Machines, Inc.
*
* International Business Machines, Inc. (hereinafter called IBM) grants
* permission under its copyrights to use, copy, modify, and distribute this
* Software with or without fee, provided that the above copyright notice and
* all paragraphs of this notice appear in all copies, and that the name of IBM
* not be used in connection with the marketing of any product incorporating
* the Software or modifications thereof, without specific, written prior
* permission.
*
* To the extent it has a right to do so, IBM grants an immunity from suit
* under its patents, if any, for the use, sale or manufacture of products to
* the extent that such products are used for performing Domain Name System
* dynamic updates in TCP/IP networks by means of the Software. No immunity is
* granted for any product per se or for any other function of any product.
*
* THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
* DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/
#include <ldns/config.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
static const char Base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char Pad64 = '=';
/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
The following encoding technique is taken from RFC 1521 by Borenstein
and Freed. It is reproduced here in a slightly edited form for
convenience.
A 65-character subset of US-ASCII is used, enabling 6 bits to be
represented per printable character. (The extra 65th character, "=",
is used to signify a special processing function.)
The encoding process represents 24-bit groups of input bits as output
strings of 4 encoded characters. Proceeding from left to right, a
24-bit input group is formed by concatenating 3 8-bit input groups.
These 24 bits are then treated as 4 concatenated 6-bit groups, each
of which is translated into a single digit in the base64 alphabet.
Each 6-bit group is used as an index into an array of 64 printable
characters. The character referenced by the index is placed in the
output string.
Table 1: The Base64 Alphabet
Value Encoding Value Encoding Value Encoding Value Encoding
0 A 17 R 34 i 51 z
1 B 18 S 35 j 52 0
2 C 19 T 36 k 53 1
3 D 20 U 37 l 54 2
4 E 21 V 38 m 55 3
5 F 22 W 39 n 56 4
6 G 23 X 40 o 57 5
7 H 24 Y 41 p 58 6
8 I 25 Z 42 q 59 7
9 J 26 a 43 r 60 8
10 K 27 b 44 s 61 9
11 L 28 c 45 t 62 +
12 M 29 d 46 u 63 /
13 N 30 e 47 v
14 O 31 f 48 w (pad) =
15 P 32 g 49 x
16 Q 33 h 50 y
Special processing is performed if fewer than 24 bits are available
at the end of the data being encoded. A full encoding quantum is
always completed at the end of a quantity. When fewer than 24 input
bits are available in an input group, zero bits are added (on the
right) to form an integral number of 6-bit groups. Padding at the
end of the data is performed using the '=' character.
Since all base64 input is an integral number of octets, only the
-------------------------------------------------
following cases can arise:
(1) the final quantum of encoding input is an integral
multiple of 24 bits; here, the final unit of encoded
output will be an integral multiple of 4 characters
with no "=" padding,
(2) the final quantum of encoding input is exactly 8 bits;
here, the final unit of encoded output will be two
characters followed by two "=" padding characters, or
(3) the final quantum of encoding input is exactly 16 bits;
here, the final unit of encoded output will be three
characters followed by one "=" padding character.
*/
int
ldns_b64_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize) {
size_t datalength = 0;
uint8_t input[3];
uint8_t output[4];
size_t i;
if (srclength == 0) {
if (targsize > 0) {
target[0] = '\0';
return 0;
} else {
return -1;
}
}
while (2 < srclength) {
input[0] = *src++;
input[1] = *src++;
input[2] = *src++;
srclength -= 3;
output[0] = input[0] >> 2;
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
output[3] = input[2] & 0x3f;
assert(output[0] < 64);
assert(output[1] < 64);
assert(output[2] < 64);
assert(output[3] < 64);
if (datalength + 4 > targsize) {
return (-1);
}
target[datalength++] = Base64[output[0]];
target[datalength++] = Base64[output[1]];
target[datalength++] = Base64[output[2]];
target[datalength++] = Base64[output[3]];
}
/* Now we worry about padding. */
if (0 != srclength) {
/* Get what's left. */
input[0] = input[1] = input[2] = (uint8_t) '\0';
for (i = 0; i < srclength; i++)
input[i] = *src++;
output[0] = input[0] >> 2;
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
assert(output[0] < 64);
assert(output[1] < 64);
assert(output[2] < 64);
if (datalength + 4 > targsize) {
return (-2);
}
target[datalength++] = Base64[output[0]];
target[datalength++] = Base64[output[1]];
if (srclength == 1) {
target[datalength++] = Pad64;
} else {
target[datalength++] = Base64[output[2]];
}
target[datalength++] = Pad64;
}
if (datalength >= targsize) {
return (-3);
}
target[datalength] = '\0'; /* Returned value doesn't count \0. */
return (int) (datalength);
}

View File

@@ -0,0 +1,244 @@
/*
* Copyright (c) 1996, 1998 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/*
* Portions Copyright (c) 1995 by International Business Machines, Inc.
*
* International Business Machines, Inc. (hereinafter called IBM) grants
* permission under its copyrights to use, copy, modify, and distribute this
* Software with or without fee, provided that the above copyright notice and
* all paragraphs of this notice appear in all copies, and that the name of IBM
* not be used in connection with the marketing of any product incorporating
* the Software or modifications thereof, without specific, written prior
* permission.
*
* To the extent it has a right to do so, IBM grants an immunity from suit
* under its patents, if any, for the use, sale or manufacture of products to
* the extent that such products are used for performing Domain Name System
* dynamic updates in TCP/IP networks by means of the Software. No immunity is
* granted for any product per se or for any other function of any product.
*
* THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
* DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/
#include <ldns/config.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
static const char Base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char Pad64 = '=';
/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
The following encoding technique is taken from RFC 1521 by Borenstein
and Freed. It is reproduced here in a slightly edited form for
convenience.
A 65-character subset of US-ASCII is used, enabling 6 bits to be
represented per printable character. (The extra 65th character, "=",
is used to signify a special processing function.)
The encoding process represents 24-bit groups of input bits as output
strings of 4 encoded characters. Proceeding from left to right, a
24-bit input group is formed by concatenating 3 8-bit input groups.
These 24 bits are then treated as 4 concatenated 6-bit groups, each
of which is translated into a single digit in the base64 alphabet.
Each 6-bit group is used as an index into an array of 64 printable
characters. The character referenced by the index is placed in the
output string.
Table 1: The Base64 Alphabet
Value Encoding Value Encoding Value Encoding Value Encoding
0 A 17 R 34 i 51 z
1 B 18 S 35 j 52 0
2 C 19 T 36 k 53 1
3 D 20 U 37 l 54 2
4 E 21 V 38 m 55 3
5 F 22 W 39 n 56 4
6 G 23 X 40 o 57 5
7 H 24 Y 41 p 58 6
8 I 25 Z 42 q 59 7
9 J 26 a 43 r 60 8
10 K 27 b 44 s 61 9
11 L 28 c 45 t 62 +
12 M 29 d 46 u 63 /
13 N 30 e 47 v
14 O 31 f 48 w (pad) =
15 P 32 g 49 x
16 Q 33 h 50 y
Special processing is performed if fewer than 24 bits are available
at the end of the data being encoded. A full encoding quantum is
always completed at the end of a quantity. When fewer than 24 input
bits are available in an input group, zero bits are added (on the
right) to form an integral number of 6-bit groups. Padding at the
end of the data is performed using the '=' character.
Since all base64 input is an integral number of octets, only the
-------------------------------------------------
following cases can arise:
(1) the final quantum of encoding input is an integral
multiple of 24 bits; here, the final unit of encoded
output will be an integral multiple of 4 characters
with no "=" padding,
(2) the final quantum of encoding input is exactly 8 bits;
here, the final unit of encoded output will be two
characters followed by two "=" padding characters, or
(3) the final quantum of encoding input is exactly 16 bits;
here, the final unit of encoded output will be three
characters followed by one "=" padding character.
*/
/* skips all whitespace anywhere.
converts characters, four at a time, starting at (or after)
src from base - 64 numbers into three 8 bit bytes in the target area.
it returns the number of data bytes stored at the target, or -1 on error.
*/
int
ldns_b64_pton(char const *origsrc, uint8_t *target, size_t targsize)
{
unsigned char const* src = (unsigned char*)origsrc;
int tarindex, state, ch;
char *pos;
state = 0;
tarindex = 0;
if (strlen(origsrc) == 0) {
return 0;
}
while ((ch = *src++) != '\0') {
if (isspace((unsigned char)ch)) /* Skip whitespace anywhere. */
continue;
if (ch == Pad64)
break;
pos = strchr(Base64, ch);
if (pos == 0) {
/* A non-base64 character. */
return (-1);
}
switch (state) {
case 0:
if (target) {
if ((size_t)tarindex >= targsize)
return (-1);
target[tarindex] = (pos - Base64) << 2;
}
state = 1;
break;
case 1:
if (target) {
if ((size_t)tarindex + 1 >= targsize)
return (-1);
target[tarindex] |= (pos - Base64) >> 4;
target[tarindex+1] = ((pos - Base64) & 0x0f)
<< 4 ;
}
tarindex++;
state = 2;
break;
case 2:
if (target) {
if ((size_t)tarindex + 1 >= targsize)
return (-1);
target[tarindex] |= (pos - Base64) >> 2;
target[tarindex+1] = ((pos - Base64) & 0x03)
<< 6;
}
tarindex++;
state = 3;
break;
case 3:
if (target) {
if ((size_t)tarindex >= targsize)
return (-1);
target[tarindex] |= (pos - Base64);
}
tarindex++;
state = 0;
break;
default:
abort();
}
}
/*
* We are done decoding Base-64 chars. Let's see if we ended
* on a byte boundary, and/or with erroneous trailing characters.
*/
if (ch == Pad64) { /* We got a pad char. */
ch = *src++; /* Skip it, get next. */
switch (state) {
case 0: /* Invalid = in first position */
case 1: /* Invalid = in second position */
return (-1);
case 2: /* Valid, means one byte of info */
/* Skip any number of spaces. */
for ((void)NULL; ch != '\0'; ch = *src++)
if (!isspace((unsigned char)ch))
break;
/* Make sure there is another trailing = sign. */
if (ch != Pad64)
return (-1);
ch = *src++; /* Skip the = */
/* Fall through to "single trailing =" case. */
/* FALLTHROUGH */
case 3: /* Valid, means two bytes of info */
/*
* We know this char is an =. Is there anything but
* whitespace after it?
*/
for ((void)NULL; ch != '\0'; ch = *src++)
if (!isspace((unsigned char)ch))
return (-1);
/*
* Now make sure for cases 2 and 3 that the "extra"
* bits that slopped past the last full byte were
* zeros. If we don't check them, they become a
* subliminal channel.
*/
if (target && target[tarindex] != 0)
return (-1);
}
} else {
/*
* We ended by seeing the end of the string. Make sure we
* have no partial bytes lying around.
*/
if (state != 0)
return (-1);
}
return (tarindex);
}

View File

@@ -0,0 +1,24 @@
/* Just a replacement, if the original malloc is not
GNU-compliant. See autoconf documentation. */
#if HAVE_CONFIG_H
#include <ldns/config.h>
#endif
void *calloc();
#if !HAVE_BZERO && HAVE_MEMSET
# define bzero(buf, bytes) ((void) memset (buf, 0, bytes))
#endif
void *
calloc(size_t num, size_t size)
{
void *new = malloc(num * size);
if (!new) {
return NULL;
}
bzero(new, num * size);
return new;
}

View File

@@ -0,0 +1,16 @@
#ifdef HAVE_CONFIG_H
#include <ldns/config.h>
#endif
#ifdef HAVE_TIME_H
#include <time.h>
#endif
char *ctime_r(const time_t *timep, char *buf)
{
/* no thread safety. */
char* result = ctime(timep);
if(buf && result)
strcpy(buf, result);
return result;
}

View File

@@ -0,0 +1,229 @@
/* From openssh 4.3p2 filename openbsd-compat/fake-rfc2553.h */
/*
* Copyright (C) 2000-2003 Damien Miller. All rights reserved.
* Copyright (C) 1999 WIDE Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the project 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 PROJECT 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 PROJECT 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.
*/
/*
* Pseudo-implementation of RFC2553 name / address resolution functions
*
* But these functions are not implemented correctly. The minimum subset
* is implemented for ssh use only. For example, this routine assumes
* that ai_family is AF_INET. Don't use it for another purpose.
*/
#include <ldns/config.h>
#include <ldns/common.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "compat/fake-rfc2553.h"
#ifndef HAVE_GETNAMEINFO
int getnameinfo(const struct sockaddr *sa, size_t ATTR_UNUSED(salen), char *host,
size_t hostlen, char *serv, size_t servlen, int flags)
{
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
struct hostent *hp;
char tmpserv[16];
if (serv != NULL) {
snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port));
if (strlcpy(serv, tmpserv, servlen) >= servlen)
return (EAI_MEMORY);
}
if (host != NULL) {
if (flags & NI_NUMERICHOST) {
if (strlcpy(host, inet_ntoa(sin->sin_addr),
hostlen) >= hostlen)
return (EAI_MEMORY);
else
return (0);
} else {
hp = gethostbyaddr((char *)&sin->sin_addr,
sizeof(struct in_addr), AF_INET);
if (hp == NULL)
return (EAI_NODATA);
if (strlcpy(host, hp->h_name, hostlen) >= hostlen)
return (EAI_MEMORY);
else
return (0);
}
}
return (0);
}
#endif /* !HAVE_GETNAMEINFO */
#ifndef HAVE_GAI_STRERROR
#ifdef HAVE_CONST_GAI_STRERROR_PROTO
const char *
#else
char *
#endif
gai_strerror(int err)
{
switch (err) {
case EAI_NODATA:
return ("no address associated with name");
case EAI_MEMORY:
return ("memory allocation failure.");
case EAI_NONAME:
return ("nodename nor servname provided, or not known");
default:
return ("unknown/invalid error.");
}
}
#endif /* !HAVE_GAI_STRERROR */
#ifndef HAVE_FREEADDRINFO
void
freeaddrinfo(struct addrinfo *ai)
{
struct addrinfo *next;
for(; ai != NULL;) {
next = ai->ai_next;
free(ai);
ai = next;
}
}
#endif /* !HAVE_FREEADDRINFO */
#ifndef HAVE_GETADDRINFO
static struct
addrinfo *malloc_ai(int port, u_long addr, const struct addrinfo *hints)
{
struct addrinfo *ai;
ai = malloc(sizeof(*ai) + sizeof(struct sockaddr_in));
if (ai == NULL)
return (NULL);
memset(ai, '\0', sizeof(*ai) + sizeof(struct sockaddr_in));
ai->ai_addr = (struct sockaddr *)(ai + 1);
/* XXX -- ssh doesn't use sa_len */
ai->ai_addrlen = sizeof(struct sockaddr_in);
ai->ai_addr->sa_family = ai->ai_family = AF_INET;
((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;
((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
/* XXX: the following is not generally correct, but does what we want */
if (hints->ai_socktype)
ai->ai_socktype = hints->ai_socktype;
else
ai->ai_socktype = SOCK_STREAM;
if (hints->ai_protocol)
ai->ai_protocol = hints->ai_protocol;
return (ai);
}
int
getaddrinfo(const char *hostname, const char *servname,
const struct addrinfo *hints, struct addrinfo **res)
{
struct hostent *hp;
struct servent *sp;
struct in_addr in;
int i;
long int port;
u_long addr;
port = 0;
if (servname != NULL) {
char *cp;
port = strtol(servname, &cp, 10);
if (port > 0 && port <= 65535 && *cp == '\0')
port = htons(port);
else if ((sp = getservbyname(servname, NULL)) != NULL)
port = sp->s_port;
else
port = 0;
}
if (hints && hints->ai_flags & AI_PASSIVE) {
addr = htonl(0x00000000);
if (hostname && inet_aton(hostname, &in) != 0)
addr = in.s_addr;
*res = malloc_ai(port, addr, hints);
if (*res == NULL)
return (EAI_MEMORY);
return (0);
}
if (!hostname) {
*res = malloc_ai(port, htonl(0x7f000001), hints);
if (*res == NULL)
return (EAI_MEMORY);
return (0);
}
if (inet_aton(hostname, &in)) {
*res = malloc_ai(port, in.s_addr, hints);
if (*res == NULL)
return (EAI_MEMORY);
return (0);
}
/* Don't try DNS if AI_NUMERICHOST is set */
if (hints && hints->ai_flags & AI_NUMERICHOST)
return (EAI_NONAME);
hp = gethostbyname(hostname);
if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
struct addrinfo *cur, *prev;
cur = prev = *res = NULL;
for (i = 0; hp->h_addr_list[i]; i++) {
struct in_addr *in = (struct in_addr *)hp->h_addr_list[i];
cur = malloc_ai(port, in->s_addr, hints);
if (cur == NULL) {
if (*res != NULL)
freeaddrinfo(*res);
return (EAI_MEMORY);
}
if (prev)
prev->ai_next = cur;
else
*res = cur;
prev = cur;
}
return (0);
}
return (EAI_NODATA);
}
#endif /* !HAVE_GETADDRINFO */

View File

@@ -0,0 +1,183 @@
/* From openssh 4.3p2 filename openbsd-compat/fake-rfc2553.h */
/*
* Copyright (C) 2000-2003 Damien Miller. All rights reserved.
* Copyright (C) 1999 WIDE Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the project 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 PROJECT 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 PROJECT 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.
*/
/*
* Pseudo-implementation of RFC2553 name / address resolution functions
*
* But these functions are not implemented correctly. The minimum subset
* is implemented for ssh use only. For example, this routine assumes
* that ai_family is AF_INET. Don't use it for another purpose.
*/
#ifndef _FAKE_RFC2553_H
#define _FAKE_RFC2553_H
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <limits.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* First, socket and INET6 related definitions
*/
#ifndef HAVE_STRUCT_SOCKADDR_STORAGE
#ifndef _SS_MAXSIZE
# define _SS_MAXSIZE 128 /* Implementation specific max size */
# define _SS_PADSIZE (_SS_MAXSIZE - sizeof (struct sockaddr))
struct sockaddr_storage {
struct sockaddr ss_sa;
char __ss_pad2[_SS_PADSIZE];
};
# define ss_family ss_sa.sa_family
#endif /* _SS_MAXSIZE */
#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */
#ifndef IN6_IS_ADDR_LOOPBACK
# define IN6_IS_ADDR_LOOPBACK(a) \
(((uint32_t *)(a))[0] == 0 && ((uint32_t *)(a))[1] == 0 && \
((uint32_t *)(a))[2] == 0 && ((uint32_t *)(a))[3] == htonl(1))
#endif /* !IN6_IS_ADDR_LOOPBACK */
#ifndef HAVE_STRUCT_IN6_ADDR
struct in6_addr {
uint8_t s6_addr[16];
};
#endif /* !HAVE_STRUCT_IN6_ADDR */
#ifndef HAVE_STRUCT_SOCKADDR_IN6
struct sockaddr_in6 {
unsigned short sin6_family;
uint16_t sin6_port;
uint32_t sin6_flowinfo;
struct in6_addr sin6_addr;
};
#endif /* !HAVE_STRUCT_SOCKADDR_IN6 */
#ifndef AF_INET6
/* Define it to something that should never appear */
#define AF_INET6 AF_MAX
#endif
/*
* Next, RFC2553 name / address resolution API
*/
#ifndef NI_NUMERICHOST
# define NI_NUMERICHOST (1)
#endif
#ifndef NI_NAMEREQD
# define NI_NAMEREQD (1<<1)
#endif
#ifndef NI_NUMERICSERV
# define NI_NUMERICSERV (1<<2)
#endif
#ifndef AI_PASSIVE
# define AI_PASSIVE (1)
#endif
#ifndef AI_CANONNAME
# define AI_CANONNAME (1<<1)
#endif
#ifndef AI_NUMERICHOST
# define AI_NUMERICHOST (1<<2)
#endif
#ifndef NI_MAXSERV
# define NI_MAXSERV 32
#endif /* !NI_MAXSERV */
#ifndef NI_MAXHOST
# define NI_MAXHOST 1025
#endif /* !NI_MAXHOST */
#ifndef INT_MAX
#define INT_MAX 0xffffffff
#endif
#ifndef EAI_NODATA
# define EAI_NODATA (INT_MAX - 1)
#endif
#ifndef EAI_MEMORY
# define EAI_MEMORY (INT_MAX - 2)
#endif
#ifndef EAI_NONAME
# define EAI_NONAME (INT_MAX - 3)
#endif
#ifndef EAI_SYSTEM
# define EAI_SYSTEM (INT_MAX - 4)
#endif
#ifndef HAVE_STRUCT_ADDRINFO
struct addrinfo {
int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
int ai_family; /* PF_xxx */
int ai_socktype; /* SOCK_xxx */
int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
size_t ai_addrlen; /* length of ai_addr */
char *ai_canonname; /* canonical name for hostname */
struct sockaddr *ai_addr; /* binary address */
struct addrinfo *ai_next; /* next structure in linked list */
};
#endif /* !HAVE_STRUCT_ADDRINFO */
#ifndef HAVE_GETADDRINFO
#ifdef getaddrinfo
# undef getaddrinfo
#endif
#define getaddrinfo(a,b,c,d) (ssh_getaddrinfo(a,b,c,d))
int getaddrinfo(const char *, const char *,
const struct addrinfo *, struct addrinfo **);
#endif /* !HAVE_GETADDRINFO */
#if !defined(HAVE_GAI_STRERROR) && !defined(HAVE_CONST_GAI_STRERROR_PROTO)
#define gai_strerror(a) (ssh_gai_strerror(a))
char *gai_strerror(int);
#endif /* !HAVE_GAI_STRERROR */
#ifndef HAVE_FREEADDRINFO
#define freeaddrinfo(a) (ssh_freeaddrinfo(a))
void freeaddrinfo(struct addrinfo *);
#endif /* !HAVE_FREEADDRINFO */
#ifndef HAVE_GETNAMEINFO
#define getnameinfo(a,b,c,d,e,f,g) (ssh_getnameinfo(a,b,c,d,e,f,g))
int getnameinfo(const struct sockaddr *, size_t, char *, size_t,
char *, size_t, int);
#endif /* !HAVE_GETNAMEINFO */
#ifdef __cplusplus
}
#endif
#endif /* !_FAKE_RFC2553_H */

View File

@@ -0,0 +1,14 @@
#ifdef HAVE_CONFIG_H
#include <ldns/config.h>
#endif
#ifdef HAVE_TIME_H
#include <time.h>
#endif
struct tm *gmtime_r(const time_t *timep, struct tm *result)
{
/* no thread safety. */
*result = *gmtime(timep);
return result;
}

View File

@@ -0,0 +1,182 @@
/* From openssh4.3p2 compat/inet_aton.c */
/*
* Copyright (c) 1983, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
* -
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies, and that
* the name of Digital Equipment Corporation not be used in advertising or
* publicity pertaining to distribution of the document or software without
* specific, written prior permission.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
* -
* --Copyright--
*/
/* OPENBSD ORIGINAL: lib/libc/net/inet_addr.c */
#include <ldns/config.h>
#if !defined(HAVE_INET_ATON)
#include <sys/types.h>
#include <sys/param.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include <ctype.h>
#if 0
/*
* Ascii internet address interpretation routine.
* The value returned is in network order.
*/
in_addr_t
inet_addr(const char *cp)
{
struct in_addr val;
if (inet_aton(cp, &val))
return (val.s_addr);
return (INADDR_NONE);
}
#endif
/*
* Check whether "cp" is a valid ascii representation
* of an Internet address and convert to a binary address.
* Returns 1 if the address is valid, 0 if not.
* This replaces inet_addr, the return value from which
* cannot distinguish between failure and a local broadcast address.
*/
int
inet_aton(const char *cp, struct in_addr *addr)
{
uint32_t val;
int base, n;
char c;
unsigned int parts[4];
unsigned int *pp = parts;
c = *cp;
for (;;) {
/*
* Collect number up to ``.''.
* Values are specified as for C:
* 0x=hex, 0=octal, isdigit=decimal.
*/
if (!isdigit((int) c))
return (0);
val = 0; base = 10;
if (c == '0') {
c = *++cp;
if (c == 'x' || c == 'X')
base = 16, c = *++cp;
else
base = 8;
}
for (;;) {
if (isascii((int) c) && isdigit((int) c)) {
val = (val * base) + (c - '0');
c = *++cp;
} else if (base == 16 && isascii((int) c) && isxdigit((int) c)) {
val = (val << 4) |
(c + 10 - (islower((int) c) ? 'a' : 'A'));
c = *++cp;
} else
break;
}
if (c == '.') {
/*
* Internet format:
* a.b.c.d
* a.b.c (with c treated as 16 bits)
* a.b (with b treated as 24 bits)
*/
if (pp >= parts + 3)
return (0);
*pp++ = val;
c = *++cp;
} else
break;
}
/*
* Check for trailing characters.
*/
if (c != '\0' && (!isascii((int) c) || !isspace((int) c)))
return (0);
/*
* Concoct the address according to
* the number of parts specified.
*/
n = pp - parts + 1;
switch (n) {
case 0:
return (0); /* initial nondigit */
case 1: /* a -- 32 bits */
break;
case 2: /* a.b -- 8.24 bits */
if ((val > 0xffffff) || (parts[0] > 0xff))
return (0);
val |= parts[0] << 24;
break;
case 3: /* a.b.c -- 8.8.16 bits */
if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff))
return (0);
val |= (parts[0] << 24) | (parts[1] << 16);
break;
case 4: /* a.b.c.d -- 8.8.8.8 bits */
if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff))
return (0);
val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
break;
}
if (addr)
addr->s_addr = htonl(val);
return (1);
}
#endif /* !defined(HAVE_INET_ATON) */

View File

@@ -0,0 +1,218 @@
/* From openssh 4.3p2 compat/inet_ntop.c */
/* Copyright (c) 1996 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/* OPENBSD ORIGINAL: lib/libc/net/inet_ntop.c */
#include <ldns/config.h>
#ifndef HAVE_INET_NTOP
#include <sys/param.h>
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#include <string.h>
#include <errno.h>
#include <stdio.h>
#ifndef IN6ADDRSZ
#define IN6ADDRSZ 16 /* IPv6 T_AAAA */
#endif
#ifndef INT16SZ
#define INT16SZ 2 /* for systems without 16-bit ints */
#endif
/*
* WARNING: Don't even consider trying to compile this on a system where
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
*/
static const char *inet_ntop4(const u_char *src, char *dst, size_t size);
static const char *inet_ntop6(const u_char *src, char *dst, size_t size);
/* char *
* inet_ntop(af, src, dst, size)
* convert a network format address to presentation format.
* return:
* pointer to presentation format address (`dst'), or NULL (see errno).
* author:
* Paul Vixie, 1996.
*/
const char *
inet_ntop(int af, const void *src, char *dst, size_t size)
{
switch (af) {
case AF_INET:
return (inet_ntop4(src, dst, size));
case AF_INET6:
return (inet_ntop6(src, dst, size));
default:
#ifdef EAFNOSUPPORT
errno = EAFNOSUPPORT;
#else
errno = ENOSYS;
#endif
return (NULL);
}
/* NOTREACHED */
}
/* const char *
* inet_ntop4(src, dst, size)
* format an IPv4 address, more or less like inet_ntoa()
* return:
* `dst' (as a const)
* notes:
* (1) uses no statics
* (2) takes a u_char* not an in_addr as input
* author:
* Paul Vixie, 1996.
*/
static const char *
inet_ntop4(const u_char *src, char *dst, size_t size)
{
static const char fmt[] = "%u.%u.%u.%u";
char tmp[sizeof "255.255.255.255"];
int l;
l = snprintf(tmp, size, fmt, src[0], src[1], src[2], src[3]);
if (l <= 0 || l >= (int)size) {
errno = ENOSPC;
return (NULL);
}
strlcpy(dst, tmp, size);
return (dst);
}
/* const char *
* inet_ntop6(src, dst, size)
* convert IPv6 binary address into presentation (printable) format
* author:
* Paul Vixie, 1996.
*/
static const char *
inet_ntop6(const u_char *src, char *dst, size_t size)
{
/*
* Note that int32_t and int16_t need only be "at least" large enough
* to contain a value of the specified size. On some systems, like
* Crays, there is no such thing as an integer variable with 16 bits.
* Keep this in mind if you think this function should have been coded
* to use pointer overlays. All the world's not a VAX.
*/
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
char *tp, *ep;
struct { int base, len; } best, cur;
u_int words[IN6ADDRSZ / INT16SZ];
int i;
int advance;
/*
* Preprocess:
* Copy the input (bytewise) array into a wordwise array.
* Find the longest run of 0x00's in src[] for :: shorthanding.
*/
memset(words, '\0', sizeof words);
for (i = 0; i < IN6ADDRSZ; i++)
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
best.base = -1;
best.len = 0;
cur.base = -1;
cur.len = 0;
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
if (words[i] == 0) {
if (cur.base == -1)
cur.base = i, cur.len = 1;
else
cur.len++;
} else {
if (cur.base != -1) {
if (best.base == -1 || cur.len > best.len)
best = cur;
cur.base = -1;
}
}
}
if (cur.base != -1) {
if (best.base == -1 || cur.len > best.len)
best = cur;
}
if (best.base != -1 && best.len < 2)
best.base = -1;
/*
* Format the result.
*/
tp = tmp;
ep = tmp + sizeof(tmp);
for (i = 0; i < (IN6ADDRSZ / INT16SZ) && tp < ep; i++) {
/* Are we inside the best run of 0x00's? */
if (best.base != -1 && i >= best.base &&
i < (best.base + best.len)) {
if (i == best.base) {
if (tp + 1 >= ep)
return (NULL);
*tp++ = ':';
}
continue;
}
/* Are we following an initial run of 0x00s or any real hex? */
if (i != 0) {
if (tp + 1 >= ep)
return (NULL);
*tp++ = ':';
}
/* Is this address an encapsulated IPv4? */
if (i == 6 && best.base == 0 &&
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
if (!inet_ntop4(src+12, tp, (size_t)(ep - tp)))
return (NULL);
tp += strlen(tp);
break;
}
advance = snprintf(tp, ep - tp, "%x", words[i]);
if (advance <= 0 || advance >= ep - tp)
return (NULL);
tp += advance;
}
/* Was it a trailing run of 0x00's? */
if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) {
if (tp + 1 >= ep)
return (NULL);
*tp++ = ':';
}
if (tp + 1 >= ep)
return (NULL);
*tp++ = '\0';
/*
* Check for overflow, copy, and we're done.
*/
if ((size_t)(tp - tmp) > size) {
errno = ENOSPC;
return (NULL);
}
strlcpy(dst, tmp, size);
return (dst);
}
#endif /* !HAVE_INET_NTOP */

View File

@@ -0,0 +1,230 @@
/* $KAME: inet_pton.c,v 1.5 2001/08/20 02:32:40 itojun Exp $ */
/* Copyright (c) 1996 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#include <ldns/config.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
/*
* WARNING: Don't even consider trying to compile this on a system where
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
*/
static int inet_pton4 (const char *src, uint8_t *dst);
static int inet_pton6 (const char *src, uint8_t *dst);
/*
*
* The definitions we might miss.
*
*/
#ifndef NS_INT16SZ
#define NS_INT16SZ 2
#endif
#ifndef NS_IN6ADDRSZ
#define NS_IN6ADDRSZ 16
#endif
#ifndef NS_INADDRSZ
#define NS_INADDRSZ 4
#endif
/* int
* inet_pton(af, src, dst)
* convert from presentation format (which usually means ASCII printable)
* to network format (which is usually some kind of binary format).
* return:
* 1 if the address was valid for the specified address family
* 0 if the address wasn't valid (`dst' is untouched in this case)
* -1 if some other error occurred (`dst' is untouched in this case, too)
* author:
* Paul Vixie, 1996.
*/
int
inet_pton(af, src, dst)
int af;
const char *src;
void *dst;
{
switch (af) {
case AF_INET:
return (inet_pton4(src, dst));
case AF_INET6:
return (inet_pton6(src, dst));
default:
#ifdef EAFNOSUPPORT
errno = EAFNOSUPPORT;
#else
errno = ENOSYS;
#endif
return (-1);
}
/* NOTREACHED */
}
/* int
* inet_pton4(src, dst)
* like inet_aton() but without all the hexadecimal and shorthand.
* return:
* 1 if `src' is a valid dotted quad, else 0.
* notice:
* does not touch `dst' unless it's returning 1.
* author:
* Paul Vixie, 1996.
*/
static int
inet_pton4(src, dst)
const char *src;
uint8_t *dst;
{
static const char digits[] = "0123456789";
int saw_digit, octets, ch;
uint8_t tmp[NS_INADDRSZ], *tp;
saw_digit = 0;
octets = 0;
*(tp = tmp) = 0;
while ((ch = *src++) != '\0') {
const char *pch;
if ((pch = strchr(digits, ch)) != NULL) {
uint32_t new = *tp * 10 + (pch - digits);
if (new > 255)
return (0);
*tp = new;
if (! saw_digit) {
if (++octets > 4)
return (0);
saw_digit = 1;
}
} else if (ch == '.' && saw_digit) {
if (octets == 4)
return (0);
*++tp = 0;
saw_digit = 0;
} else
return (0);
}
if (octets < 4)
return (0);
memcpy(dst, tmp, NS_INADDRSZ);
return (1);
}
/* int
* inet_pton6(src, dst)
* convert presentation level address to network order binary form.
* return:
* 1 if `src' is a valid [RFC1884 2.2] address, else 0.
* notice:
* (1) does not touch `dst' unless it's returning 1.
* (2) :: in a full address is silently ignored.
* credit:
* inspired by Mark Andrews.
* author:
* Paul Vixie, 1996.
*/
static int
inet_pton6(src, dst)
const char *src;
uint8_t *dst;
{
static const char xdigits_l[] = "0123456789abcdef",
xdigits_u[] = "0123456789ABCDEF";
uint8_t tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
const char *xdigits, *curtok;
int ch, saw_xdigit;
uint32_t val;
memset((tp = tmp), '\0', NS_IN6ADDRSZ);
endp = tp + NS_IN6ADDRSZ;
colonp = NULL;
/* Leading :: requires some special handling. */
if (*src == ':')
if (*++src != ':')
return (0);
curtok = src;
saw_xdigit = 0;
val = 0;
while ((ch = *src++) != '\0') {
const char *pch;
if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
pch = strchr((xdigits = xdigits_u), ch);
if (pch != NULL) {
val <<= 4;
val |= (pch - xdigits);
if (val > 0xffff)
return (0);
saw_xdigit = 1;
continue;
}
if (ch == ':') {
curtok = src;
if (!saw_xdigit) {
if (colonp)
return (0);
colonp = tp;
continue;
}
if (tp + NS_INT16SZ > endp)
return (0);
*tp++ = (uint8_t) (val >> 8) & 0xff;
*tp++ = (uint8_t) val & 0xff;
saw_xdigit = 0;
val = 0;
continue;
}
if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
inet_pton4(curtok, tp) > 0) {
tp += NS_INADDRSZ;
saw_xdigit = 0;
break; /* '\0' was seen by inet_pton4(). */
}
return (0);
}
if (saw_xdigit) {
if (tp + NS_INT16SZ > endp)
return (0);
*tp++ = (uint8_t) (val >> 8) & 0xff;
*tp++ = (uint8_t) val & 0xff;
}
if (colonp != NULL) {
/*
* Since some memmove()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand.
*/
const int n = tp - colonp;
int i;
for (i = 1; i <= n; i++) {
endp[- i] = colonp[n - i];
colonp[n - i] = 0;
}
tp = endp;
}
if (tp != endp)
return (0);
memcpy(dst, tmp, NS_IN6ADDRSZ);
return (1);
}

View File

@@ -0,0 +1,15 @@
/* Just a replacement, if the original isascii is not
present */
#if HAVE_CONFIG_H
#include <ldns/config.h>
#endif
int isascii(int c);
/* true if character is ascii. */
int
isascii(int c)
{
return c >= 0 && c < 128;
}

View File

@@ -0,0 +1,15 @@
/* Just a replacement, if the original isblank is not
present */
#if HAVE_CONFIG_H
#include <ldns/config.h>
#endif
int isblank(int c);
/* true if character is a blank (space or tab). C99. */
int
isblank(int c)
{
return (c == ' ') || (c == '\t');
}

View File

@@ -0,0 +1,14 @@
#ifdef HAVE_CONFIG_H
#include <ldns/config.h>
#endif
#ifdef HAVE_TIME_H
#include <time.h>
#endif
struct tm *localtime_r(const time_t *timep, struct tm *result)
{
/* no thread safety. */
*result = *localtime(timep);
return result;
}

View File

@@ -0,0 +1,22 @@
/* Just a replacement, if the original malloc is not
GNU-compliant. See autoconf documentation. */
#if HAVE_CONFIG_H
#include <ldns/config.h>
#endif
#undef malloc
#include <sys/types.h>
void *malloc (size_t n);
/* Allocate an N-byte block of memory from the heap.
If N is zero, allocate a 1-byte block. */
void *
rpl_malloc (size_t n)
{
if (n == 0)
n = 1;
return malloc (n);
}

View File

@@ -0,0 +1,43 @@
/*
* memmove.c: memmove compat implementation.
*
* Copyright (c) 2001-2008, NLnet Labs. All rights reserved.
*
* See LICENSE for the license.
*/
#include <ldns/config.h>
#include <stdlib.h>
void *memmove(void *dest, const void *src, size_t n);
void *memmove(void *dest, const void *src, size_t n)
{
uint8_t* from = (uint8_t*) src;
uint8_t* to = (uint8_t*) dest;
if (from == to || n == 0)
return dest;
if (to > from && to-from < (int)n) {
/* to overlaps with from */
/* <from......> */
/* <to........> */
/* copy in reverse, to avoid overwriting from */
int i;
for(i=n-1; i>=0; i--)
to[i] = from[i];
return dest;
}
if (from > to && from-to < (int)n) {
/* to overlaps with from */
/* <from......> */
/* <to........> */
/* copy forwards, to avoid overwriting from */
size_t i;
for(i=0; i<n; i++)
to[i] = from[i];
return dest;
}
memcpy(dest, src, n);
return dest;
}

View File

@@ -0,0 +1,30 @@
/* Just a replacement, if the original malloc is not
GNU-compliant. Based on malloc.c */
#if HAVE_CONFIG_H
#include <ldns/config.h>
#endif
#undef realloc
#include <sys/types.h>
void *realloc (void*, size_t);
void *malloc (size_t);
/* Changes allocation to new sizes, copies over old data.
* if oldptr is NULL, does a malloc.
* if size is zero, allocate 1-byte block....
* (does not return NULL and free block)
*/
void *
rpl_realloc (void* ptr, size_t n)
{
if (n == 0)
n = 1;
if(ptr == 0) {
return malloc(n);
}
return realloc(ptr, n);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,57 @@
/* from openssh 4.3p2 compat/strlcpy.c */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* OPENBSD ORIGINAL: lib/libc/string/strlcpy.c */
#include <ldns/config.h>
#ifndef HAVE_STRLCPY
#include <sys/types.h>
#include <string.h>
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
size_t
strlcpy(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
/* Copy as many bytes as will fit */
if (n != 0 && --n != 0) {
do {
if ((*d++ = *s++) == 0)
break;
} while (--n != 0);
}
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}
return(s - src - 1); /* count does not include NUL */
}
#endif /* !HAVE_STRLCPY */

View File

@@ -0,0 +1,31 @@
#ifdef HAVE_CONFIG_H
#include <ldns/config.h>
#endif
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <time.h>
time_t
timegm (struct tm *tm) {
time_t ret;
char *tz;
tz = getenv("TZ");
putenv((char*)"TZ=");
tzset();
ret = mktime(tm);
if (tz) {
char buf[256];
snprintf(buf, sizeof(buf), "TZ=%s", tz);
putenv(tz);
}
else
putenv((char*)"TZ");
tzset();
return ret;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,53 @@
Revision history for Perl extension DNS::LDNS.
0.01 Thu Nov 22 12:48:29 2012
- original version; created by h2xs 1.23 with options
-A -n LDNS
0.02 Fri Jan 18 09:47:57 2013
- Support for DNSSec and Resolver. Added some more constants from
the header files; created by h2xs 1.23 with options
-n LDNS /usr/include/ldns/ldns.h /usr/include/ldns/error.h /usr/include/ldns/rr.h /usr/include/ldns/keys.h /usr/include/ldns/packet.h /usr/include/ldns/resolver.h /usr/include/ldns/rdata.h /usr/include/ldns/dnssec.h
0.03 Fri Apr 19 13:40:57 2013
- Renamed module to Net::LDNS
0.04 Fri Dec 13 14:15:26 2013
- Renamed module to DNS::LDNS
0.05 Mon Dec 30 10:14:00 2013
- Corrected versioning variable in all classes.
- Cleaned up the base class documentation.
0.06 Tue Dec 31 12:17:00 2013
- Corrected pod syntax
0.50 Sun Mar 30 11:05:23 2014
- Added prev parameter to the DNS::LDNS::RR::new(str) constructor.
- Corrected DNS::LDNS::RR::new(file/filename) constructor. Added prev
parameter, changed the default_ttl and origin parameters to
references so they can return data back to the caller as intended.
Using the 'built-in' default values for ttl and origin, rather than
my own values.
- Corrected the DNS::LDNS::Zone::new() constructor. Corrected file
option for reading zone from stream. Using the 'built-in' default
values for ttl and origin, rather than my own values.
- Removed the $DNS::LDNS::DEFAULT_* variables, they proved to be less
useful after modifying the Zone and RR constructors.
- More robust Makefile.PL. Check for existence of ldns library
and perl modules required for the test suite.
0.51 Wed Apr 2 09:12:00 2014
- Added META.yml, and added some more package dependencies.
- Compatibility with ldns < 1.6.12.
0.52 Tue May 5 09:13:00 2015
- Fixed typo in META.yml
0.60 Thu Dec 29 11:15:00 2016
- Compatibility with ldns 1.7
- Dist::zilla build management
0.61 Fri Dec 30 14:32:00 2016
- Bugfixes for ldns 1.7 compatibility
- Compatibility with perl 5.25

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,38 @@
Changes
constants.PL
dist.ini
LDNS.xs
lib/DNS/LDNS.pm
lib/DNS/LDNS/DNSSecDataChain.pm
lib/DNS/LDNS/DNSSecName.pm
lib/DNS/LDNS/DNSSecRRs.pm
lib/DNS/LDNS/DNSSecRRSets.pm
lib/DNS/LDNS/DNSSecTrustTree.pm
lib/DNS/LDNS/DNSSecZone.pm
lib/DNS/LDNS/GC.pm
lib/DNS/LDNS/Key.pm
lib/DNS/LDNS/KeyList.pm
lib/DNS/LDNS/Packet.pm
lib/DNS/LDNS/RBNode.pm
lib/DNS/LDNS/RBTree.pm
lib/DNS/LDNS/RData.pm
lib/DNS/LDNS/Resolver.pm
lib/DNS/LDNS/RR.pm
lib/DNS/LDNS/RRList.pm
lib/DNS/LDNS/Zone.pm
MANIFEST
ppport.h
README
t/dnssec_datachain.t
t/dnssec_zone.t
t/key.t
t/DNS-LDNS.t
t/rdata.t
t/resolver.t
t/rr.t
t/rrlist.t
t/testdata/key.private
t/testdata/myzone.org
t/testdata/resolv.conf
t/zone.t
typemap

View File

@@ -0,0 +1,36 @@
DNS::LDNS version 0.61
======================
DESCRIPTION
DNS::LDNS is a perl OO-wrapper for the ldns library. For a detailed
description on how this library works, you are advised to read the ldns
documentation. For a functional description of the wrapper classes,
please read the perldoc for DNS::LDNS and subclasses.
INSTALLATION
To install this module type the following:
perl Makefile.PL
make
make test
make install
DEPENDENCIES
This module requires these other modules and libraries:
ldns
AUTHOR
Erik Pihl Ostlyngen, erik.ostlyngen@uninett.no
COPYRIGHT AND LICENCE
Copyright (C) 2013 by UNINETT Norid AS
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.8 or,
at your option, any later version of Perl 5 you may have available.

View File

@@ -0,0 +1,280 @@
use ExtUtils::Constant;
# If you edit these definitions to change the constants used by this module,
# you will need to use the generated const-c.inc and const-xs.inc
# files to replace their "fallback" counterparts before distributing your
# changes.
my @names = (qw(LDNS_AA LDNS_AD LDNS_CD LDNS_DEFAULT_EXP_TIME
LDNS_DEFAULT_TTL LDNS_DNSSEC_KEYPROTO LDNS_IP4ADDRLEN
LDNS_IP6ADDRLEN LDNS_KEY_REVOKE_KEY LDNS_KEY_SEP_KEY
LDNS_KEY_ZONE_KEY LDNS_MAX_DOMAINLEN LDNS_MAX_KEYLEN
LDNS_MAX_LABELLEN LDNS_MAX_PACKETLEN LDNS_MAX_POINTERS
LDNS_MAX_RDFLEN LDNS_NSEC3_MAX_ITERATIONS
LDNS_NSEC3_VARS_OPTOUT_MASK LDNS_PORT LDNS_QR LDNS_RA LDNS_RD
LDNS_RDATA_FIELD_DESCRIPTORS_COMMON LDNS_RDF_SIZE_16BYTES
LDNS_RDF_SIZE_6BYTES LDNS_RDF_SIZE_BYTE
LDNS_RDF_SIZE_DOUBLEWORD LDNS_RDF_SIZE_WORD LDNS_RESOLV_ANCHOR
LDNS_RESOLV_DEFDOMAIN LDNS_RESOLV_INET LDNS_RESOLV_INET6
LDNS_RESOLV_INETANY LDNS_RESOLV_KEYWORD LDNS_RESOLV_KEYWORDS
LDNS_RESOLV_NAMESERVER LDNS_RESOLV_OPTIONS LDNS_RESOLV_RTT_INF
LDNS_RESOLV_RTT_MIN LDNS_RESOLV_SEARCH LDNS_RESOLV_SORTLIST
LDNS_RR_OVERHEAD LDNS_SIGNATURE_LEAVE_ADD_NEW
LDNS_SIGNATURE_LEAVE_NO_ADD LDNS_SIGNATURE_REMOVE_ADD_NEW
LDNS_SIGNATURE_REMOVE_NO_ADD LDNS_TC),
{name=>"LDNS_CERT_ACPKIX", macro=>"1"},
{name=>"LDNS_CERT_IACPKIX", macro=>"1"},
{name=>"LDNS_CERT_IPGP", macro=>"1"},
{name=>"LDNS_CERT_IPKIX", macro=>"1"},
{name=>"LDNS_CERT_ISPKI", macro=>"1"},
{name=>"LDNS_CERT_OID", macro=>"1"},
{name=>"LDNS_CERT_PGP", macro=>"1"},
{name=>"LDNS_CERT_PKIX", macro=>"1"},
{name=>"LDNS_CERT_SPKI", macro=>"1"},
{name=>"LDNS_CERT_URI", macro=>"1"},
{name=>"LDNS_DH", macro=>"1"},
{name=>"LDNS_DSA", macro=>"1"},
{name=>"LDNS_DSA_NSEC3", macro=>"1"},
{name=>"LDNS_ECC", macro=>"1"},
{name=>"LDNS_ECC_GOST", macro=>"1"},
{name=>"LDNS_HASH_GOST", macro=>"1"},
{name=>"LDNS_PACKET_ANSWER", macro=>"1"},
{name=>"LDNS_PACKET_IQUERY", macro=>"1"},
{name=>"LDNS_PACKET_NODATA", macro=>"1"},
{name=>"LDNS_PACKET_NOTIFY", macro=>"1"},
{name=>"LDNS_PACKET_NXDOMAIN", macro=>"1"},
{name=>"LDNS_PACKET_QUERY", macro=>"1"},
{name=>"LDNS_PACKET_QUESTION", macro=>"1"},
{name=>"LDNS_PACKET_REFERRAL", macro=>"1"},
{name=>"LDNS_PACKET_STATUS", macro=>"1"},
{name=>"LDNS_PACKET_UNKNOWN", macro=>"1"},
{name=>"LDNS_PACKET_UPDATE", macro=>"1"},
{name=>"LDNS_PRIVATEDNS", macro=>"1"},
{name=>"LDNS_PRIVATEOID", macro=>"1"},
{name=>"LDNS_RCODE_FORMERR", macro=>"1"},
{name=>"LDNS_RCODE_NOERROR", macro=>"1"},
{name=>"LDNS_RCODE_NOTAUTH", macro=>"1"},
{name=>"LDNS_RCODE_NOTIMPL", macro=>"1"},
{name=>"LDNS_RCODE_NOTZONE", macro=>"1"},
{name=>"LDNS_RCODE_NXDOMAIN", macro=>"1"},
{name=>"LDNS_RCODE_NXRRSET", macro=>"1"},
{name=>"LDNS_RCODE_REFUSED", macro=>"1"},
{name=>"LDNS_RCODE_SERVFAIL", macro=>"1"},
{name=>"LDNS_RCODE_YXDOMAIN", macro=>"1"},
{name=>"LDNS_RCODE_YXRRSET", macro=>"1"},
{name=>"LDNS_RDF_TYPE_A", macro=>"1"},
{name=>"LDNS_RDF_TYPE_AAAA", macro=>"1"},
{name=>"LDNS_RDF_TYPE_ALG", macro=>"1"},
{name=>"LDNS_RDF_TYPE_APL", macro=>"1"},
{name=>"LDNS_RDF_TYPE_ATMA", macro=>"1"},
{name=>"LDNS_RDF_TYPE_B32_EXT", macro=>"1"},
{name=>"LDNS_RDF_TYPE_B64", macro=>"1"},
{name=>"LDNS_RDF_TYPE_CERT_ALG", macro=>"1"},
{name=>"LDNS_RDF_TYPE_CLASS", macro=>"1"},
{name=>"LDNS_RDF_TYPE_DNAME", macro=>"1"},
{name=>"LDNS_RDF_TYPE_HEX", macro=>"1"},
{name=>"LDNS_RDF_TYPE_INT16", macro=>"1"},
{name=>"LDNS_RDF_TYPE_INT16_DATA", macro=>"1"},
{name=>"LDNS_RDF_TYPE_INT32", macro=>"1"},
{name=>"LDNS_RDF_TYPE_INT8", macro=>"1"},
{name=>"LDNS_RDF_TYPE_IPSECKEY", macro=>"1"},
{name=>"LDNS_RDF_TYPE_LOC", macro=>"1"},
{name=>"LDNS_RDF_TYPE_NONE", macro=>"1"},
{name=>"LDNS_RDF_TYPE_NSAP", macro=>"1"},
{name=>"LDNS_RDF_TYPE_NSEC", macro=>"1"},
{name=>"LDNS_RDF_TYPE_NSEC3_NEXT_OWNER", macro=>"1"},
{name=>"LDNS_RDF_TYPE_NSEC3_SALT", macro=>"1"},
{name=>"LDNS_RDF_TYPE_PERIOD", macro=>"1"},
{name=>"LDNS_RDF_TYPE_SERVICE", macro=>"1"},
{name=>"LDNS_RDF_TYPE_STR", macro=>"1"},
{name=>"LDNS_RDF_TYPE_TIME", macro=>"1"},
{name=>"LDNS_RDF_TYPE_HIP", macro=>"1"},
{name=>"LDNS_RDF_TYPE_TSIGTIME", macro=>"1"},
{name=>"LDNS_RDF_TYPE_TYPE", macro=>"1"},
{name=>"LDNS_RDF_TYPE_UNKNOWN", macro=>"1"},
{name=>"LDNS_RDF_TYPE_WKS", macro=>"1"},
{name=>"LDNS_RR_CLASS_ANY", macro=>"1"},
{name=>"LDNS_RR_CLASS_CH", macro=>"1"},
{name=>"LDNS_RR_CLASS_COUNT", macro=>"1"},
{name=>"LDNS_RR_CLASS_FIRST", macro=>"1"},
{name=>"LDNS_RR_CLASS_HS", macro=>"1"},
{name=>"LDNS_RR_CLASS_IN", macro=>"1"},
{name=>"LDNS_RR_CLASS_LAST", macro=>"1"},
{name=>"LDNS_RR_CLASS_NONE", macro=>"1"},
{name=>"LDNS_RR_COMPRESS", macro=>"1"},
{name=>"LDNS_RR_NO_COMPRESS", macro=>"1"},
{name=>"LDNS_RR_TYPE_A", macro=>"1"},
{name=>"LDNS_RR_TYPE_A6", macro=>"1"},
{name=>"LDNS_RR_TYPE_AAAA", macro=>"1"},
{name=>"LDNS_RR_TYPE_AFSDB", macro=>"1"},
{name=>"LDNS_RR_TYPE_ANY", macro=>"1"},
{name=>"LDNS_RR_TYPE_APL", macro=>"1"},
{name=>"LDNS_RR_TYPE_ATMA", macro=>"1"},
{name=>"LDNS_RR_TYPE_AXFR", macro=>"1"},
{name=>"LDNS_RR_TYPE_CERT", macro=>"1"},
{name=>"LDNS_RR_TYPE_CNAME", macro=>"1"},
{name=>"LDNS_RR_TYPE_COUNT", macro=>"1"},
{name=>"LDNS_RR_TYPE_DHCID", macro=>"1"},
{name=>"LDNS_RR_TYPE_DLV", macro=>"1"},
{name=>"LDNS_RR_TYPE_DNAME", macro=>"1"},
{name=>"LDNS_RR_TYPE_DNSKEY", macro=>"1"},
{name=>"LDNS_RR_TYPE_DS", macro=>"1"},
{name=>"LDNS_RR_TYPE_EID", macro=>"1"},
{name=>"LDNS_RR_TYPE_FIRST", macro=>"1"},
{name=>"LDNS_RR_TYPE_GID", macro=>"1"},
{name=>"LDNS_RR_TYPE_GPOS", macro=>"1"},
{name=>"LDNS_RR_TYPE_HINFO", macro=>"1"},
{name=>"LDNS_RR_TYPE_IPSECKEY", macro=>"1"},
{name=>"LDNS_RR_TYPE_ISDN", macro=>"1"},
{name=>"LDNS_RR_TYPE_IXFR", macro=>"1"},
{name=>"LDNS_RR_TYPE_KEY", macro=>"1"},
{name=>"LDNS_RR_TYPE_KX", macro=>"1"},
{name=>"LDNS_RR_TYPE_LAST", macro=>"1"},
{name=>"LDNS_RR_TYPE_LOC", macro=>"1"},
{name=>"LDNS_RR_TYPE_MAILA", macro=>"1"},
{name=>"LDNS_RR_TYPE_MAILB", macro=>"1"},
{name=>"LDNS_RR_TYPE_MB", macro=>"1"},
{name=>"LDNS_RR_TYPE_MD", macro=>"1"},
{name=>"LDNS_RR_TYPE_MF", macro=>"1"},
{name=>"LDNS_RR_TYPE_MG", macro=>"1"},
{name=>"LDNS_RR_TYPE_MINFO", macro=>"1"},
{name=>"LDNS_RR_TYPE_MR", macro=>"1"},
{name=>"LDNS_RR_TYPE_MX", macro=>"1"},
{name=>"LDNS_RR_TYPE_NAPTR", macro=>"1"},
{name=>"LDNS_RR_TYPE_NIMLOC", macro=>"1"},
{name=>"LDNS_RR_TYPE_NS", macro=>"1"},
{name=>"LDNS_RR_TYPE_NSAP", macro=>"1"},
{name=>"LDNS_RR_TYPE_NSAP_PTR", macro=>"1"},
{name=>"LDNS_RR_TYPE_NSEC", macro=>"1"},
{name=>"LDNS_RR_TYPE_NSEC3", macro=>"1"},
{name=>"LDNS_RR_TYPE_NSEC3PARAM", macro=>"1"},
{name=>"LDNS_RR_TYPE_NSEC3PARAMS", macro=>"1"},
{name=>"LDNS_RR_TYPE_NULL", macro=>"1"},
{name=>"LDNS_RR_TYPE_NXT", macro=>"1"},
{name=>"LDNS_RR_TYPE_OPT", macro=>"1"},
{name=>"LDNS_RR_TYPE_PTR", macro=>"1"},
{name=>"LDNS_RR_TYPE_PX", macro=>"1"},
{name=>"LDNS_RR_TYPE_RP", macro=>"1"},
{name=>"LDNS_RR_TYPE_RRSIG", macro=>"1"},
{name=>"LDNS_RR_TYPE_RT", macro=>"1"},
{name=>"LDNS_RR_TYPE_SIG", macro=>"1"},
{name=>"LDNS_RR_TYPE_SINK", macro=>"1"},
{name=>"LDNS_RR_TYPE_SOA", macro=>"1"},
{name=>"LDNS_RR_TYPE_SPF", macro=>"1"},
{name=>"LDNS_RR_TYPE_SRV", macro=>"1"},
{name=>"LDNS_RR_TYPE_SSHFP", macro=>"1"},
{name=>"LDNS_RR_TYPE_TALINK", macro=>"1"},
{name=>"LDNS_RR_TYPE_TSIG", macro=>"1"},
{name=>"LDNS_RR_TYPE_TXT", macro=>"1"},
{name=>"LDNS_RR_TYPE_UID", macro=>"1"},
{name=>"LDNS_RR_TYPE_UINFO", macro=>"1"},
{name=>"LDNS_RR_TYPE_UNSPEC", macro=>"1"},
{name=>"LDNS_RR_TYPE_WKS", macro=>"1"},
{name=>"LDNS_RR_TYPE_X25", macro=>"1"},
{name=>"LDNS_RSAMD5", macro=>"1"},
{name=>"LDNS_RSASHA1", macro=>"1"},
{name=>"LDNS_RSASHA1_NSEC3", macro=>"1"},
{name=>"LDNS_RSASHA256", macro=>"1"},
{name=>"LDNS_RSASHA512", macro=>"1"},
{name=>"LDNS_SECTION_ADDITIONAL", macro=>"1"},
{name=>"LDNS_SECTION_ANSWER", macro=>"1"},
{name=>"LDNS_SECTION_ANY", macro=>"1"},
{name=>"LDNS_SECTION_ANY_NOQUESTION", macro=>"1"},
{name=>"LDNS_SECTION_AUTHORITY", macro=>"1"},
{name=>"LDNS_SECTION_QUESTION", macro=>"1"},
{name=>"LDNS_SHA1", macro=>"1"},
{name=>"LDNS_SHA256", macro=>"1"},
{name=>"LDNS_SIGN_DSA", macro=>"1"},
{name=>"LDNS_SIGN_DSA_NSEC3", macro=>"1"},
{name=>"LDNS_SIGN_ECC_GOST", macro=>"1"},
{name=>"LDNS_SIGN_HMACSHA1", macro=>"1"},
{name=>"LDNS_SIGN_HMACSHA256", macro=>"1"},
{name=>"LDNS_SIGN_RSAMD5", macro=>"1"},
{name=>"LDNS_SIGN_RSASHA1", macro=>"1"},
{name=>"LDNS_SIGN_RSASHA1_NSEC3", macro=>"1"},
{name=>"LDNS_SIGN_RSASHA256", macro=>"1"},
{name=>"LDNS_SIGN_RSASHA512", macro=>"1"},
{name=>"LDNS_STATUS_ADDRESS_ERR", macro=>"1"},
{name=>"LDNS_STATUS_CERT_BAD_ALGORITHM", macro=>"1"},
{name=>"LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL", macro=>"1"},
{name=>"LDNS_STATUS_CRYPTO_BOGUS", macro=>"1"},
{name=>"LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION", macro=>"1"},
{name=>"LDNS_STATUS_CRYPTO_NO_DNSKEY", macro=>"1"},
{name=>"LDNS_STATUS_CRYPTO_NO_DS", macro=>"1"},
{name=>"LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY", macro=>"1"},
{name=>"LDNS_STATUS_CRYPTO_NO_RRSIG", macro=>"1"},
{name=>"LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY", macro=>"1"},
{name=>"LDNS_STATUS_CRYPTO_NO_TRUSTED_DS", macro=>"1"},
{name=>"LDNS_STATUS_CRYPTO_SIG_EXPIRED", macro=>"1"},
{name=>"LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED", macro=>"1"},
{name=>"LDNS_STATUS_CRYPTO_TSIG_BOGUS", macro=>"1"},
{name=>"LDNS_STATUS_CRYPTO_TSIG_ERR", macro=>"1"},
{name=>"LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR", macro=>"1"},
{name=>"LDNS_STATUS_CRYPTO_UNKNOWN_ALGO", macro=>"1"},
{name=>"LDNS_STATUS_CRYPTO_VALIDATED", macro=>"1"},
{name=>"LDNS_STATUS_DDD_OVERFLOW", macro=>"1"},
{name=>"LDNS_STATUS_DNSSEC_EXISTENCE_DENIED", macro=>"1"},
{name=>"LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND", macro=>"1"},
{name=>"LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED", macro=>"1"},
{name=>"LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED", macro=>"1"},
{name=>"LDNS_STATUS_DOMAINNAME_OVERFLOW", macro=>"1"},
{name=>"LDNS_STATUS_DOMAINNAME_UNDERFLOW", macro=>"1"},
{name=>"LDNS_STATUS_EMPTY_LABEL", macro=>"1"},
{name=>"LDNS_STATUS_ENGINE_KEY_NOT_LOADED", macro=>"1"},
{name=>"LDNS_STATUS_ERR", macro=>"1"},
{name=>"LDNS_STATUS_FILE_ERR", macro=>"1"},
{name=>"LDNS_STATUS_INTERNAL_ERR", macro=>"1"},
{name=>"LDNS_STATUS_INVALID_B32_EXT", macro=>"1"},
{name=>"LDNS_STATUS_INVALID_B64", macro=>"1"},
{name=>"LDNS_STATUS_INVALID_HEX", macro=>"1"},
{name=>"LDNS_STATUS_INVALID_INT", macro=>"1"},
{name=>"LDNS_STATUS_INVALID_IP4", macro=>"1"},
{name=>"LDNS_STATUS_INVALID_IP6", macro=>"1"},
{name=>"LDNS_STATUS_INVALID_POINTER", macro=>"1"},
{name=>"LDNS_STATUS_INVALID_STR", macro=>"1"},
{name=>"LDNS_STATUS_INVALID_TIME", macro=>"1"},
{name=>"LDNS_STATUS_LABEL_OVERFLOW", macro=>"1"},
{name=>"LDNS_STATUS_MEM_ERR", macro=>"1"},
{name=>"LDNS_STATUS_MISSING_RDATA_FIELDS_KEY", macro=>"1"},
{name=>"LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG", macro=>"1"},
{name=>"LDNS_STATUS_NETWORK_ERR", macro=>"1"},
{name=>"LDNS_STATUS_NOT_IMPL", macro=>"1"},
{name=>"LDNS_STATUS_NO_DATA", macro=>"1"},
{name=>"LDNS_STATUS_NSEC3_ERR", macro=>"1"},
{name=>"LDNS_STATUS_NULL", macro=>"1"},
{name=>"LDNS_STATUS_OK", macro=>"1"},
{name=>"LDNS_STATUS_PACKET_OVERFLOW", macro=>"1"},
{name=>"LDNS_STATUS_RES_NO_NS", macro=>"1"},
{name=>"LDNS_STATUS_RES_QUERY", macro=>"1"},
{name=>"LDNS_STATUS_SOCKET_ERROR", macro=>"1"},
{name=>"LDNS_STATUS_SSL_ERR", macro=>"1"},
{name=>"LDNS_STATUS_SYNTAX_ALG_ERR", macro=>"1"},
{name=>"LDNS_STATUS_SYNTAX_BAD_ESCAPE", macro=>"1"},
{name=>"LDNS_STATUS_SYNTAX_CLASS_ERR", macro=>"1"},
{name=>"LDNS_STATUS_SYNTAX_DNAME_ERR", macro=>"1"},
{name=>"LDNS_STATUS_SYNTAX_EMPTY", macro=>"1"},
{name=>"LDNS_STATUS_SYNTAX_ERR", macro=>"1"},
{name=>"LDNS_STATUS_SYNTAX_INCLUDE", macro=>"1"},
{name=>"LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL", macro=>"1"},
{name=>"LDNS_STATUS_SYNTAX_INTEGER_OVERFLOW", macro=>"1"},
{name=>"LDNS_STATUS_SYNTAX_ITERATIONS_OVERFLOW", macro=>"1"},
{name=>"LDNS_STATUS_SYNTAX_KEYWORD_ERR", macro=>"1"},
{name=>"LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR", macro=>"1"},
{name=>"LDNS_STATUS_SYNTAX_ORIGIN", macro=>"1"},
{name=>"LDNS_STATUS_SYNTAX_RDATA_ERR", macro=>"1"},
{name=>"LDNS_STATUS_SYNTAX_TTL", macro=>"1"},
{name=>"LDNS_STATUS_SYNTAX_TTL_ERR", macro=>"1"},
{name=>"LDNS_STATUS_SYNTAX_TYPE_ERR", macro=>"1"},
{name=>"LDNS_STATUS_SYNTAX_VERSION_ERR", macro=>"1"},
{name=>"LDNS_STATUS_UNKNOWN_INET", macro=>"1"},
{name=>"LDNS_STATUS_WIRE_INCOMPLETE_ADDITIONAL", macro=>"1"},
{name=>"LDNS_STATUS_WIRE_INCOMPLETE_ANSWER", macro=>"1"},
{name=>"LDNS_STATUS_WIRE_INCOMPLETE_AUTHORITY", macro=>"1"},
{name=>"LDNS_STATUS_WIRE_INCOMPLETE_HEADER", macro=>"1"},
{name=>"LDNS_STATUS_WIRE_INCOMPLETE_QUESTION", macro=>"1"});
ExtUtils::Constant::WriteConstants(
NAME => 'LDNS',
NAMES => \@names,
DEFAULT_TYPE => 'IV',
C_FILE => 'const-c.inc',
XS_FILE => 'const-xs.inc',
);

View File

@@ -0,0 +1,18 @@
name = DNS-LDNS
author = Erik Ostlyngen <erik@uninett.no>
copyright_holder = UNINETT Norid AS
copyright_year = 2013
license = None
version = 0.61
[AutoPrereqs]
[GatherDir]
[MetaYAML]
[MakeMaker::Awesome]
WriteMakefile_arg = LIBS => ['-lldns']
footer_file = constants.PL
[CheckLib]
lib = ldns
header = ldns/ldns.h
[License]
[PruneCruft]

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,87 @@
package DNS::LDNS::DNSSecDataChain;
use 5.008008;
use strict;
use warnings;
use DNS::LDNS;
our $VERSION = '0.61';
sub rrset {
my $self = shift;
return DNS::LDNS::GC::own($self->_rrset, $self);
}
sub signatures {
my $self = shift;
return DNS::LDNS::GC::own($self->_signatures, $self);
}
sub parent {
my $self = shift;
return DNS::LDNS::GC::own($self->_parent, $self);
}
sub derive_trust_tree {
my ($self, $rr) = @_;
if (!DNS::LDNS::GC::is_owned($rr) or DNS::LDNS::GC::owner($rr) ne $self) {
die "The rr ($rr) must be in the data chain ($self)";
}
return DNS::LDNS::GC::own($self->_derive_trust_tree($rr), $self);
}
sub derive_trust_tree_time {
my ($self, $rr, $checktime) = @_;
if (!DNS::LDNS::GC::is_owned($rr) or DNS::LDNS::GC::owner($rr) ne $self) {
die "The rr ($rr) must be in the data chain ($self)";
}
return DNS::LDNS::GC::own(
$self->_derive_trust_tree_time($rr, $checktime), $self);
}
1;
__END__
=head1 NAME
DNS::LDNS::DNSSecDataChain - DNSSec data chain element
=head1 SYNOPSIS
use DNS::LDNS ':all'
chain = new DNS::LDNS::DNSSecDataChain
chain->print(fp)
chain->derive_trust_tree(rr)
chain->derive_trust_tree_time(rr, checktime)
# Node attributes
rrset = chain->rrset
rrset = chain->signatures
rrtype = chain->parent_type
pchain = chain->parent
rcode = chain->packet_rcode
rrtype = chain->packet_qtype
bool = chain->packet_nodata
=head1 SEE ALSO
http://www.nlnetlabs.nl/projects/ldns
=head1 AUTHOR
Erik Pihl Ostlyngen, E<lt>erik.ostlyngen@uninett.noE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2013 by UNINETT Norid AS
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.14.2 or,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@@ -0,0 +1,110 @@
package DNS::LDNS::DNSSecName;
use 5.008008;
use strict;
use warnings;
use DNS::LDNS ':all';
our $VERSION = '0.61';
sub new {
my $class = shift;
return _new;
}
sub name {
my $self = shift;
return DNS::LDNS::GC::own($self->_name, $self);
}
sub set_name {
my ($self, $name) = @_;
DNS::LDNS::GC::disown(my $old = $self->name);
_set_name($self, my $copy = $name->clone);
DNS::LDNS::GC::own($copy, $self);
}
sub rrsets {
my $self = shift;
return DNS::LDNS::GC::own($self->_rrsets, $self);
}
sub add_rr {
my ($self, $rr) = @_;
my $s = _add_rr($self, my $copy = $rr->clone);
DNS::LDNS::GC::own($copy, $self);
$DNS::LDNS::last_status = $s;
return $s;
}
sub nsec {
my $self = shift;
return DNS::LDNS::GC::own($self->_nsec, $self);
}
sub set_nsec {
my ($self, $nsec) = @_;
DNS::LDNS::GC::disown(my $old = $self->nsec);
_set_nsec($self, my $copy = $nsec->clone);
DNS::LDNS::GC::own($copy, $self);
}
sub hashed_name {
my $self = shift;
return DNS::LDNS::GC::own($self->_hashed_name, $self);
}
sub nsec_signatures {
my $self = shift;
return DNS::LDNS::GC::own($self->_nsec_signatures, $self);
}
sub DESTROY {
DNS::LDNS::GC::free($_[0]);
}
1;
__END__
=head1 NAME
DNS::LDNS::DNSSecName - Dname with rrsets in a dnssec zone
=head1 SYNOPSIS
use LDNS ':all'
my name = new DNS::LDNS::DNSSecName
rdata = name->name
name->set_name(rdata)
bool = name->is_glue
rrsets = name->rrsets
name->add_rr(rr)
rr = name->nsec
name->set_nsec(rr)
hash = name->hashed_name
rrs = name->nsec_signatures
=head1 SEE ALSO
http://www.nlnetlabs.nl/projects/ldns
=head1 AUTHOR
Erik Pihl Ostlyngen, E<lt>erik.ostlyngen@uninett.noE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2013 by UNINETT Norid AS
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.14.2 or,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@@ -0,0 +1,85 @@
package DNS::LDNS::DNSSecRRSets;
use 5.008008;
use strict;
use warnings;
use DNS::LDNS;
our $VERSION = '0.61';
# Note: Since this class does not have a constructor, we can let its child
# objects be owned by the parent. This reduces the recursion depth on
# DESTROY.
sub rrs {
my $self = shift;
return DNS::LDNS::GC::own($self->_rrs, DNS::LDNS::GC::owner($self));
}
sub signatures {
my $self = shift;
return DNS::LDNS::GC::own($self->_signatures, DNS::LDNS::GC::owner($self));
}
sub next {
my $self = shift;
return DNS::LDNS::GC::own($self->_next, DNS::LDNS::GC::owner($self));
}
sub set_type {
my ($self, $type) = @_;
my $s = _set_type($self, $type);
$DNS::LDNS::last_status = $s;
return $s;
}
sub add_rr {
my ($self, $rr) = @_;
my $s = _add_rr($self, my $copy = $rr->clone);
$DNS::LDNS::last_status = $s;
DNS::LDNS::GC::own($copy, $self);
return $s;
}
sub DESTROY {
DNS::LDNS::GC::free($_[0]);
}
1;
__END__
=head1 NAME
DNS::LDNS::DNSSecRRSets - Linked list of rrsets in a dnssec zone
=head1 SYNOPSIS
use DNS::LDNS ':all'
rrs = rrsets->rrs
rrs = rrsets->signatures
rrsets2 = rrsets->next
rrsets->add_rr(rr)
bool = rrsets->contains_type(rr_type)
rr_type = rrsets->type
rrsets->set_type(rr_type)
=head1 SEE ALSO
http://www.nlnetlabs.nl/projects/ldns
=head1 AUTHOR
Erik Pihl Ostlyngen, E<lt>erik.ostlyngen@uninett.noE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2013 by UNINETT Norid AS
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.14.2 or,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@@ -0,0 +1,82 @@
package DNS::LDNS::DNSSecRRs;
use 5.008008;
use strict;
use warnings;
use DNS::LDNS;
our $VERSION = '0.61';
# Note: This class does not have a constructor. Thus, it can not be created
# as an individual object. The data structure of the node is owned
# and freed by the owner of the parent rather than the parent node. This
# is to prevent deep recursion on DESTROY.
sub to_string {
my $self = shift;
my $ret = '';
while ($self and $self->rr) {
$ret .= $self->rr->to_string;
$self = $self->next;
}
return $ret;
}
sub add_rr {
my ($self, $rr) = @_;
my $s = _add_rr($self, my $copy = $rr->clone);
DNS::LDNS::GC::own($self, $copy);
$DNS::LDNS::last_status = $s;
return $s;
}
sub rr {
my $self = shift;
return DNS::LDNS::GC::own($self->_rr, DNS::LDNS::GC::owner($self));
}
sub next {
my $self = shift;
return DNS::LDNS::GC::own($self->_next, DNS::LDNS::GC::owner($self));
}
sub DESTROY {
DNS::LDNS::GC::free($_[0]);
}
1;
__END__
=head1 NAME
DNS::LDNS::DNSSecRRs - Linked list of rrs in a dnssec zone
=head1 SYNOPSIS
use DNS::LDNS ':all'
rrs->to_string
rrs->add_rr(rr)
rr = rrs->rr
rrs2 = rrs->next
=head1 SEE ALSO
http://www.nlnetlabs.nl/projects/ldns
=head1 AUTHOR
Erik Pihl Ostlyngen, E<lt>erik.ostlyngen@uninett.noE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2013 by UNINETT Norid AS
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.14.2 or,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@@ -0,0 +1,99 @@
package DNS::LDNS::DNSSecTrustTree;
use 5.008008;
use strict;
use warnings;
use DNS::LDNS;
our $VERSION = '0.61';
sub add_parent {
my ($self, $parent, $sig, $parent_status) = @_;
if (DNS::LDNS::GC::is_owned($parent)) {
die "Cannot add to multiple trees.";
}
my $s = _add_parent($self, $parent, $sig, $parent_status);
DNS::LDNS::GC::own($parent, $self);
$DNS::LDNS::last_status = $s;
return $s;
}
sub contains_keys {
my ($self, $trusted_keys) = @_;
my $s = _contains_keys($self, $trusted_keys);
$DNS::LDNS::last_status = $s;
return $s;
}
sub rr {
my $self = shift;
return DNS::LDNS::GC::own($self->_rr, $self);
}
sub rrset {
my $self = shift;
return DNS::LDNS::GC::own($self->_rrset, $self);
}
sub parent {
my ($self, $i) = @_;
return DNS::LDNS::GC::own($self->_parent($i), $self);
}
sub parent_status {
my ($self, $i) = @_;
my $s = _parent_status($self, $i);
$DNS::LDNS::last_status = $s;
return $s;
}
sub parent_signature {
my ($self, $i) = @_;
return DNS::LDNS::GC::own($self->_parent_signature($i), $self);
}
1;
__END__
=head1 NAME
DNS::LDNS::DNSSecTrustTree - Trust tree from signed RR to trust anchors
=head1 SYNOPSIS
use DNS::LDNS ':all'
tree = new DNS::LDNS::DNSSecTrustTree
tree->print(fp)
d = tree->depth
status = tree->add_parent(parent, sig, parent_status)
status = tree->contains_keys(trusted_keys)
# Node attributes
rr = tree->rr;
rrset = tree->rrset
ptree = tree->parent(i)
pstatus = tree->parent_status(i)
rr = tree->parent_signature(i)
count = tree->parent_count
=head1 SEE ALSO
http://www.nlnetlabs.nl/projects/ldns
=head1 AUTHOR
Erik Pihl Ostlyngen, E<lt>erik.ostlyngen@uninett.noE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2013 by UNINETT Norid AS
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.14.2 or,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@@ -0,0 +1,176 @@
package DNS::LDNS::DNSSecZone;
use 5.008008;
use strict;
use warnings;
use DNS::LDNS ':all';
our $VERSION = '0.61';
sub new {
my ($class, %args) = @_;
my $line_nr;
my $status = &LDNS_STATUS_OK;
my $zone;
my $file;
if ($args{filename}) {
unless (open FILE, $args{filename}) {
$DNS::LDNS::last_status = &LDNS_STATUS_FILE_ERR;
$DNS::LDNS::line_nr = 0;
return;
}
$file = \*FILE;
}
elsif ($args{file}) {
$file = $args{file};
}
if ($file) {
$zone = _new_from_file($file,
$args{origin},
$args{ttl} || 0,
$args{class} || 0,
$status, $line_nr);
}
else {
$zone = _new();
}
if ($args{filename}) {
close $file;
}
$DNS::LDNS::last_status = $status;
$DNS::LDNS::line_nr = $line_nr;
if (!defined $zone) {
return;
}
return $zone;
}
sub soa {
my $self = shift;
return DNS::LDNS::GC::own($self->_soa, $self);
}
sub names {
my $self = shift;
return DNS::LDNS::GC::own($self->_names, $self);
}
sub find_rrset {
my ($self, $name, $type) = @_;
return DNS::LDNS::GC::own($self->_find_rrset($name, $type), $self);
}
sub add_rr {
my ($self, $rr) = @_;
# Set a copy of the rr in case it is already owned
my $s = _add_rr($self, my $copy = $rr->clone);
$DNS::LDNS::last_status = $s;
DNS::LDNS::GC::own($copy, $self);
return $s;
}
sub add_empty_nonterminals {
my $self = shift;
my $s = _add_empty_nonterminals($self);
$DNS::LDNS::last_status = $s;
return $s;
}
sub mark_glue {
my $self = shift;
my $s = _mark_glue($self);
$DNS::LDNS::last_status = $s;
return $s;
}
sub sign {
my ($self, $keylist, $policy, $flags) = @_;
my $s = _sign($self, $keylist, $policy, $flags);
$DNS::LDNS::last_status = $s;
return $s;
}
sub sign_nsec3 {
my ($self, $keylist, $policy, $algorithm, $flags, $iterations, $salt,
$signflags) = @_;
my $s = _sign_nsec3($self, $keylist, $policy, $algorithm, $flags,
$iterations, $salt, $signflags);
$DNS::LDNS::last_status = $s;
return $s;
}
sub to_string {
return "DNS::LDNS::DNSSecZone::to_string is not yet implemented";
}
sub DESTROY {
DNS::LDNS::GC::free($_[0]);
}
1;
__END__
=head1 NAME
DNS::LDNS::DNSSecZone - Zone with dnssec data
=head1 SYNOPSIS
use DNS::LDNS ':all'
my z = new DNS::LDNS::DNSSecZone(
filename => '/path/to/myzone',
origin => new DNS::LDNS::RData(LDNS_RDF_TYPE_DNAME, 'myzone'), #optional
ttl => 3600, #optional
class => LDNS_RR_CLASS_, #optional
)
my z = new DNS::LDNS::DNSSecZone(
file => \*FILE,
origin => ..., ttl => ..., class => ...
)
my z = new DNS::LDNS::DNSSecZone
rr = z->soa
rbtree = z->names
rrsets = z->find_rrset
z->add_rr(rr)
z->create_from_zone(zone)
z->add_empty_nonterminals
z->sign(keylist, policy)
z->sign_nsec3(keylist, policy, algorithm, flags, iterations, salt)
z->create_nsecs
z->create_nsec3s(algorithm, flags, iterations, salt)
z->create_rrsigs(key_list, policy, flags)
=head1 TODO
z->to_string
=head1 SEE ALSO
http://www.nlnetlabs.nl/projects/ldns
=head1 AUTHOR
Erik Pihl Ostlyngen, E<lt>erik.ostlyngen@uninett.noE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2013 by UNINETT Norid AS
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.14.2 or,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@@ -0,0 +1,122 @@
package DNS::LDNS::GC;
use strict;
use warnings;
our $VERSION = '0.61';
my %ref_count;
my %owned_by;
sub own {
my ($obj, $owner) = @_;
# print STDERR "Owning $obj -> $owner\n";
return unless (defined $obj);
if ($owned_by{$$owner}) {
# If the owner is an owned object, let obj be owned by
# the owners owner. We want to avoid recursive ownerships.
$owner = $owned_by{$$owner};
}
if (exists $owned_by{$$obj}) {
$ref_count{$$obj}++;
}
else {
$ref_count{$$obj} = 1;
$owned_by{$$obj} = $owner;
}
return $obj;
}
# Return true if the object is owned by someone
sub is_owned {
return (exists $owned_by{${$_[0]}});
}
sub owner {
return $owned_by{${$_[0]}};
}
sub disown {
return unless (defined $_[0]);
delete $owned_by{${$_[0]}};
}
my %free_method = (
'DNS::LDNS::Zone' => '_zone_deep_free',
'DNS::LDNS::RRList' => '_rrlist_deep_free',
'DNS::LDNS::RR' => '_rr_free',
'DNS::LDNS::RData' => '_rdata_deep_free',
'DNS::LDNS::DNSSecZone' => '_dnssec_zone_deep_free',
'DNS::LDNS::DNSSecName' => '_dnssec_name_deep_free',
'DNS::LDNS::Resolver' => '_resolver_deep_free',
'DNS::LDNS::Packet' => '_packet_free',
'DNS::LDNS::Key' => '_key_deep_free',
'DNS::LDNS::KeyList' => '_keylist_free',
'DNS::LDNS::DNSSecDataChain' => '_dnssec_datachain',
);
my %not_deleted_by_owner = (
'DNS::LDNS::DNSSecTrustChain' => 1,
);
sub free {
my $obj = shift;
# print STDERR "Freeing $obj\n";
if (exists $ref_count{$$obj}) {
# print STDERR "Derefing $obj\n";
$ref_count{$$obj}--;
return if ($ref_count{$$obj} > 0);
}
# print STDERR "Deleting $obj\n";
delete $ref_count{$$obj};
if (exists $owned_by{$$obj}) {
delete $owned_by{$$obj};
return unless ($not_deleted_by_owner{ref $obj});
}
my $class = ref $obj;
my $free = $free_method{ref $obj};
die "Internal error: No freeing method for $obj (".ref $obj.")"
unless ($free);
no strict;
&$free($obj);
}
1;
__END__
=head1 NAME
DNS::LDNS::GC - Garbage collector, used internally by the DNS::LDNS modules
=head1 SYNOPSIS
Garbage collector class for DNS::LDNS objects.
=head1 SEE ALSO
http://www.nlnetlabs.nl/projects/ldns
=head1 AUTHOR
Erik Pihl Ostlyngen, E<lt>erik.ostlyngen@uninett.noE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2013 by UNINETT Norid AS
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.14.2 or,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@@ -0,0 +1,122 @@
package DNS::LDNS::Key;
use 5.008008;
use strict;
use warnings;
use DNS::LDNS ':all';
our $VERSION = '0.61';
sub new {
my ($class, %args) = @_;
my $key;
if ($args{filename} or $args{file}) {
my $status = &LDNS_STATUS_OK;
my $line_nr = 0;
my $file = $args{file};
if ($args{filename}) {
unless (open FILE, $args{filename}) {
$DNS::LDNS::last_status = &LDNS_STATUS_FILE_ERR;
return;
}
$file = \*FILE;
}
$key = _new_from_file($file, $line_nr, $status);
if ($args{filename}) {
close $file;
}
$DNS::LDNS::last_status = $status;
$DNS::LDNS::line_nr = $line_nr;
if (!defined $key) {
return;
}
}
else {
$key = _new();
}
return $key;
}
sub set_pubkey_owner {
my ($self, $owner) = @_;
my $oldowner = $self->pubkey_owner;
DNS::LDNS::GC::disown(my $old = $self->pubkey_owner);
$self->_set_pubkey_owner($owner);
return DNS::LDNS::GC::own($owner, $self);
}
sub pubkey_owner {
my $self = shift;
return DNS::LDNS::GC::own($self->_pubkey_owner, $self);
}
sub DESTROY {
DNS::LDNS::GC::free($_[0]);
}
1;
__END__
=head1 NAME
DNS::LDNS::Key - DNSSec private key
=head1 SYNOPSIS
use DNS::LDNS ':all'
key = new DNS::LDNS::Key
key = new DNS::LDNS::Key(file => \*FILE)
key = new DNS::LDNS::Key(filename => 'keyfile')
str = key->to_string
key->print(\*OUTPUT)
key->set_algorithm(alg)
alg = key->algorithm
key->set_flags(flags)
flags = key->flags
key->set_hmac_key(hmac)
hmac = key->hmac_key
key->set_hmac_size(size)
size = key->hmac_size
key->set_origttl(ttl)
ttl = key->origttl
key->set_inception(epoch)
epoch = key->inception
key->set_expiration(epoch)
epoch = key->expiration
key->set_pubkey_owner(rdata)
rdata = key->pubkey_owner
key->set_keytag(tag)
tag = key->keytag
key->set_use(bool)
bool = key->use
str = key->get_file_base_name
rr = key->to_rr
=head1 SEE ALSO
http://www.nlnetlabs.nl/projects/ldns
=head1 AUTHOR
Erik Pihl Ostlyngen, E<lt>erik.ostlyngen@uninett.noE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2013 by UNINETT Norid AS
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.14.2 or,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@@ -0,0 +1,72 @@
package DNS::LDNS::KeyList;
use 5.008008;
use strict;
use warnings;
use DNS::LDNS ':all';
our $VERSION = '0.61';
sub new {
my $class = shift;
return _new();
}
sub push {
my ($self, @keys) = @_;
for my $k (@keys) {
if (DNS::LDNS::GC::is_owned($k)) {
die "Cannot push a key on multiple lists.";
}
$self->_push($k);
DNS::LDNS::GC::own($k, $self);
}
}
sub key {
my ($self, $index) = @_;
return DNS::LDNS::GC::own($self->_key($index), $self);
}
sub DESTROY {
DNS::LDNS::GC::free($_[0]);
}
1;
__END__
=head1 NAME
DNS::LDNS::KeyList - Linked list of dnssec keys
=head1 SYNOPSIS
use DNS::LDNS ':all'
my l = new DNS::LDNS::KeyList
l->set_use(bool)
l->push(@keys)
key = l->pop
c = l->count
key = l->key(index)
=head1 SEE ALSO
http://www.nlnetlabs.nl/projects/ldns
=head1 AUTHOR
Erik Pihl Ostlyngen, E<lt>erik.ostlyngen@uninett.noE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2013 by UNINETT Norid AS
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.14.2 or,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@@ -0,0 +1,259 @@
package DNS::LDNS::Packet;
use 5.008008;
use strict;
use warnings;
use DNS::LDNS;
our $VERSION = '0.61';
sub new {
my ($class, %args) = @_;
if ($args{name}) {
return _query_new(
$args{name}, $args{type}, $args{class}, $args{flags});
}
else {
return _new;
}
}
sub question {
my $self = shift;
return DNS::LDNS::GC::own($self->_question, $self);
}
sub set_question {
my ($self, $l) = @_;
DNS::LDNS::GC::disown(my $old = $self->question);
$self->_set_question($l);
return DNS::LDNS::GC::own($l, $self);
}
sub answer {
my $self = shift;
return DNS::LDNS::GC::own($self->_answer, $self);
}
sub set_answer {
my ($self, $l) = @_;
DNS::LDNS::GC::disown(my $old = $self->answer);
$self->_set_answer($l);
return DNS::LDNS::GC::own($l, $self);
}
sub authority {
my $self = shift;
return DNS::LDNS::GC::own($self->_authority, $self);
}
sub set_authority {
my ($self, $l) = @_;
DNS::LDNS::GC::disown(my $old = $self->authority);
$self->_set_authority($l);
return DNS::LDNS::GC::own($l, $self);
}
sub additional {
my $self = shift;
return DNS::LDNS::GC::own($self->_additional, $self);
}
sub set_additional {
my ($self, $l) = @_;
DNS::LDNS::GC::disown(my $old = $self->additional);
$self->_set_additional($l);
return DNS::LDNS::GC::own($l, $self);
}
sub answerfrom {
my $self = shift;
return DNS::LDNS::GC::own($self->_answerfrom, $self);
}
sub set_answerfrom {
my ($self, $a) = @_;
DNS::LDNS::GC::disown(my $old = $self->answerfrom);
$self->_set_answerfrom($a);
return DNS::LDNS::GC::own($a, $self);
}
sub timestamp {
my $self = shift;
my $t = _timestamp($self);
return wantarray ? @$t : $t;
}
sub edns_data {
my $self = shift;
return DNS::LDNS::GC::own($self->_edns_data, $self);
}
sub set_edns_data {
my ($self, $data) = @_;
DNS::LDNS::GC::disown(my $old = $self->edns_data);
$self->_set_edns_data($data);
return DNS::LDNS::GC::own($data, $self);
}
sub push_rr {
my ($self, $sec, $rr) = @_;
my $ret = $self->_push_rr($sec, my $copy = $_->clone);
DNS::LDNS::GC::own($copy, $self);
return $ret;
}
sub safe_push_rr {
my ($self, $sec, $rr) = @_;
my $ret = $self->_safe_push_rr($sec, my $copy = $_->clone);
if ($ret) {
DNS::LDNS::GC::own($copy, $self);
}
return $ret;
}
sub tsig {
my $self = shift;
return DNS::LDNS::GC::own($self->_tsig, $self);
}
sub set_tsig {
my ($self, $rr) = @_;
DNS::LDNS::GC::disown(my $old = $self->tsig);
$self->_set_tsig($rr);
return DNS::LDNS::GC::own($rr, $self);
}
sub DESTROY {
DNS::LDNS::GC::free($_[0]);
}
1;
__END__
=head1 NAME
DNS::LDNS::Packet - DNS packet
=head1 SYNOPSIS
use DNS::LDNS ':all'
my pkt = new DNS::LDNS::Packet(name => rdata, type => LDNS_RR_TYPE_...,
class => LDNS_RR_CLASS_..., flags => ...)
my pkt = new DNS::LDNS::Packet
pkt2 = pkt->clone
pkt->to_string
rrlist = pkt->question
pkt->set_question(rrlist)
'
rrlist = pkt->answer
pkt->set_answer(rrlist)
rrlist = pkt->authority
pkt->set_authority(rrlist)
rrlist = pkt->additional
pkt->set_additional(rrlist)
rrlist = pkt->all
rrlist = pkt->all_noquestion
for (qw/qr aa tc rd cd ra ad/) {
bool = pkt->$_
pkt->set_$_(bool)
}
id = pkt->id
pkt->set_id(id)
pkt->set_random_id
count = pkt->qdcount
count = pkt->ancount
count = pkt->nscount
count = pkt->arcount
opcode = pkt->opcode
pkt->set_opcode(opcode)
rcode = pkt->rcode # Response code
pkt->set_rcode(rcode)
size = pkt->size
epoch = pkt->querytime
pkt->set_querytime(epoch)
rdata = pkt->answerfrom
pkt->set_answerfrom(rdata)
(sec, usec) = pkt->timestamp
pkt->set_timestamp(sec, usec)
bool = pkt->edns
size = pkt->edns_udp_size
pkt->set_edns_udp_size(size)
rcode = pkt->edns_extended_rcode
pkt->set_edns_extended_rcode(rcode)
v = pkt->edns_version
pkt->set_edns_version(v)
z = pkt->edns_z
pkt->set_edns_z(z)
do = pkt->edns_do
pkt->set_edns_do(do)
rdata = pkt->edns_data
pkt->set_edns_data(rdata)
pkt->set_flags(flags)
rrlist = pkt->rr_list_by_name(rdata, section)
rrlist = pkt->rr_list_by_type(type, section)
rrlist = pkt->rr_list_by_name_and_type(rdata, type, section)
bool = pkt->rr(section, rr) # Check if rr exists
pkt->push_rr(section, rr)
pkt->safe_push_rr(section, rr)
count = pkt->section_count(section)
bool = pkt->empty
rr = pkt->tsig
pkt->set_tsig(rr)
type = pkt->reply_type
rrlist = pkt->get_rrsigs_for_name_and_type(rdata, rrtype)
rrlist = pkt->get_rrsigs_for_type(rrtype)
=head1 SEE ALSO
http://www.nlnetlabs.nl/projects/ldns
=head1 AUTHOR
Erik Pihl Ostlyngen, E<lt>erik.ostlyngen@uninett.noE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2013 by UNINETT Norid AS
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.14.2 or,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@@ -0,0 +1,71 @@
package DNS::LDNS::RBNode;
use 5.008008;
use strict;
use warnings;
use DNS::LDNS;
our $VERSION = '0.61';
# Note: This class does not have a constructor. Thus, it can not be created
# as an individual object. The data structure of the object will always be
# owned and freed by its parent object.
sub next {
my $self = shift;
return DNS::LDNS::GC::own($self->_next, $self);
}
sub previous {
my $self = shift;
return DNS::LDNS::GC::own($self->_previous, $self);
}
sub next_nonglue {
my $self = shift;
return DNS::LDNS::GC::own($self->_next_nonglue, $self);
}
sub name {
my ($self) = @_;
return DNS::LDNS::GC::own($self->_name, $self);
}
sub DESTROY {
DNS::LDNS::GC::free($_[0]);
}
1;
__END__
=head1 NAME
DNS::LDNS::RBNode - Node in the RBTree
=head1 SYNOPSIS
use DNS::LDNS ':all'
node2 = node->next
node2 = node->next_nonglue
bool = node->is_null
dnssec_name = node->name
=head1 SEE ALSO
http://www.nlnetlabs.nl/projects/ldns
=head1 AUTHOR
Erik Pihl Ostlyngen, E<lt>erik.ostlyngen@uninett.noE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2013 by UNINETT Norid AS
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.14.2 or,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@@ -0,0 +1,59 @@
package DNS::LDNS::RBTree;
use 5.008008;
use strict;
use warnings;
use DNS::LDNS;
our $VERSION = '0.61';
# Note: Since this class does not have a constructor, we can let its child
# objects be owned by the parent. This reduces the recursion depth on
# DESTROY.
sub first {
my $self = shift;
return DNS::LDNS::GC::own($self->_first, $self);
}
sub last {
my $self = shift;
return DNS::LDNS::GC::own($self->_last, $self);
}
sub DESTROY {
DNS::LDNS::GC::free($_[0]);
}
1;
__END__
=head1 NAME
DNS::LDNS::RBTree - Tree of DNSSecName nodes
=head1 SYNOPSIS
use DNS::LDNS ':all'
rbnode = rbtree->first
rbnode = rbtree->last
=head1 SEE ALSO
http://www.nlnetlabs.nl/projects/ldns
=head1 AUTHOR
Erik Pihl Ostlyngen, E<lt>erik.ostlyngen@uninett.noE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2013 by UNINETT Norid AS
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.14.2 or,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@@ -0,0 +1,91 @@
package DNS::LDNS::RData;
use 5.008008;
use strict;
use warnings;
use DNS::LDNS;
our $VERSION = '0.61';
sub new {
my ($class, $type, $str) = @_;
return _new($type, $str);
}
sub cat {
my ($self, $other) = @_;
my $s = _cat($self, $other);
$DNS::LDNS::last_status = $s;
return $s;
}
sub nsec3_hash_name {
my ($self, $algorithm, $iterations, $salt) = @_;
return DNS::LDNS::GC::own(
$self->_nsec3_hash_name($algorithm, $iterations, $salt), $self);
}
sub DESTROY {
DNS::LDNS::GC::free($_[0]);
}
1;
__END__
=head1 NAME
DNS::LDNS::RData - Rdata field or a dname in an rr
=head1 SYNOPSIS
use DNS::LDNS ':all'
my rd = new DNS::LDNS::RData(rdf_type, str)
rd2 = rd->clone
rdf_type = rd->type
rd->set_type(rdf_type)
rd->print(\*FILE)
str = rd->to_string
count = rd->label_count
rd2 = rd->label(pos)
bool = rd->is_wildcard
bool = rd->matches_wildcard(wildcard)
bool = rd->is_subdomain(parent)
rd2 = rd->left_chop
status = rd->cat(rd2)
rd->compare(rd2)
rd2 = rd->address_reverse
rd2 = rd->dname_reverse
rd2 = rd->nsec3_hash_name(name, algorithm, iterations, salt)
epoch = rd->to_unix_time
( epoch = rd->2native_time_t )
rr_type = rd->to_rr_type
=head1 SEE ALSO
http://www.nlnetlabs.nl/projects/ldns
=head1 AUTHOR
Erik Pihl Ostlyngen, E<lt>erik.ostlyngen@uninett.noE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2013 by UNINETT Norid AS
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.14.2 or,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@@ -0,0 +1,493 @@
package DNS::LDNS::RR;
use 5.008008;
use strict;
use warnings;
use DNS::LDNS ':all';
our $VERSION = '0.61';
sub new {
my $class = shift;
my $rr;
my $status = &LDNS_STATUS_OK;
if (scalar(@_) == 0) {
$rr = _new;
}
elsif (scalar(@_) == 1) {
$rr = _new_from_str($_[0], 0,
undef, undef,
$status);
}
else {
my %args = @_;
# Perl 5.25 does not allow us to pass read-only undef into a
# parameter changing function. So we must send it with a variable.
my $undef = undef;
if ($args{str}) {
$rr = _new_from_str($args{str},
$args{default_ttl} || 0,
$args{origin},
$args{prev} ? ${$args{prev}} : $undef,
$status);
}
elsif ($args{filename} or $args{file}) {
my $line_nr = 0;
my $file = $args{file};
if ($args{filename}) {
unless (open FILE, $args{filename}) {
$DNS::LDNS::last_status = &LDNS_STATUS_FILE_ERR;
$DNS::LDNS::line_nr = 0;
return;
}
$file = \*FILE;
}
my $ttl = 0;
$rr = _new_from_file($file,
$args{default_ttl} ? ${$args{default_ttl}} : $ttl,
$args{origin} ? ${$args{origin}} : $undef,
$args{prev} ? ${$args{prev}} : $undef,
$status,
$line_nr);
if ($args{filename}) {
close $file;
}
$DNS::LDNS::line_nr = $line_nr;
}
elsif ($args{type}) {
$rr = _new_from_type($args{type});
if ($args{owner}) {
$rr->set_owner(ref $args{owner} ? $args{owner} :
new DNS::LDNS::RData(&LDNS_RDF_TYPE_DNAME, $args{owner}));
}
$rr->set_ttl($args{ttl}) if ($args{ttl});
$rr->set_class($args{class}) if ($args{class});
if ($args{rdata}) {
if (!$rr->set_rdata(@{$args{rdata}})) {
$DNS::LDNS::last_status = &LDNS_STATUS_SYNTAX_RDATA_ERR;
return;
}
}
}
}
if (!defined $rr) {
$DNS::LDNS::last_status = $status;
return;
}
return $rr;
}
sub owner {
my $self = shift;
return DNS::LDNS::GC::own($self->_owner, $self);
}
sub set_owner {
my ($self, $owner) = @_;
DNS::LDNS::GC::disown(my $old = $self->owner);
$self->_set_owner($owner);
return DNS::LDNS::GC::own($owner, $self);
}
sub dname {
return $_[0]->owner->to_string;
}
sub rdata {
my ($self, $index) = @_;
return DNS::LDNS::GC::own($self->_rdata($index), $self);
}
# replace all existing rdata with new ones. Requires the
# input array to be exactly same length as rd_count
sub set_rdata {
my ($self, @rdata) = @_;
if (scalar @rdata != $self->rd_count) {
# Hopefully this is a proper error to return here...
$DNS::LDNS::last_status = LDNS_STATUS_SYNTAX_RDATA_ERR;
return;
}
my $i = 0;
for (@rdata) {
my $oldrd = _set_rdata($self, my $copy = $_->clone, $i);
DNS::LDNS::GC::disown(my $old = $oldrd);
DNS::LDNS::GC::own($copy, $self);
$i++;
}
return 1;
}
sub push_rdata {
my ($self, @rdata) = @_;
for (@rdata) {
# Push a copy in case the input rdata are already owned
$self->_push_rdata(my $copy = $_->clone);
DNS::LDNS::GC::own($copy, $self);
}
}
sub rrsig_typecovered {
my $self = shift;
return DNS::LDNS::GC::own($self->_rrsig_typecovered, $self);
}
sub rrsig_set_typecovered {
my ($self, $type) = shift;
DNS::LDNS::GC::disown(my $old = $self->rrsig_typecovered);
my $result = $self->_rrsig_set_typecovered(my $copy = $type->clone);
DNS::LDNS::GC::own($copy, $self);
return $result;
}
sub rrsig_algorithm {
my $self = shift;
return DNS::LDNS::GC::own($self->_rrsig_algorithm, $self);
}
sub rrsig_set_algorithm {
my ($self, $algo) = shift;
DNS::LDNS::GC::disown(my $old = $self->rrsig_algorithm);
my $result = $self->_rrsig_set_algorithm(my $copy = $algo->clone);
DNS::LDNS::GC::own($copy, $self);
return $result;
}
sub rrsig_expiration {
my $self = shift;
return DNS::LDNS::GC::own($self->_rrsig_expiration, $self);
}
sub rrsig_set_expiration {
my ($self, $date) = shift;
DNS::LDNS::GC::disown(my $old = $self->rrsig_expiration);
my $result = $self->_rrsig_set_expiration(my $copy = $date->clone);
DNS::LDNS::GC::own($copy, $self);
return $result;
}
sub rrsig_inception {
my $self = shift;
return DNS::LDNS::GC::own($self->_rrsig_inception, $self);
}
sub rrsig_set_inception {
my ($self, $date) = shift;
DNS::LDNS::GC::disown(my $old = $self->rrsig_inception);
my $result = $self->_rrsig_set_inception(my $copy = $date->clone);
DNS::LDNS::GC::own($copy, $self);
return $result;
}
sub rrsig_keytag {
my $self = shift;
return DNS::LDNS::GC::own($self->_rrsig_keytag, $self);
}
sub rrsig_set_keytag {
my ($self, $tag) = shift;
DNS::LDNS::GC::disown(my $old = $self->rrsig_keytag);
my $result = $self->_rrsig_set_keytag(my $copy = $tag->clone);
DNS::LDNS::GC::own($copy, $self);
return $result;
}
sub rrsig_sig {
my $self = shift;
return DNS::LDNS::GC::own($self->_rrsig_sig, $self);
}
sub rrsig_set_sig {
my ($self, $sig) = shift;
DNS::LDNS::GC::disown(my $old = $self->rrsig_sig);
my $result = $self->_rrsig_set_sig(my $copy = $sig->clone);
DNS::LDNS::GC::own($copy, $self);
return $result;
}
sub rrsig_labels {
my $self = shift;
return DNS::LDNS::GC::own($self->_rrsig_labels, $self);
}
sub rrsig_set_labels {
my ($self, $lab) = shift;
DNS::LDNS::GC::disown(my $old = $self->rrsig_labels);
my $result = $self->_rrsig_set_labels(my $copy = $lab->clone);
DNS::LDNS::GC::own($copy, $self);
return $result;
}
sub rrsig_origttl {
my $self = shift;
return DNS::LDNS::GC::own($self->_rrsig_origttl, $self);
}
sub rrsig_set_origttl {
my ($self, $ttl) = shift;
DNS::LDNS::GC::disown(my $old = $self->rrsig_origttl);
my $result = $self->_rrsig_set_origttl(my $copy = $ttl->clone);
DNS::LDNS::GC::own($copy, $self);
return $result;
}
sub rrsig_signame {
my $self = shift;
return DNS::LDNS::GC::own($self->_rrsig_signame, $self);
}
sub rrsig_set_signame {
my ($self, $name) = shift;
DNS::LDNS::GC::disown(my $old = $self->rrsig_signame);
my $result = $self->_rrsig_set_signame(my $copy = $name->clone);
DNS::LDNS::GC::own($copy, $self);
return $result;
}
sub dnskey_algorithm {
my $self = shift;
return DNS::LDNS::GC::own($self->_dnskey_algorithm, $self);
}
sub dnskey_set_algorithm {
my ($self, $algo) = shift;
DNS::LDNS::GC::disown(my $old = $self->dnskey_algorithm);
my $result = $self->_dnskey_set_algorithm(my $copy = $algo->clone);
DNS::LDNS::GC::own($copy, $self);
return $result;
}
sub dnskey_flags {
my $self = shift;
return DNS::LDNS::GC::own($self->_dnskey_flags, $self);
}
sub dnskey_set_flags {
my ($self, $flags) = shift;
DNS::LDNS::GC::disown(my $old = $self->flags);
my $result = $self->_dnskey_set_flags(my $copy = $flags->clone);
DNS::LDNS::GC::own($copy, $self);
return $result;
}
sub dnskey_protocol {
my $self = shift;
return DNS::LDNS::GC::own($self->_dnskey_protocol, $self);
}
sub dnskey_set_protocol {
my ($self, $proto) = shift;
DNS::LDNS::GC::disown(my $old = $self->dnskey_protocol);
my $result = $self->_dnskey_set_protocol(my $copy = $proto->clone);
DNS::LDNS::GC::own($copy, $self);
return $result;
}
sub dnskey_key {
my $self = shift;
return DNS::LDNS::GC::own($self->_dnskey_key, $self);
}
sub dnskey_set_key {
my ($self, $key) = shift;
DNS::LDNS::GC::disown(my $old = $self->dnskey_key);
my $result = $self->_dnskey_set_key(my $copy = $key->clone);
DNS::LDNS::GC::own($copy, $self);
return $result;
}
sub nsec3_next_owner {
my $self = shift;
return DNS::LDNS::GC::own($self->_nsec3_next_owner, $self);
}
sub nsec3_bitmap {
my $self = shift;
return DNS::LDNS::GC::own($self->_nsec3_bitmap, $self);
}
sub nsec3_salt {
my $self = shift;
return DNS::LDNS::GC::own($self->_nsec3_salt, $self);
}
sub hash_name_from_nsec3 {
my ($self, $name) = @_;
my $hash = $self->_hash_name_from_nsec3($name);
return DNS::LDNS::GC::own($self->_hash_name_from_nsec3($name), $self);
}
sub verify_denial {
my ($self, $nsecs, $rrsigs) = @_;
my $s = _verify_denial($self, $nsecs, $rrsigs);
$DNS::LDNS::last_status = $s;
return $s;
}
sub verify_denial_nsec3 {
my ($self, $nsecs, $rrsigs, $packet_rcode, $packet_qtype,
$packet_nodata) = @_;
my $s = _verify_denial_nsec3($self, $nsecs, $rrsigs, $packet_rcode,
$packet_qtype, $packet_nodata);
$DNS::LDNS::last_status = $s;
return $s;
}
sub verify_denial_nsec3_match {
my ($self, $nsecs, $rrsigs, $packet_rcode, $packet_qtype,
$packet_nodata) = @_;
my $status;
my $match = _verify_denial_nsec3_match($self, $nsecs, $rrsigs, $packet_rcode, $packet_qtype, $packet_nodata, $status);
$DNS::LDNS::last_status = $status;
if ($status != &LDNS_STATUS_OK) {
return;
}
# $match is an RR owned by the $nsecs list.
return DNS::LDNS::GC::own($match, $nsecs);
}
sub DESTROY {
DNS::LDNS::GC::free($_[0]);
}
1;
__END__
=head1 NAME
DNS::LDNS::RR - Resource record
=head1 SYNOPSIS
use DNS::LDNS ':all'
my rr = new DNS::LDNS::RR('mylabel 3600 IN A 168.10.10.10')
my rr = new DNS::LDNS::RR(
str => 'mylabel 3600 IN A 168.10.10.10',
default_ttl => 3600, # optional
origin => $origin_rdata, # optional
prev => \$prev_rdata, # optional
)
my rr = new DNS::LDNS::RR(
filename => '/path/to/rr',
default_ttl => \$ttl, # optional
origin => \$origin_rdata, # optional
prev => \$prev_rdata) # optional
my rr = new DNS::LDNS::RR(
file => \*FILE,
default_ttl => \$ttl, # optional
origin => \$origin_rdata, # optional
prev => \$prev_rdata) # optional
my rr = new DNS::LDNS::RR(
type => LDNS_RR_TYPE_A,
rdata => [new DNS::LDNS::RData(...), new DNS::LDNS::RData(...), ...],
class => LDNS_RR_CLASS_IN, # optional
ttl => 3600, # optional
owner => new DNS::LDNS::RData(LDNS_RDF_TYPE_DNAME, 'mylabel'), # optional)
my rr = new DNS::LDNS::RR
rr2 = rr->clone
rr->print(\*FILE)
rr->to_string
ttl = rr->ttl
rr->set_ttl(ttl)
type = rr->type
rr->set_type(type)
class = rr->class
rr->set_class(class)
rdata = rr->owner
rr->set_owner(rdata)
str = rr->dname
count = rr->rd_count
rdata = rr->rdata(index)
rr->set_rdata(rd1, rd2, rd3, ...)
rr->push_rdata(rd1, rd2, rd3, ...)
rdata = rr->pop_rdata
rr->compare(rr2)
rr->compare_dname(rr2)
rr->compare_no_rdata(rr2)
rr->compare_ds(rr2)
hash = rr->hash_name_from_nsec3(dname)
status = rr->verify_denial(nsecs, rrsigs)
status = rr->verify_denial_nsec3(nsecs, rrsigs, packet_rcode, packet_qtype, packet_nodata)
match = rr->verify_denial_nsec3_match(nsecs, rrsigs, packet_rcode, packet_qtype, packet_nodata)
rr->nsec3_add_param_rdfs(algorithm, flags, iterations, salt)
a = rr->nsec3_algorithm
f = rr->nsec3_flags
o = rr->nsec3_optout
i = rr->nsec3_iterations
rdata = rr->nsec3_next_owner
rdata = rr->nsec3_bitmap
rdata = rr->nsec3_salt
rdata = rr->rrsig_keytag
bool = rr->rrsig_set_keytag(rdata)
rdata = rr->rrsig_signame
bool = rr->rrsig_set_signame(rdata)
rdata = rr->rrsig_sig
bool = rr->rrsig_set_sig(rdata)
rdata = rr->rrsig_algorithm
bool = rr->rrsig_set_algorithm(rdata)
rdata = rr->rrsig_inception
bool = rr->rrsig_set_inception(rdata)
rdata = rr->rrsig_expiration
bool = rr->rrsig_set_expiration(rdata)
rdata = rr->rrsig_labels
bool = rr->rrsig_set_labels(rdata)
rdata = rr->rrsig_origttl
bool = rr->rrsig_set_origttl(rdata)
key = rr->get_dnskey_for_rrsig(rrlist)
rdata = rr->dnskey_algorithm
bool = rr->dnskey_set_algorithm(rdata)
rdata = rr->dnskey_flags
bool = rr->dnskey_set_flags(rdata)
rdata = rr->dnskey_protocol
bool = rr->dnskey_set_protocol(rdata)
rdata = rr->dnskey_key
bool = rr->dnskey_set_key(rdata)
bits = rr->dnskey_key_size
tag = rr->calc_keytag
ds = rr->key_to_ds(hash)
rr->is_question
=head1 SEE ALSO
http://www.nlnetlabs.nl/projects/ldns
=head1 AUTHOR
Erik Pihl Ostlyngen, E<lt>erik.ostlyngen@uninett.noE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2013 by UNINETT Norid AS
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.14.2 or,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@@ -0,0 +1,183 @@
package DNS::LDNS::RRList;
use 5.008008;
use strict;
use warnings;
use DNS::LDNS;
our $VERSION = '0.61';
sub new {
my ($class, %args) = @_;
if ($args{hosts_filename} or $args{hosts_file}) {
my $file = $args{hosts_file};
if ($args{hosts_filename}) {
unless (open FILE, $args{hosts_filename}) {
$DNS::LDNS::last_status = &LDNS_STATUS_FILE_ERR;
$DNS::LDNS::line_nr = 0;
return;
}
$file = \*FILE;
}
my $list = _new_hosts_from_file($file, $DNS::LDNS::line_nr);
if ($args{hosts_filename}) {
close $file;
}
return $list;
}
return _new();
}
sub rr {
my ($self, $index) = @_;
return DNS::LDNS::GC::own($self->_rr($index), $self);
}
sub push {
my ($self, @rrs) = @_;
for my $rr (@rrs) {
# Push a copy of the rr in case it is already owned
$self->_push(my $copy = $rr->clone);
DNS::LDNS::GC::own($copy, $self);
}
}
sub push_list {
my ($self, $list) = @_;
$self->_push_list(my $copy = $list->clone);
DNS::LDNS::GC::own($copy, $self);
}
sub verify {
my ($self, $sig, $keys) = @_;
my $goodkeys = new DNS::LDNS::RRList;
my $s = _verify($self, $sig, $keys, $goodkeys);
$DNS::LDNS::last_status = $s;
return wantarray ? ($s, $goodkeys) : $s;
}
sub verify_time {
my ($self, $sig, $keys, $checktime) = @_;
my $goodkeys = new DNS::LDNS::RRList;
my $s = _verify_time($self, $sig, $keys, $checktime, $goodkeys);
$DNS::LDNS::last_status = $s;
return wantarray ? ($s, $goodkeys) : $s;
}
sub verify_notime {
my ($self, $sig, $keys) = @_;
my $goodkeys = new DNS::LDNS::RRList;
my $s = _verify_notime($self, $sig, $keys, $goodkeys);
$DNS::LDNS::last_status = $s;
return wantarray ? ($s, $goodkeys) : $s;
}
sub verify_rrsig_keylist {
my ($self, $sig, $keys) = @_;
my $goodkeys = new DNS::LDNS::RRList;
my $s = _verify_rrsig_keylist($self, $sig, $keys, $goodkeys);
$DNS::LDNS::last_status = $s;
return wantarray ? ($s, $goodkeys) : $s;
}
sub verify_rrsig_keylist_notime {
my ($self, $sig, $keys, $check_time) = @_;
my $goodkeys = new DNS::LDNS::RRList;
my $s = _verify_rrsig_keylist_notime($self, $sig, $keys, $goodkeys);
$DNS::LDNS::last_status = $s;
return wantarray ? ($s, $goodkeys) : $s;
}
sub get_dnskey_for_rrsig {
my ($self, $rrsig) = @_;
return DNS::LDNS::GC::own(_get_dnskey_for_rrsig($rrsig, $self), $self);
}
sub get_rrsig_for_name_and_type {
my ($self, $name, $type) = @_;
return DNS::LDNS::GC::own(
_get_dnskey_for_name_and_type($name, $type, $self), $self);
}
sub DESTROY {
DNS::LDNS::GC::free($_[0]);
}
1;
__END__
=head1 NAME
DNS::LDNS::RRList - List of rrs
=head1 SYNOPSIS
use DNS::LDNS ':all'
my l = new DNS::LDNS::RRList
my l = new DNS::LDNS::RRList(hosts_file => \*FILE)
my l = new DNS::LDNS::RRList(hosts_filename => fname)
my l2 = l->clone
l->to_string
l->print(\*FILE)
count = l->rr_count
rr = l->rr(index)
l->push(@rr)
rr = l->pop
l->push_list(l2)
l2 = l->pop_list(count)
l2 = l->pop_rrset
l->compare(l2)
l2 = l->subtype_by_rdata(rdata, pos)
bool = l->is_rrset
bool = l->contains_rr(rr)
(status, goodkeys) = l->verify(sig, keys)
(status, goodkeys) = l->verify_time(sig, keys, checktime)
(status, goodkeys) = l->verify_notime(sig, keys)
(status, goodkeys) = l->verify_rrsig_keylist(sig, keys)
(status, goodkeys) = l->verify_rrsig_keylist_time(sig, keys, checktime)
(status, goodkeys) = l->verify_rrsig_keylist_notime(sig, keys)
status = l->verify_rrsig(sig, keys)
status = l->verify_rrsig_time(sig, keys, checktime)
rr = l->create_empty_rrsig(key)
rrlist = l->sign_public(keylist)
rrlist->canonicalize
rrlist->sort
rrlist->sort_nsec3 # the list must contain only nsec3 rrs
rr = keylist->get_dnskey_for_rrsig(rrsig)
rr = keylist->get_rrsig_for_name_and_type(name, type)
=head1 SEE ALSO
http://www.nlnetlabs.nl/projects/ldns
=head1 AUTHOR
Erik Pihl Ostlyngen, E<lt>erik.ostlyngen@uninett.noE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2013 by UNINETT Norid AS
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.14.2 or,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@@ -0,0 +1,355 @@
package DNS::LDNS::Resolver;
use 5.008008;
use strict;
use warnings;
use DNS::LDNS ':all';
our $VERSION = '0.61';
sub new {
my ($class, %args) = @_;
my $file;
my $status = &LDNS_STATUS_OK;
if ($args{filename}) {
unless (open FILE, $args{filename}) {
$DNS::LDNS::last_status = &LDNS_STATUS_FILE_ERR;
$DNS::LDNS::line_nr = 0;
return;
}
$file = \*FILE;
}
elsif ($args{file}) {
$file = $args{file};
}
my $resolver;
if ($file) {
$resolver = _new_from_file($file, $status);
}
else {
$resolver = _new();
}
if ($args{filename}) {
close $file;
}
$DNS::LDNS::last_status = $status;
if (!defined $resolver) {
return;
}
return $resolver;
}
sub dnssec_anchors {
my $self = shift;
return DNS::LDNS::GC::own($self->_dnssec_anchors, $self);
}
sub push_dnssec_anchor {
my ($self, $rr) = @_;
_push_dnssec_anchor($self, my $copy = $rr->clone);
DNS::LDNS::GC::own($copy, $self);
}
sub set_dnssec_anchors {
my ($self, $l) = @_;
DNS::LDNS::GC::disown(my $old = $self->dnssec_anchors);
$self->_set_dnssec_anchors($l);
DNS::LDNS::GC::own($l, $self);
return $l;
}
sub domain {
my $self = shift;
return DNS::LDNS::GC::own($self->_domain, $self);
}
sub set_domain {
my ($self, $dom) = @_;
DNS::LDNS::GC::disown(my $old = $self->domain);
_set_domain($self, my $copy = $dom->clone);
DNS::LDNS::GC::own($copy, $self);
}
sub nameservers {
my $self = shift;
my $list = _nameservers($self);
for my $r (@$list) {
DNS::LDNS::GC::own($r, $self);
}
return wantarray ? @$list : $list;
}
sub push_nameserver {
my ($self, $n) = @_;
my $s = _push_nameserver($self, my $copy = $n->clone);
DNS::LDNS::GC::own($copy, $self);
$DNS::LDNS::last_status = $s;
return $s;
}
sub pop_nameserver {
my $self = shift;
return DNS::LDNS::GC::own($self->_pop_nameserver);
}
sub push_searchlist {
my ($self, $rd) = @_;
_push_searchlist($self, my $copy = $rd->clone);
DNS::LDNS::GC::own($copy, $self);
}
sub searchlist {
my $self = shift;
my $list = _searchlist($self);
for my $r (@$list) {
DNS::LDNS::GC::own($r, $self);
}
return wantarray ? @$list : $list;
}
sub timeout {
my $self = shift;
my $t = _timeout($self);
return wantarray ? @$t : $t;
}
sub rtt {
my $self = shift;
my $list = _rtt($self);
return wantarray ? @$list : $list;
}
sub set_rtt {
my ($self, @rtt) = @_;
# FIXME: Validate @rtt, existence, size
_set_rtt($self, \@rtt);
}
sub fetch_valid_domain_keys {
my ($self, $domain, $keys) = @_;
my $status;
my $trusted = _fetch_valid_domain_keys($self, $domain, $keys, $status);
$DNS::LDNS::last_status = $status;
if (!$trusted) {
return;
}
return DNS::LDNS::GC::own($trusted, $self);
}
sub fetch_valid_domain_keys_time {
my ($self, $domain, $keys, $checktime) = @_;
my $status;
my $trusted = _fetch_valid_domain_keys_time(
$self, $domain, $keys, $checktime, $status);
$DNS::LDNS::last_status = $status;
if (!$trusted) {
return;
}
return DNS::LDNS::GC::own($trusted, $self);
}
sub prepare_query_pkt {
my ($self, $rdata, $type, $class, $flags) = @_;
my $s = &LDNS_STATUS_OK;
my $qry = _prepare_query_pkt($self, $rdata, $type, $class, $flags, $s);
$DNS::LDNS::last_status = $s;
if ($s != LDNS_STATUS_OK) {
return;
}
return $qry;
}
sub send {
my ($self, $rdata, $type, $class, $flags) = @_;
my $s = &LDNS_STATUS_OK;
my $ans = _send($self, $rdata, $type, $class, $flags, $s);
$DNS::LDNS::last_status = $s;
if ($s != LDNS_STATUS_OK) {
return;
}
return $ans;
}
sub send_pkt {
my ($self, $qry) = @_;
my $s = &LDNS_STATUS_OK;
my $ans = _send_pkt($self, $qry, $s);
$DNS::LDNS::last_status = $s;
if ($s != LDNS_STATUS_OK) {
return;
}
return $ans;
}
sub verify_trusted {
my ($self, $rrset, $rrsigs, $validating_keys) = @_;
my $s = _verify_trusted($self, $rrset, $rrsigs, $validating_keys);
$DNS::LDNS::last_status = $s;
return $s;
}
sub verify_trusted_time {
my ($self, $rrset, $rrsigs, $check_time, $validating_keys) = @_;
my $s = _verify_trusted_time($self, $rrset, $rrsigs, $check_time,
$validating_keys);
$DNS::LDNS::last_status = $s;
return $s;
}
sub DESTROY {
DNS::LDNS::GC::free($_[0]);
}
1;
__END__
=head1 NAME
DNS::LDNS::Resolver - DNS resolver
=head1 SYNOPSIS
use DNS::LDNS ':all'
my r = new DNS::LDNS::Resolver(filename => '/my/resolv.conf')
my r = new DNS::LDNS::Resolver(file => \*FILE)
my r = new DNS::LDNS::Resolver
bool = r->dnssec
r->set_dnssec(bool)
bool = r->dnssec_cd # Resolver sets the CD bit
r->set_dnssec_cd(bool)
port = r->port
r->set_port(port)
bool = r->recursive
r->set_recursive(bool)
bool = r->debug
r->set_debug(bool)
count = r->retry
r->set_retry(count)
count = r->retrans
r->set_retrans(count)
bool = r->fallback # Resolver truncation fallback mechanism
r->set_fallback(bool)
bool = r->ip6
r->set_ip6(bool)
size = r->edns_udp_size
r->set_edns_udp_size(size)
bool = r->usevc # Use virtual circuit (TCP)
r->set_usevc(bool)
r->fail
r->set_fail
r->defnames
r->set_defnames
r->dnsrch
r->set_dnsrch
r->igntc
r->set_igntc
bool = r->random # randomize nameserver before usage
r->set_random(bool)
rrlist = r->dnssec_anchors # list of trusted DNSSEC anchors
r->push_dnssec_anchor(rr)
r->set_dnssec_anchors(rrlist)
rdata = r->domain # Domain to add to relative queries
r->set_domain(rdata)
@rdata = r->nameservers
count = r->nameserver_count
r->push_nameserver(rdata)
rdata = r->pop_nameserver
r->nameservers_randomize
str = r->tsig_keyname
r->set_tsig_keyname(str)
str = r->tsig_algorithm
r->set_tsig_algorithm(str)
str = r->tsig_keydata
r->set_tsig_keydata(str)
count = r->searchlist_count
r->push_searchlist(rdata)
@rdata = r->searchlist
@times = r->rtt # Round trip times
r->set_rtt(@rtt)
time = r->nameserver_rtt(pos)
r->set_nameserver_rtt(pos, time)
(sec, usec) = r->timeout
r->set_timeout(sec, usec)
# DNSSec validation
rrlist = r->fetch_valid_domain_keys(domain, keys)
rrlist = r->fetch_valid_domain_keys_time(domain, keys, checktime)
rrlist = r->validate_domain_ds(domain, keys)
rrlist = r->validate_domain_ds_time(domain, keys, checktime)
rrlist = r->validate_domain_dnskey(domain, keys)
rrlist = r->validate_domain_dnskey_time(domain, keys, checktime)
status = r->verify_trusted(rrset, rrsigs, validation_keys)
status = r->verify_trusted_time(rrset, rrsigs, checktime, validation_keys)
bool = r->trusted_key(keys, trusted_keys)
chain = r->build_data_chain(qflags, dataset, pkt, orig_rr)
# Query
pkt = r->query(rdata, type, class, flags)
pkt = r->search(rdata, type, class, flags)
query = r->prepare_query_pkt(rdata, type, class, flags)
answer = r->send(rdata, type, class, flags)
answer = r->send_pkt(query)
rrlist = r->get_rr_list_addr_by_name(name, class, flags)
rrlist = r->get_rr_list_name_by_addr(addr, class, flags)
=head1 SEE ALSO
http://www.nlnetlabs.nl/projects/ldns
=head1 AUTHOR
Erik Pihl Ostlyngen, E<lt>erik.ostlyngen@uninett.noE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2013 by UNINETT Norid AS
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.14.2 or,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@@ -0,0 +1,140 @@
package DNS::LDNS::Zone;
use 5.008008;
use strict;
use warnings;
use DNS::LDNS ':all';
our $VERSION = '0.61';
sub new {
my ($class, %args) = @_;
my $line_nr = 0;
my $status = &LDNS_STATUS_OK;
my $zone;
my $file;
if ($args{filename}) {
unless (open FILE, $args{filename}) {
$DNS::LDNS::last_status = &LDNS_STATUS_FILE_ERR;
$DNS::LDNS::line_nr = 0;
return;
}
$file = \*FILE;
}
elsif ($args{file}) {
$file = $args{file};
}
if ($file) {
$zone = _new_from_file($file,
$args{origin},
$args{default_ttl} || 0,
$args{class} || 0,
$status, $line_nr);
}
else {
$zone = _new();
}
if ($args{filename}) {
close $file;
}
$DNS::LDNS::last_status = $status;
$DNS::LDNS::line_nr = $line_nr;
if (!defined $zone) {
return;
}
return $zone;
}
sub to_string {
my $self = shift;
return join('', map { $self->$_ ? $self->$_->to_string : '' } qw/soa rrs/);
}
sub soa {
my $self = shift;
return DNS::LDNS::GC::own($self->_soa, $self);
}
sub set_soa {
my ($self, $soa) = @_;
DNS::LDNS::GC::disown(my $old = $self->soa);
$self->_set_soa(my $copy = $soa->clone);
return DNS::LDNS::GC::own($copy, $self);
}
sub rrs {
my $self = shift;
return DNS::LDNS::GC::own($self->_rrs, $self);
}
sub set_rrs {
my ($self, $list) = @_;
DNS::LDNS::GC::disown(my $old = $self->rrs);
$self->_set_rrs(my $copy = $list->clone);
return DNS::LDNS::GC::own($copy, $self);
}
sub DESTROY {
DNS::LDNS::GC::free($_[0]);
}
1;
__END__
=head1 NAME
DNS::LDNS::Zone - Parsed zonefile
=head1 SYNOPSIS
use DNS::LDNS ':all'
my z = new DNS::LDNS::Zone(
filename => '/path/to/myzone',
origin => new DNS::LDNS::RData(LDNS_RDF_TYPE_DNAME, 'myzone'), #optional
default_ttl => 3600, #optional
class => LDNS_RR_CLASS_IN, #optional
)
my z = new DNS::LDNS::Zone(
file => \*FILE,
origin => ..., default_ttl => ..., class => ...
)
my z = new DNS::LDNS::Zone
z->to_string
z->print(\*FILE)
z->canonicalize
z->sort
rr = z->soa
z->set_soa(rr)
rrlist = z->rrs
z->set_rrs(rrlist)
z->sign(keylist)
z->sign_nsec3(keylist, algorithm, flags, iterations, salt)
=head1 SEE ALSO
http://www.nlnetlabs.nl/projects/ldns
=head1 AUTHOR
Erik Pihl Ostlyngen, E<lt>erik.ostlyngen@uninett.noE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2013 by UNINETT Norid AS
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.14.2 or,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@@ -0,0 +1,136 @@
# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl DNS-LDNS.t'
#########################
# change 'tests => 2' to 'tests => last_test_to_print';
use strict;
use warnings;
use Test::More tests => 2;
BEGIN { use_ok('DNS::LDNS') };
my $fail = 0;
foreach my $constname (qw(
LDNS_AA LDNS_AD LDNS_CD LDNS_CERT_ACPKIX LDNS_CERT_IACPKIX
LDNS_CERT_IPGP LDNS_CERT_IPKIX LDNS_CERT_ISPKI LDNS_CERT_OID
LDNS_CERT_PGP LDNS_CERT_PKIX LDNS_CERT_SPKI LDNS_CERT_URI
LDNS_DEFAULT_TTL LDNS_DH LDNS_DSA LDNS_DSA_NSEC3 LDNS_ECC LDNS_ECC_GOST
LDNS_HASH_GOST LDNS_IP4ADDRLEN LDNS_IP6ADDRLEN
LDNS_KEY_REVOKE_KEY LDNS_KEY_SEP_KEY LDNS_KEY_ZONE_KEY
LDNS_MAX_DOMAINLEN LDNS_MAX_LABELLEN LDNS_MAX_PACKETLEN
LDNS_MAX_POINTERS LDNS_MAX_RDFLEN LDNS_NSEC3_VARS_OPTOUT_MASK
LDNS_PACKET_ANSWER LDNS_PACKET_IQUERY LDNS_PACKET_NODATA
LDNS_PACKET_NOTIFY LDNS_PACKET_NXDOMAIN LDNS_PACKET_QUERY
LDNS_PACKET_QUESTION LDNS_PACKET_REFERRAL LDNS_PACKET_STATUS
LDNS_PACKET_UNKNOWN LDNS_PACKET_UPDATE LDNS_PORT LDNS_PRIVATEDNS
LDNS_PRIVATEOID LDNS_QR LDNS_RA LDNS_RCODE_FORMERR LDNS_RCODE_NOERROR
LDNS_RCODE_NOTAUTH LDNS_RCODE_NOTIMPL LDNS_RCODE_NOTZONE
LDNS_RCODE_NXDOMAIN LDNS_RCODE_NXRRSET LDNS_RCODE_REFUSED
LDNS_RCODE_SERVFAIL LDNS_RCODE_YXDOMAIN LDNS_RCODE_YXRRSET LDNS_RD
LDNS_RDATA_FIELD_DESCRIPTORS_COMMON LDNS_RDF_SIZE_16BYTES
LDNS_RDF_SIZE_6BYTES LDNS_RDF_SIZE_BYTE LDNS_RDF_SIZE_DOUBLEWORD
LDNS_RDF_SIZE_WORD LDNS_RDF_TYPE_A LDNS_RDF_TYPE_AAAA LDNS_RDF_TYPE_ALG
LDNS_RDF_TYPE_APL LDNS_RDF_TYPE_ATMA LDNS_RDF_TYPE_B32_EXT
LDNS_RDF_TYPE_B64 LDNS_RDF_TYPE_CERT_ALG LDNS_RDF_TYPE_CLASS
LDNS_RDF_TYPE_DNAME LDNS_RDF_TYPE_HEX LDNS_RDF_TYPE_INT16
LDNS_RDF_TYPE_INT16_DATA LDNS_RDF_TYPE_INT32 LDNS_RDF_TYPE_INT8
LDNS_RDF_TYPE_IPSECKEY LDNS_RDF_TYPE_LOC LDNS_RDF_TYPE_NONE
LDNS_RDF_TYPE_NSAP LDNS_RDF_TYPE_NSEC LDNS_RDF_TYPE_NSEC3_NEXT_OWNER
LDNS_RDF_TYPE_NSEC3_SALT LDNS_RDF_TYPE_PERIOD LDNS_RDF_TYPE_SERVICE
LDNS_RDF_TYPE_STR LDNS_RDF_TYPE_TIME LDNS_RDF_TYPE_HIP
LDNS_RDF_TYPE_TSIGTIME LDNS_RDF_TYPE_TYPE LDNS_RDF_TYPE_UNKNOWN
LDNS_RDF_TYPE_WKS LDNS_RESOLV_ANCHOR LDNS_RESOLV_DEFDOMAIN
LDNS_RESOLV_INET LDNS_RESOLV_INET6 LDNS_RESOLV_INETANY
LDNS_RESOLV_KEYWORD LDNS_RESOLV_KEYWORDS LDNS_RESOLV_NAMESERVER
LDNS_RESOLV_OPTIONS LDNS_RESOLV_RTT_INF LDNS_RESOLV_RTT_MIN
LDNS_RESOLV_SEARCH LDNS_RESOLV_SORTLIST LDNS_RR_CLASS_ANY
LDNS_RR_CLASS_CH LDNS_RR_CLASS_COUNT LDNS_RR_CLASS_FIRST
LDNS_RR_CLASS_HS LDNS_RR_CLASS_IN LDNS_RR_CLASS_LAST LDNS_RR_CLASS_NONE
LDNS_RR_COMPRESS LDNS_RR_NO_COMPRESS LDNS_RR_OVERHEAD LDNS_RR_TYPE_A
LDNS_RR_TYPE_A6 LDNS_RR_TYPE_AAAA LDNS_RR_TYPE_AFSDB LDNS_RR_TYPE_ANY
LDNS_RR_TYPE_APL LDNS_RR_TYPE_ATMA LDNS_RR_TYPE_AXFR LDNS_RR_TYPE_CERT
LDNS_RR_TYPE_CNAME LDNS_RR_TYPE_COUNT LDNS_RR_TYPE_DHCID
LDNS_RR_TYPE_DLV LDNS_RR_TYPE_DNAME LDNS_RR_TYPE_DNSKEY LDNS_RR_TYPE_DS
LDNS_RR_TYPE_EID LDNS_RR_TYPE_FIRST LDNS_RR_TYPE_GID LDNS_RR_TYPE_GPOS
LDNS_RR_TYPE_HINFO LDNS_RR_TYPE_IPSECKEY LDNS_RR_TYPE_ISDN
LDNS_RR_TYPE_IXFR LDNS_RR_TYPE_KEY LDNS_RR_TYPE_KX LDNS_RR_TYPE_LAST
LDNS_RR_TYPE_LOC LDNS_RR_TYPE_MAILA LDNS_RR_TYPE_MAILB LDNS_RR_TYPE_MB
LDNS_RR_TYPE_MD LDNS_RR_TYPE_MF LDNS_RR_TYPE_MG LDNS_RR_TYPE_MINFO
LDNS_RR_TYPE_MR LDNS_RR_TYPE_MX LDNS_RR_TYPE_NAPTR LDNS_RR_TYPE_NIMLOC
LDNS_RR_TYPE_NS LDNS_RR_TYPE_NSAP LDNS_RR_TYPE_NSAP_PTR
LDNS_RR_TYPE_NSEC LDNS_RR_TYPE_NSEC3 LDNS_RR_TYPE_NSEC3PARAM
LDNS_RR_TYPE_NSEC3PARAMS LDNS_RR_TYPE_NULL LDNS_RR_TYPE_NXT
LDNS_RR_TYPE_OPT LDNS_RR_TYPE_PTR LDNS_RR_TYPE_PX LDNS_RR_TYPE_RP
LDNS_RR_TYPE_RRSIG LDNS_RR_TYPE_RT LDNS_RR_TYPE_SIG LDNS_RR_TYPE_SINK
LDNS_RR_TYPE_SOA LDNS_RR_TYPE_SPF LDNS_RR_TYPE_SRV LDNS_RR_TYPE_SSHFP
LDNS_RR_TYPE_TALINK LDNS_RR_TYPE_TSIG LDNS_RR_TYPE_TXT LDNS_RR_TYPE_UID
LDNS_RR_TYPE_UINFO LDNS_RR_TYPE_UNSPEC LDNS_RR_TYPE_WKS
LDNS_RR_TYPE_X25 LDNS_RSAMD5 LDNS_RSASHA1 LDNS_RSASHA1_NSEC3
LDNS_RSASHA256 LDNS_RSASHA512 LDNS_SECTION_ADDITIONAL
LDNS_SECTION_ANSWER LDNS_SECTION_ANY LDNS_SECTION_ANY_NOQUESTION
LDNS_SECTION_AUTHORITY LDNS_SECTION_QUESTION LDNS_SHA1 LDNS_SHA256
LDNS_SIGN_DSA LDNS_SIGN_DSA_NSEC3 LDNS_SIGN_ECC_GOST
LDNS_SIGN_HMACSHA1 LDNS_SIGN_HMACSHA256
LDNS_SIGN_RSAMD5 LDNS_SIGN_RSASHA1 LDNS_SIGN_RSASHA1_NSEC3
LDNS_SIGN_RSASHA256 LDNS_SIGN_RSASHA512 LDNS_STATUS_ADDRESS_ERR
LDNS_STATUS_CERT_BAD_ALGORITHM LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL
LDNS_STATUS_CRYPTO_BOGUS LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION
LDNS_STATUS_CRYPTO_NO_DNSKEY LDNS_STATUS_CRYPTO_NO_DS
LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY
LDNS_STATUS_CRYPTO_NO_RRSIG LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY
LDNS_STATUS_CRYPTO_NO_TRUSTED_DS LDNS_STATUS_CRYPTO_SIG_EXPIRED
LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED LDNS_STATUS_CRYPTO_TSIG_BOGUS
LDNS_STATUS_CRYPTO_TSIG_ERR LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR
LDNS_STATUS_CRYPTO_UNKNOWN_ALGO LDNS_STATUS_CRYPTO_VALIDATED
LDNS_STATUS_DDD_OVERFLOW LDNS_STATUS_DNSSEC_EXISTENCE_DENIED
LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND
LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED
LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED
LDNS_STATUS_DOMAINNAME_OVERFLOW LDNS_STATUS_DOMAINNAME_UNDERFLOW
LDNS_STATUS_EMPTY_LABEL LDNS_STATUS_ENGINE_KEY_NOT_LOADED
LDNS_STATUS_ERR LDNS_STATUS_FILE_ERR LDNS_STATUS_INTERNAL_ERR
LDNS_STATUS_INVALID_B32_EXT LDNS_STATUS_INVALID_B64
LDNS_STATUS_INVALID_HEX LDNS_STATUS_INVALID_INT LDNS_STATUS_INVALID_IP4
LDNS_STATUS_INVALID_IP6 LDNS_STATUS_INVALID_POINTER
LDNS_STATUS_INVALID_STR LDNS_STATUS_INVALID_TIME
LDNS_STATUS_LABEL_OVERFLOW LDNS_STATUS_MEM_ERR
LDNS_STATUS_MISSING_RDATA_FIELDS_KEY
LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG LDNS_STATUS_NETWORK_ERR
LDNS_STATUS_NOT_IMPL LDNS_STATUS_NO_DATA LDNS_STATUS_NSEC3_ERR
LDNS_STATUS_NULL LDNS_STATUS_OK LDNS_STATUS_PACKET_OVERFLOW
LDNS_STATUS_RES_NO_NS LDNS_STATUS_RES_QUERY LDNS_STATUS_SOCKET_ERROR
LDNS_STATUS_SSL_ERR LDNS_STATUS_SYNTAX_ALG_ERR
LDNS_STATUS_SYNTAX_BAD_ESCAPE LDNS_STATUS_SYNTAX_CLASS_ERR
LDNS_STATUS_SYNTAX_DNAME_ERR LDNS_STATUS_SYNTAX_EMPTY
LDNS_STATUS_SYNTAX_ERR LDNS_STATUS_SYNTAX_INCLUDE
LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL
LDNS_STATUS_SYNTAX_INTEGER_OVERFLOW
LDNS_STATUS_SYNTAX_ITERATIONS_OVERFLOW LDNS_STATUS_SYNTAX_KEYWORD_ERR
LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR LDNS_STATUS_SYNTAX_ORIGIN
LDNS_STATUS_SYNTAX_RDATA_ERR LDNS_STATUS_SYNTAX_TTL
LDNS_STATUS_SYNTAX_TTL_ERR LDNS_STATUS_SYNTAX_TYPE_ERR
LDNS_STATUS_SYNTAX_VERSION_ERR LDNS_STATUS_UNKNOWN_INET
LDNS_STATUS_WIRE_INCOMPLETE_ADDITIONAL
LDNS_STATUS_WIRE_INCOMPLETE_ANSWER
LDNS_STATUS_WIRE_INCOMPLETE_AUTHORITY
LDNS_STATUS_WIRE_INCOMPLETE_HEADER LDNS_STATUS_WIRE_INCOMPLETE_QUESTION
LDNS_TC)) {
next if (eval "my \$a = $constname; 1");
if ($@ =~ /^Your vendor has not defined LDNS macro $constname/) {
print "# pass: $@";
} else {
print "# fail: $@";
$fail = 1;
}
}
ok( $fail == 0 , 'Constants' );
#########################
# Insert your test code below, the Test::More module is use()ed here so read
# its man page ( perldoc Test::More ) for help writing this test script.

View File

@@ -0,0 +1,60 @@
use Test::More tests => 10;
use Test::Exception;
use FindBin qw/$Bin/;
use DNS::LDNS ':all';
BEGIN { use_ok('DNS::LDNS') };
# Note: This test makes queries on real internet dns data, and assumes
# that the iis.se domain is signed.
my $r = new DNS::LDNS::Resolver(filename => "/etc/resolv.conf");
$r->set_dnssec(1);
$r->set_random(0);
my $p = $r->query(
new DNS::LDNS::RData(LDNS_RDF_TYPE_DNAME, 'iis.se.'),
LDNS_RR_TYPE_SOA, LDNS_RR_CLASS_IN, LDNS_RD);
SKIP: {
skip "Resolver is not dnssec able. Skip this test.", 9 unless ($p->ad);
isa_ok($p, 'DNS::LDNS::Packet');
my $rrset = $p->rr_list_by_type(LDNS_RR_TYPE_SOA, LDNS_SECTION_ANSWER);
ok($rrset->rr_count > 0, 'Got an answer with some content');
my $chain = $r->build_data_chain(LDNS_RD, $rrset, $p, undef);
isa_ok($chain, 'DNS::LDNS::DNSSecDataChain');
isa_ok($chain->parent, 'DNS::LDNS::DNSSecDataChain');
dies_ok {
my $new_rr = new DNS::LDNS::RR(str => 'test.test. 1234 IN A 10.0.0.1');
my $t = $chain->derive_trust_tree($new_rr);
} 'Making a trust tree with foreign rr fails.';
my $rr = $chain->rrset->rr(0);
my $tree = $chain->derive_trust_tree($rr);
isa_ok($tree, 'DNS::LDNS::DNSSecTrustTree');
# Get root keys.
my $root_keys_pk = $r->query(
new DNS::LDNS::RData(LDNS_RDF_TYPE_DNAME, '.'),
LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN, LDNS_RD);
my $root_keys = $root_keys_pk->rr_list_by_type(
LDNS_RR_TYPE_DNSKEY, LDNS_SECTION_ANSWER);
is($tree->contains_keys($root_keys), LDNS_STATUS_OK,
'Root key found in trust chain');
ok($tree->depth > 1, 'The trust tree is more than one node.');
isa_ok($tree->parent(0), 'DNS::LDNS::DNSSecTrustTree');
}

View File

@@ -0,0 +1,35 @@
use Test::More tests => 7;
use FindBin qw/$Bin/;
use DNS::LDNS ':all';
BEGIN { use_ok('DNS::LDNS') };
# Create a new dnssec zone
my $z = new DNS::LDNS::DNSSecZone;
isa_ok($z, 'DNS::LDNS::DNSSecZone', 'Create an empty zone');
# Read a zone from file and create a dnssec zone from it
my $z2 = new DNS::LDNS::Zone(
filename => "$Bin/testdata/myzone.org");
$z->create_from_zone($z2);
my $rrset = $z->find_rrset(
new DNS::LDNS::RData(LDNS_RDF_TYPE_DNAME, 'ns1.myzone.org.'),
LDNS_RR_TYPE_A);
is($rrset->rrs->rr->type, LDNS_RR_TYPE_A, 'Found an A record');
is($rrset->rrs->rr->dname, 'ns1.myzone.org.', 'Dname is ns1.myzone.org.');
is($z->add_empty_nonterminals, LDNS_STATUS_OK, 'Add empty non-terminals');
my $klist = new DNS::LDNS::KeyList;
$klist->push(new DNS::LDNS::Key(filename => "$Bin/testdata/key.private"));
$klist->key(0)->set_pubkey_owner(
new DNS::LDNS::RData(LDNS_RDF_TYPE_DNAME, 'myzone.org'));
is($z->sign($klist, LDNS_SIGNATURE_REMOVE_ADD_NEW, 0), LDNS_STATUS_OK, 'Sign');
is($z->sign_nsec3($klist, LDNS_SIGNATURE_REMOVE_ADD_NEW, 1, 0, 10, 'ABBA', 0),
LDNS_STATUS_OK, 'Sign nsec3');

View File

@@ -0,0 +1,25 @@
use Test::More tests => 8;
use FindBin qw/$Bin/;
use DNS::LDNS ':all';
BEGIN { use_ok('DNS::LDNS') };
my $key = new DNS::LDNS::Key(filename => "$Bin/testdata/key.private");
ok($key, 'Created new key object from file');
is($key->algorithm, 7, 'Algorithm is NSEC3RSASHA1');
my $now = time;
$key->set_inception($now);
$key->set_expiration($now + 10000);
is($key->inception, $now, 'Inception time');
is($key->expiration, $now + 10000, 'Expiration time');
like($key->to_rr->to_string, qr|3600\s+IN\s+DNSKEY\s+256\s+3\s+7\s+AwEAAfg/ghOkk|, 'Got rr representation of key');
my $klist = new DNS::LDNS::KeyList;
$klist->push($key);
is($klist->count, 1, 'Keylist has one key');
is($$key, ${$klist->key(0)}, 'Key in keylist is the one we pushed');
# FIXME: pop is buggy in ldns 1.6.12, uncomment when this starts working
# is($klist->pop(), $$key, 'Pop key from list');
# is($klist->count, 0, 'No keys left in list');

View File

@@ -0,0 +1,47 @@
use Test::More tests => 18;
use DNS::LDNS ':all';
BEGIN { use_ok('DNS::LDNS') };
# Integer data
my $i = new DNS::LDNS::RData(LDNS_RDF_TYPE_INT32, '1237654');
is($i->to_string, '1237654', 'Integer value rdata');
my $ii = new DNS::LDNS::RData(LDNS_RDF_TYPE_INT32, '1237654X');
is($ii, undef, '1237654X is invalid');
# Period data
my $p1 = new DNS::LDNS::RData(LDNS_RDF_TYPE_PERIOD, '3h3m3s');
is($p1->to_string, sprintf("%d", 3600*3 + 60*3 + 3), 'Normalizing period');
my $pi = new DNS::LDNS::RData(LDNS_RDF_TYPE_PERIOD, '3h3X3s');
is($pi, undef, 'Invalid period value 3h3X3s');
# DNames
my $dn1 = new DNS::LDNS::RData(LDNS_RDF_TYPE_DNAME, 'azone.org');
my $dn2 = new DNS::LDNS::RData(LDNS_RDF_TYPE_DNAME, 'other.org');
my $dn3 = new DNS::LDNS::RData(LDNS_RDF_TYPE_DNAME, 'sub.other.org');
my $dn4 = new DNS::LDNS::RData(LDNS_RDF_TYPE_DNAME, 'adder.org');
$dn1->cat($dn2);
is($dn1->to_string, 'azone.org.other.org.', 'Concatenating two domain names');
my $chopped = $dn1->left_chop;
is($chopped->to_string, 'org.other.org.', 'Chop off left domain name label');
ok($dn3->is_subdomain($dn2), 'sub.other.org is subdomain of other.org');
ok(!$dn2->is_subdomain($dn3), 'other.org is not subdomain of sub.other.org');
is($dn3->label_count, 3, 'sub.other.org has 3 labels');
is($dn3->label(1)->to_string, 'other.', 'label 1 of sub.other.org is other.');
my $dni = new DNS::LDNS::RData(
LDNS_RDF_TYPE_DNAME, 'not..valid.org');
is($dni, undef, 'Invalid dname not_valid.org');
my $wc = new DNS::LDNS::RData(LDNS_RDF_TYPE_DNAME, '*.other.org');
ok($wc->is_wildcard, '*.other.org is a wildcard');
ok(!$dn3->is_wildcard, 'sub.other.org is not a wildcard');
ok($dn3->matches_wildcard($wc), 'sub.other.org matches *.other.org');
ok(!$dn4->matches_wildcard($wc), 'adder.org does not match *.other.org');
is($dn3->compare($dn4), 1, 'sub.other.org > adder.org');
is($dn4->compare($dn3), -1, 'adder.org < sub.other.org');

View File

@@ -0,0 +1,23 @@
use Test::More tests => 3;
use FindBin qw/$Bin/;
use DNS::LDNS ':all';
BEGIN { use_ok('DNS::LDNS') };
my $r = new DNS::LDNS::Resolver(filename => "/etc/resolv.conf");
$r->set_random(0);
my $p = $r->query(
new DNS::LDNS::RData(LDNS_RDF_TYPE_DNAME, 'org'),
LDNS_RR_TYPE_SOA, LDNS_RR_CLASS_IN, LDNS_RD);
isa_ok($p, 'DNS::LDNS::Packet', 'Make a simple query');
my $r2 = new DNS::LDNS::Resolver(filename => "$Bin/testdata/resolv.conf");
$r2->set_rtt(2, 3);
my @rtt = $r2->rtt;
is_deeply(\@rtt, [2, 3], "set_rtt and rtt");

View File

@@ -0,0 +1,74 @@
use Test::More tests => 19;
use FindBin qw/$Bin/;
use DNS::LDNS ':all';
BEGIN { use_ok('DNS::LDNS') };
my $rr1 = new DNS::LDNS::RR;
isa_ok($rr1, 'DNS::LDNS::RR', 'Create empty rr');
$rr1 = new DNS::LDNS::RR(
type => LDNS_RR_TYPE_SOA,
class => LDNS_RR_CLASS_CH,
ttl => 1234,
owner => 'myzone.org',
rdata => [
new DNS::LDNS::RData(LDNS_RDF_TYPE_DNAME, 'hostmaster.myzone.org'),
new DNS::LDNS::RData(LDNS_RDF_TYPE_DNAME, 'master.myzone.org'),
new DNS::LDNS::RData(LDNS_RDF_TYPE_INT32, '2012113030'),
new DNS::LDNS::RData(LDNS_RDF_TYPE_PERIOD, '12345'),
new DNS::LDNS::RData(LDNS_RDF_TYPE_PERIOD, '1827'),
new DNS::LDNS::RData(LDNS_RDF_TYPE_PERIOD, '2345678'),
new DNS::LDNS::RData(LDNS_RDF_TYPE_PERIOD, '87654')
],
);
isa_ok($rr1, 'DNS::LDNS::RR', 'Create SOA rr with rdata');
like($rr1->to_string, qr/^myzone\.org\.\s+1234\s+CH\s+SOA\s+hostmaster\.myzone\.org\.\s+master\.myzone\.org\.\s+2012113030\s+12345\s+1827\s+2345678\s+87654$/,
'Format SOA rr as string');
is($rr1->pop_rdata->to_string, '87654', 'pop rdata');
$rr1->push_rdata(new DNS::LDNS::RData(LDNS_RDF_TYPE_PERIOD, '55667'));
is($rr1->rdata(6)->to_string, '55667', 'push_rdata and access rdata by index');
my $rr2 = new DNS::LDNS::RR(str => 'myzone.org. 1234 IN SOA hostmaster.myzone.org. master.myzone.org. 2012 12345 1827 2345678 87654');
isa_ok($rr2, 'DNS::LDNS::RR', 'Create SOA rr from string');
like($rr2->to_string, qr/^myzone\.org\.\s+1234\s+IN\s+SOA\s+hostmaster\.myzone\.org\.\s+master\.myzone\.org\.\s+2012\s+12345\s+1827\s+2345678\s+87654$/,
'Format it back to string');
ok($rr1->compare($rr2) > 0, 'Compare rr, greater than');
ok($rr2->compare($rr1) < 0, 'Compare rr, less than');
is($rr1->compare($rr1), 0, 'Compare rr, equal');
my $rr3 = new DNS::LDNS::RR(str => 'ozone.org. 1234 IN SOA hostmaster.ozone.org. master.ozone.org. 2012 12345 1827 2345678 87654');
ok($rr3->compare_dname($rr1) > 0, 'Compare dname, greater than');
ok($rr1->compare_dname($rr3) < 0, 'Compare dname, less than');
is($rr1->compare_dname($rr2), 0, 'Compare dname, equal');
# Read records from a zonefile
my $origin = new DNS::LDNS::RData(LDNS_RDF_TYPE_DNAME, '.');
my $prev = $origin->clone;
my $ttl = 0;
my $count = 0;
open(ZONE, "$Bin/testdata/myzone.org");
my $rr4 = new DNS::LDNS::RR(file => \*ZONE, default_ttl => \$ttl,
origin => \$origin, prev => \$prev);
is($DNS::LDNS::last_status, LDNS_STATUS_SYNTAX_TTL, "Read ttl statement.");
is($ttl, 4500, "TTL is 4500");
$rr4 = new DNS::LDNS::RR(file => \*ZONE, default_ttl => \$ttl,
origin => \$origin, prev => \$prev);
is($DNS::LDNS::last_status, LDNS_STATUS_SYNTAX_ORIGIN, "Read origin statement.");
is($origin->to_string, "myzone.org.", "Origin is myzone.org.");
while (!eof(\*ZONE)) {
$rr4 = new DNS::LDNS::RR(file => \*ZONE, default_ttl => \$ttl,
origin => \$origin, prev => \$prev);
last unless ($rr4);
$count++;
}
is($count, 6);

View File

@@ -0,0 +1,84 @@
use Test::More tests => 24;
use FindBin qw/$Bin/;
use DNS::LDNS ':all';
BEGIN { use_ok('DNS::LDNS') };
# Create list
my $list = new DNS::LDNS::RRList;
isa_ok($list, 'DNS::LDNS::RRList', 'Create an empty rr list');
# Push/pop/count rr
$list->push(new DNS::LDNS::RR(str => 'ns.myzone.org 3600 IN AAAA ::1'));
is($list->rr_count, 1, 'Added one rr');
like($list->rr(0)->to_string, qr/^ns\.myzone\.org\.\s+3600\s+IN\s+AAAA\s+::1$/, 'Added rr is at position 0');
$list->push(new DNS::LDNS::RR(str => 'ns.myzone.org 7200 IN A 192.168.100.2'));
is($list->rr_count, 2, 'Added another rr');
like($list->rr(1)->to_string, qr/^ns\.myzone\.org\.\s+7200\s+IN\s+A\s+192\.168\.100\.2$/, 'Last added rr is at position 1');
like($list->pop->to_string, qr/^ns\.myzone\.org\.\s+7200\s+IN\s+A\s+192\.168\.100\.2$/, 'pop the last element');
is($list->rr_count, 1, '1 element left in the list');
# Push/pop list
my $l2 = new DNS::LDNS::RRList;
$l2->push(new DNS::LDNS::RR(str => 'ns2.myzone.org 3600 IN A 192.168.100.0'));
$l2->push(new DNS::LDNS::RR(str => 'ns2.myzone.org 3600 IN A 192.168.100.1'));
$list->push_list($l2);
is($list->rr_count, 3, 'Pushed two elements. List count is now 3.');
$list->push_list($l2);
$list->push_list($l2);
my $l3 = $list->pop_list(1);
is($list->rr_count, 6, 'Pushed 4 elements, popped 1, count is now 6');
is($l3->rr_count, 1, 'Popped list contains 1 elements');
$l3 = $list->pop_list(3);
is($list->rr_count, 3, 'Popped 3 elements, count is now 3');
is($l3->rr_count, 3, 'Popped list contains 3 elements');
# RRSets
ok($l2->is_rrset, 'List is rrset');
ok(!$list->is_rrset, 'List is no longer an rrset');
my $rrset = $list->pop_rrset;
ok($rrset->is_rrset, 'Popped list is rrset');
is($rrset->rr_count, 2, 'Popped rrset has two elements.');
# Compare, contains, subtype
my $rr = new DNS::LDNS::RR(str => 'ns2.myzone.org 3600 IN A 192.168.100.0');
ok($rrset->contains_rr($rr), 'RRSet contains rr '.$rr->to_string);
is($list->compare($l2), -1, '$list < $l2');
is($l2->compare($list), 1, '$l2 > $list');
$list->push(new DNS::LDNS::RR(str => 'ns3.myzone.org 3600 IN A 192.168.100.0'),
new DNS::LDNS::RR(str => 'ns3.myzone.org 3600 IN A 192.168.100.1'),
new DNS::LDNS::RR(str => 'ns4.myzone.org 3600 IN A 192.168.100.1'));
my $subtype = $list->subtype_by_rdata(
new DNS::LDNS::RData(LDNS_RDF_TYPE_A, '192.168.100.1'), 0);
is($subtype->to_string, "ns3.myzone.org.\t3600\tIN\tA\t192.168.100.1\nns4.myzone.org.\t3600\tIN\tA\t192.168.100.1\n", 'Filter rrs by rdata');
# DNSSec signature verification
my $keylist = new DNS::LDNS::RRList;
$keylist->push(
new DNS::LDNS::RR(str => 'trondheim.no. 3600 IN DNSKEY 256 3 8 AwEAAZIDdRI8I+F/J6OT8xX7CbGQYRr8rWH9dvloUlRJXcEVE2pRAez6 pJC5Odg+i2WvDUeE4tUO1gwwjU83TIinZxxsDnqr7FzvqpHeJbVd2N3d S4zaJcbjSnwMqdebmTEXSrflp8DeIAH0GQGNQjhOPubbb/nADYP2RS1i CoOADa8P'),
new DNS::LDNS::RR(str => 'trondheim.no. 3600 IN DNSKEY 257 3 8 AwEAAax9EgKyRsMpU2B0E2dZ+nkWnmZHjlBO3uXBI+2x33dG8bk+XSqr kyWTelhhsqLqIxsaYSwYgzLtn+/qzlFjKwcaU95p+Tp95MOVXYqUtRyC VyLGkzA7ZDbx7TFCi3PyLDM/Arx+DvOx6nNvA/erqIU5gYEo9Nm1KXEy rhfSn3xc96p1AOhmTuSo6EfYlPY4gxHDgJdHFv7Fi9zV6VFmJ29h0rsG 5g3pV1lvCcGcxfRLJ1u7JRw2BWMo9lgHzGuypEVV7iLnvbfDlXhF+jAS owR2JxlESC3dOgNiNWvc4pbyVXBXpP6h/5JpcxkzF7BNJMZiLN14qvam G1+LuZM8qfc=')
);
my $soalist = new DNS::LDNS::RRList;
$soalist->push(
new DNS::LDNS::RR(str => 'trondheim.no. 3600 IN SOA charm.norid.no. hostmaster.norid.no. 2013021137 14400 1800 2419200 3600')
);
my $siglist = new DNS::LDNS::RRList;
$siglist->push(
new DNS::LDNS::RR(str => 'trondheim.no. 3600 IN RRSIG SOA 8 2 3600 20130227105101 20130213090318 36381 trondheim.no. NbeN8E4pvQSDk3Dn0i8B4e2A3KAY8JrX+zcJazPTgHbT6wjzCncn3ANn 6rs+HdcCLtptyX1QbzlZD/lOY8kjJw5TEUoFX2Q/2sBYdt1aT6qgt/+H o71iUz3bk1V73zjSG/OpqG0oXmjCWSBZgzK6UI+zGlgG0Kvrc7H1pw5S ZBA=')
);
my ($status, $goodkeys) = $soalist->verify_notime($siglist, $keylist);
is ($status, LDNS_STATUS_OK, 'Verification returned status ok.');
is ($goodkeys->rr_count, 1, 'One key matched the signature.');
my $klist = new DNS::LDNS::KeyList;
$klist->push(new DNS::LDNS::Key(filename => "$Bin/testdata/key.private"));
$klist->key(0)->set_pubkey_owner(
new DNS::LDNS::RData(LDNS_RDF_TYPE_DNAME, 'myzone.org'));
my $sigs = $l2->sign_public($klist);
is($sigs->rr_count, 1, 'Sign public, got 1 rrsig');

View File

@@ -0,0 +1,13 @@
Private-key-format: v1.2
Algorithm: 7 (NSEC3RSASHA1)
Modulus: +D+CE6ST+vFtbnXLdNESSprWSpbpRqEyri20vOx/JIViYdflGQyT0SDWSAE0JqtRlq73qSTDNuR3KWG/57oQQQ5P/wdQaF4TXA/nGjQJPEnhwKVUPVl5WRvqJLpW3C5xSSkhUkwjCp8y6z4NkbX0x7kum9ZTyTai6hkAhjyXu56yXAHX80DWadGK7RmX4JNlJalp2O33hJmakw8BVpgM9yaN4TixVsmZyHLi4hLjMAsjkEEJnfV8WoMEyyjs4kdKDHQAIa854loRcOluT1FiBKgecVAjDu/mkxnqYedN68Yx/wi7D+eClGf/gZjsmuoKKxCxnvDkRCKxrdMJtrsduw==
PublicExponent: AQAB
PrivateExponent: A8m0SmhweZvFd7IEcLvf85N5QZob5SAAjffUki1poz0Fy0hoDoHKn55IpsCd8xkaHZp93O7aq7PAvbjoHLkSFmwJfHK4H1+QHA+CDzxMB8d40l+zcVw0Jc/vOrA9Mw7iW6NtBrxyrG7RcBV6T4bfPUzuESKsFJ3oznmjMGksR4iUrnYAoUgi1pCQlxhSkPM74YhNWbUxYr4gRlL2xGGcJ2qMM8KG06or/Ok+d4bxnxiDBo41THik8ptfu/DL3HrJLOJ1CrvZGy9Q3uFiCvfD9Sk+eOZz1XPkJrUDKGYGoUvZc8enStXSM+TKd3EQy5owjJt+j2h0JdYJM8pxF2EWwQ==
Prime1: /5r4e+6kJS/+UJ0DMenJGm0vxfgFHvk5yLfz+1sKd6C9qQJN5da1m6kWuPdtBG7XGhZb8cJPOfK//g9hVS9GYEDyYmhYZsPTL+1vkiecDpeEQkrf4RCtU7NXLNT/AVNe01iEnIGuKbva6z19P1hjNO23d7LXHil1oULM1W8O1Z8=
Prime2: +KGhJOe+dB5Ud9cFlspMIIpZKHvoDc8VUb2avnhicDX5YC8dVS3nBoyc1cBNgxi4nSvBSl8/fwNT1cHJsPj7Xp2FOAsIBITRnmQt2P5JDpTEuMkEjMT8h/gJ8WnJ0+/VQhLG6rfsSAXdXvVhP4VYttPdiQ0fAe8b5v2MH1VzamU=
Exponent1: UWCEVeifR9ukywOCHeUBirFScWPKNZdBR18RhWfxyC5b07ARHuihvyIxQsg7ZBrpzrtpoGmtkZRwfbFl2poHfOOQh7YS1vzngq3ERLLpo1en2vc9mckWdbx2N6bEXSau3Pikl7NNwKm3RAe6lW1NgG9iZvCAPnESqzm6PwVxop8=
Exponent2: FMsnt/dttTZoKBGilQbcMQiBBmK+eJEuHkT2MSHOUcYh0gp+sIYDQUf3QeUwVlt17ScgpkCrBctYcpMfdB6On04bOyGpDP+yrEWClBhIMeD9RtsA92juGc0Dv93yFDiFpF3/pte0+h0Lc4qgFHjpf3jemTywsC+4LKxd0K0L1wU=
Coefficient: klnXksRr0Z8HPLASytPt4EeBK3Md7MM+Ihm6DIM5PA/KO9k0s8231hspcxBDj37HYwJ7eD77svUJFzdUOqIT8gChc6uq9VI9NFggs8rn4EndoEe+zU477NpL4U09LMfbAN+NATkhDWabVIQBeGqpIAR0fxFIqGhDtkiLyNqhq3c=
Created: 20120614100023
Publish: 20120614100023
Activate: 20120614100023

View File

@@ -0,0 +1,17 @@
$TTL 4500
$ORIGIN myzone.org.
myzone.org. 1000 IN SOA (
ldns.myzone.org.
ns.ldns.myzone.org.
2012113030
12345
1827
2345678
87654 )
ns.ldns A 192.168.100.2
ns2 5600 IN AAAA 2001:dead:dead::2
ns2 6600 IN A 192.168.100.7
ns1 3600 IN A 192.168.100.2
ns1 4600 IN AAAA 2001:dead:dead::1

View File

@@ -0,0 +1,3 @@
nameserver 127.0.0.1
nameserver 192.168.100.1
search foo.bar.org

View File

@@ -0,0 +1,75 @@
use Test::More tests => 16;
use FindBin qw/$Bin/;
use DNS::LDNS ':all';
BEGIN { use_ok('DNS::LDNS') };
# Create a new zone
my $z = new DNS::LDNS::Zone;
isa_ok($z, 'DNS::LDNS::Zone', 'Create an empty zone');
# Fill inn a soa and some rrs
$z->set_soa(new DNS::LDNS::RR(str => join(' ', qw/myzone.org 1000 IN SOA
hostmaster.myzone.org. master.myzone.org. 2012113030 12345 1827 2345678
87654/)));
is($z->soa->dname, 'myzone.org.', 'Found soa record');
my $rrs = new DNS::LDNS::RRList;
$rrs->push(new DNS::LDNS::RR(str => 'ns2.myzone.org 3600 IN A 192.168.100.2'),
new DNS::LDNS::RR(str => 'ns2.myzone.org 3600 IN A 192.168.100.9'),
new DNS::LDNS::RR(str => 'ns3.myzone.org 3600 IN A 192.168.100.2'),
new DNS::LDNS::RR(str => 'ns1.myzone.org 3600 IN A 192.168.100.7'));
$z->set_rrs($rrs);
is($z->rrs->rr(0)->to_string, "ns2.myzone.org.\t3600\tIN\tA\t192.168.100.2\n",
'Check first rr');
is($z->rrs->rr(3)->to_string, "ns1.myzone.org.\t3600\tIN\tA\t192.168.100.7\n",
'Check last rr');
$z->sort;
is($z->rrs->rr(0)->to_string, "ns1.myzone.org.\t3600\tIN\tA\t192.168.100.7\n",
'Check first rr after sorting');
is($z->rrs->rr(3)->to_string, "ns3.myzone.org.\t3600\tIN\tA\t192.168.100.2\n",
'Check last rr after sorting');
# Read a zone from file
my $z2 = new DNS::LDNS::Zone(
filename => "$Bin/testdata/myzone.org", ttl => 100);
$z2->canonicalize;
like($z2->to_string, qr/\nns.ldns.myzone.org.\s+/, 'Canonicalize');
like($z2->to_string, qr/^myzone.org.\s+1000\s+IN\s+SOA\s+ldns.myzone.org.\s+ns.ldns.myzone.org.\s+2012113030\s+12345\s+1827\s+2345678\s+87654\s+/, 'Found soa rec');
like($z2->to_string, qr/ns.ldns.myzone.org.\s+4500\s+IN\s+A\s+192.168.100.2/, 'Found ns rec');
like($z2->to_string, qr/ns2.myzone.org.\s+5600\s+IN\s+AAAA\s+2001:dead:dead::2/, 'Found yet another ns rec');
is($z2->rrs->rr_count, 5, 'Zone has 5 rrs');
my $klist = new DNS::LDNS::KeyList;
$klist->push(new DNS::LDNS::Key(filename => "$Bin/testdata/key.private"));
$klist->key(0)->set_pubkey_owner(
new DNS::LDNS::RData(LDNS_RDF_TYPE_DNAME, 'myzone.org'));
my $z3 = $z2->sign($klist);
my $sigc = grep { $z3->rrs->rr($_)->type == LDNS_RR_TYPE_RRSIG }
(0 .. $z3->rrs->rr_count - 1);
is($sigc, 10, 'Signed zone has 10 signatures');
my $nsecc = grep { $z3->rrs->rr($_)->type == LDNS_RR_TYPE_NSEC }
(0 .. $z3->rrs->rr_count - 1);
is($nsecc, 4, 'Signed zone has 3 nsec recs');
my $z4 = $z2->sign_nsec3($klist, 1, 0, 2, 'ABC');
my $sigc3 = grep { $z4->rrs->rr($_)->type == LDNS_RR_TYPE_RRSIG }
(0 .. $z4->rrs->rr_count - 1);
is($sigc3, 12, 'NSEC3-signed zone has 12 signatures');
my $nsecc3 = grep { $z4->rrs->rr($_)->type == LDNS_RR_TYPE_NSEC3 }
(0 .. $z4->rrs->rr_count - 1);
is($nsecc3, 5, 'NSEC3-signed zone has 5 nsec recs');

View File

@@ -0,0 +1,71 @@
TYPEMAP
DNS__LDNS__Zone LDNS_GENERIC_STRUCT
DNS__LDNS__RRList LDNS_GENERIC_STRUCT
DNS__LDNS__RR LDNS_GENERIC_STRUCT
DNS__LDNS__RData LDNS_GENERIC_STRUCT
DNS__LDNS__DNSSecZone LDNS_GENERIC_STRUCT
DNS__LDNS__DNSSecRRSets LDNS_GENERIC_STRUCT
DNS__LDNS__DNSSecRRs LDNS_GENERIC_STRUCT
DNS__LDNS__DNSSecName LDNS_GENERIC_STRUCT
DNS__LDNS__RBTree LDNS_GENERIC_STRUCT
DNS__LDNS__RBNode LDNS_GENERIC_STRUCT
DNS__LDNS__Resolver LDNS_GENERIC_STRUCT
DNS__LDNS__Packet LDNS_GENERIC_STRUCT
DNS__LDNS__Key LDNS_GENERIC_STRUCT
DNS__LDNS__KeyList LDNS_GENERIC_STRUCT
DNS__LDNS__DNSSecDataChain LDNS_GENERIC_STRUCT
DNS__LDNS__DNSSecTrustTree LDNS_GENERIC_STRUCT
Mortal_PV Mortal_PV
DNS__LDNS__RR__Opt LDNS_GENERIC_STRUCT_OPT
DNS__LDNS__RData__Opt LDNS_GENERIC_STRUCT_OPT
LDNS_Pkt_Opcode T_ENUM
LDNS_Pkt_Rcode T_ENUM
LDNS_Pkt_Section T_ENUM
LDNS_Pkt_Type T_ENUM
LDNS_RR_Type T_ENUM
LDNS_RR_Class T_ENUM
LDNS_RDF_Type T_ENUM
LDNS_Hash T_ENUM
LDNS_Status T_ENUM
LDNS_Signing_Algorithm T_ENUM
uint32_t T_UV
uint16_t T_UV
uint8_t T_UV
signed char T_UV
INPUT
LDNS_GENERIC_STRUCT_OPT
if (!SvOK($arg)) {
$var = NULL;
}
else if (sv_derived_from($arg, \"${(my $ntt=$ntype)=~s/__/::/g;$ntt=~s/::Opt$//;\$ntt}\")){
IV tmp = SvIV((SV*)SvRV($arg));
$var = INT2PTR($type, tmp);
}
else
croak(\"$var is not of type ${(my $ntt=$ntype)=~s/__/::/g;$ntt=~s/::Opt$//;\$ntt}\")
INPUT
LDNS_GENERIC_STRUCT
if (sv_derived_from($arg, \"${(my $ntt=$ntype)=~s/__/::/g;\$ntt}\")){
IV tmp = SvIV((SV*)SvRV($arg));
$var = INT2PTR($type, tmp);
}
else
croak(\"$var is not of type ${(my $ntt=$ntype)=~s/__/::/g;\$ntt}\")
OUTPUT
LDNS_GENERIC_STRUCT
sv_setref_pv($arg, \"${(my $ntt=$ntype)=~s/__/::/g;\$ntt}\", (void*)$var);
OUTPUT
LDNS_GENERIC_STRUCT_OPT
sv_setref_pv($arg, \"${(my $ntt=$ntype)=~s/__/::/g;$ntt=~s/::Opt$//;\$ntt}\", (void*)$var);
OUTPUT
Mortal_PV
sv_setsv($arg, sv_2mortal(newSVpv($var, 0)));
free((void *)$var);

View File

@@ -0,0 +1,10 @@
NETLDNS is a functionality port of NLnet Labs' LDNS to the .NET
2.0 framework, contributed by Alex Nicoll of the Carnegie Mellon
University Software Engineering Institute. NETLDNS is released
under the BSD license. NETLDNS uses Mihnea Radulescu's BigInteger
Library (http://www.codeproject.com/KB/cs/BigInteger_Library.aspx)
from CodeProject to help with key manipulation. Please contact Alex at
anicoll@cert.org with inquiries or requests for newer versions.
This project is not supported by NLnet Labs.

Binary file not shown.

View File

@@ -0,0 +1,50 @@
#!/bin/ksh
#
# $Id$
PREFIX=/opt/ldns
OPENSSL=/usr/sfw
SUDO=sudo
MAKE_PROGRAM=gmake
MAKE_ARGS="-j 4"
OBJ32=obj32
OBJ64=obj64
SRCDIR=`pwd`
test -d $OBJ32 && $SUDO rm -fr $OBJ32
mkdir $OBJ32
export CFLAGS=""
export LDFLAGS="-L${OPENSSL}/lib -R${OPENSSL}/lib"
(cd $OBJ32; \
${SRCDIR}/configure --with-ssl=${OPENSSL} --prefix=${PREFIX} --libdir=${PREFIX}/lib; \
$MAKE_PROGRAM $MAKE_ARGS)
if [ `isainfo -k` = amd64 ]; then
test -d $OBJ64 && $SUDO rm -fr $OBJ64
mkdir $OBJ64
export CFLAGS="-m64"
export LDFLAGS="-L${OPENSSL}/lib/amd64 -R${OPENSSL}/lib/amd64"
(cd $OBJ64; \
${SRCDIR}/configure --with-ssl=${OPENSSL} --prefix=${PREFIX} --libdir=${PREFIX}/lib/amd64; \
$MAKE_PROGRAM $MAKE_ARGS)
fi
# optionally install
#
if [ x$1 = xinstall ]; then
(cd $OBJ32; $SUDO $MAKE_PROGRAM install-h)
(cd $OBJ32; $SUDO $MAKE_PROGRAM install-doc)
(cd $OBJ32; $SUDO $MAKE_PROGRAM install-lib)
if [ `isainfo -k` = amd64 ]; then
(cd $OBJ64; $SUDO $MAKE_PROGRAM install-lib)
fi
fi

View File

@@ -0,0 +1,28 @@
Copyright (c) 2011, Xelerance
Author: Christopher Olah <chris@xelerance.com>
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 Xelerance 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,89 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = build
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
-rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/ldnsx.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/ldnsx.qhc"
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
"run these through (pdf)latex."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."

View File

@@ -0,0 +1,36 @@
LDNSX: Easy DNS (including DNSSEC) via ldns.
ldns is a great library. It is a powerful tool for
working with DNS. python-ldns it is a straight up clone of the C
interface, however that is not a very good interface for python. Its
documentation is incomplete and some functions don't work as
described. And some objects don't have a full python API.
ldnsx aims to fix this. It wraps around the ldns python bindings,
working around its limitations and providing a well-documented, more
pythonistic interface.
Written by Christopher Olah <chris@xelerance.com>
Examples
========
Query the default resolver for google.com's A records. Print the response
packet.
>>> import ldnsx
>>> resolver = ldnsx.resolver()
>>> print resolver.query("google.com","A")
Print the NS records for com. from f.root-servers.net if we get a
response, else an error message.
>>> import ldnsx
>>> pkt = ldnsx.resolver("f.root-servers.net").query("com.","NS")
>>> if pkt:
>>> for rr in pkt.answer():
>>> print rr
>>> else:
>>> print "response not received"

View File

@@ -0,0 +1,30 @@
#!/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 = ldnsx.resolver("zone.nic.cz")
#Print results
for rr in resolver.AXFR(utf2name(u"háčkyčárky.cz")):
# rdf = rr.owner()
# if (rdf.get_type() == ldns.LDNS_RDF_TYPE_DNAME):
# print "RDF owner: type=",rr.type(),"data=",name2utf(rr.owner())
# 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)

View File

@@ -0,0 +1,39 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import ldnsx
import sys
debug = True
if len(sys.argv) < 2:
print "Usage:", sys.argv[0], "domain [resolver_addr]"
sys.exit(1)
name = sys.argv[1]
# Create resolver
resolver = ldnsx.resolver(dnssec=True)
# Custom resolver
if len(sys.argv) > 2:
# Clear previous nameservers
resolver.set_nameservers(sys.argv[2:])
# Resolve DNS name
pkt = resolver.query(name, "A")
if pkt and pkt.answer():
# Debug
if debug:
print "NS returned:", pkt.rcode(), "(AA: %d AD: %d)" % ( "AA" in pkt.flags(), "AD" in pkt.flags() )
# SERVFAIL indicated bogus name
if pkt.rcode() == "SERVFAIL":
print name, "failed to resolve"
# Check AD (Authenticated) bit
if pkt.rcode() == "NOERROR":
if "AD" in pkt.flags(): print name, "is secure"
else: print name, "is insecure"

View File

@@ -0,0 +1,11 @@
import ldnsx
resolver = ldnsx.resolver()
pkt = resolver.query("nic.cz", "MX")
if (pkt):
mx = pkt.answer()
if (mx):
mx.sort()
print mx

View File

@@ -0,0 +1,17 @@
#!/usr/bin/python
#
# MX is a small program that prints out the mx records for a particular domain
#
import ldnsx
resolver = ldnsx.resolver()
pkt = resolver.query("nic.cz", "MX")
if pkt:
for rr in pkt.answer(rr_type = "MX"):
rdf = rr.owner()
print rr
#Could also do:
#print rr[0], rr[1], rr[2], rr[3], " ".join(rr[4:])
#print rr.owner(), rr.ttl(), rr.rr_clas(), rr.rr_type(), " ".join(rr[4:])

View File

@@ -0,0 +1,25 @@
#!/usr/bin/python
# vim:fileencoding=utf-8
#
# Walk a domain that's using NSEC and print in zonefile format.
import sys
import ldnsx
def walk(domain):
res = ldnsx.resolver("193.110.157.136", dnssec=True)
pkt = res.query(domain, 666)
try:
nsec_rr = pkt.authority(rr_type="NSEC")[0]
except:
print "no NSEC found, domain is not signed or using NSEC3"
sys.exit()
for rr_type in nsec_rr[5].split(' ')[:-1]:
for rr in ldnsx.get_rrs(domain, rr_type):
print str(rr)[:-1]
next_rec = nsec_rr[4]
if (next_rec != domain) and (next_rec[-len(domain):] == domain):
walk(next_rec)
walk("xelerance.com")

View File

@@ -0,0 +1,921 @@
# Copyright (C) Xelerance Corp. <http://www.xelerance.com/>.
# Author: Christopher Olah <colah@xelerance.com>
# License: BSD
""" Easy DNS (including DNSSEC) via ldns.
ldns is a great library. It is a powerful tool for
working with DNS. python-ldns it is a straight up clone of the C
interface, however that is not a very good interface for python. Its
documentation is incomplete and some functions don't work as
described. And some objects don't have a full python API.
ldnsx aims to fix this. It wraps around the ldns python bindings,
working around its limitations and providing a well-documented, more
pythonistic interface.
**WARNING:**
**API subject to change.** No backwards compatibility guarantee. Write software using this version at your own risk!
Examples
--------
Query the default resolver for google.com's A records. Print the response
packet.
>>> import ldnsx
>>> resolver = ldnsx.resolver()
>>> print resolver.query("google.com","A")
Print the root NS records from f.root-servers.net; if we get a
response, else an error message.
>>> import ldnsx
>>> pkt = ldnsx.resolver("f.root-servers.net").query(".", "NS")
>>> if pkt:
>>> for rr in pkt.answer():
>>> print rr
>>> else:
>>> print "response not received"
"""
import time, sys, calendar, warnings, socket
try:
import ldns
except ImportError:
print >> sys.stderr, "ldnsx requires the ldns-python sub-package from http://www.nlnetlabs.nl/projects/ldns/"
print >> sys.stderr, "Fedora/CentOS: yum install ldns-python"
print >> sys.stderr, "Debian/Ubuntu: apt-get install python-ldns"
print >> sys.stderr, "openSUSE: zypper in python-ldns"
sys.exit(1)
__version__ = "0.1"
def isValidIP(ipaddr):
try:
v4 = socket.inet_pton(socket.AF_INET,ipaddr)
return 4
except:
try:
v6 = socket.inet_pton(socket.AF_INET6,ipaddr)
return 6
except:
return 0
def query(name, rr_type, rr_class="IN", flags=["RD"], tries = 3, res=None):
"""Convenience function. Creates a resolver and then queries it. Refer to resolver.query()
* name -- domain to query for
* rr_type -- rr_type to query for
* flags -- flags for query (list of strings)
* tries -- number of times to retry the query on failure
* res -- configurations for the resolver as a dict -- see resolver()
"""
if isinstance(res, list) or isinstance(res, tuple):
res = resolver(*res)
elif isinstance(res, dict):
res = resolver(**res)
else:
res = resolver(res)
return res.query(name, rr_type, rr_class, flags, tries)
def get_rrs(name, rr_type, rr_class="IN", tries = 3, strict = False, res=None, **kwds):
"""Convenience function. Gets RRs for name of type rr_type trying tries times.
If strict, it raises and exception on failure, otherwise it returns [].
* name -- domain to query for
* rr_type -- rr_type to query for
* flags -- flags for query (list of strings)
* tries -- number of times to retry the query on failure
* strict -- if the query fails, do we return [] or raise an exception?
* res -- configurations for the resolver as a dict -- see resolver()
* kwds -- query filters, refer to packet.answer()
"""
if isinstance(res, list) or isinstance(res, tuple):
res = resolver(*res)
elif isinstance(res, dict):
res = resolver(**res)
else:
res = resolver(res)
if "|" in rr_type:
pkt = res.query(name, "ANY", rr_class=rr_class, tries=tries)
else:
pkt = res.query(name, rr_type, rr_class=rr_class, tries=tries)
if pkt:
if rr_type in ["", "ANY", "*"]:
return pkt.answer( **kwds)
else:
return pkt.answer(rr_type=rr_type, **kwds)
else:
if strict:
raise Exception("LDNS couldn't complete query")
else:
return []
def secure_query(name, rr_type, rr_class="IN", flags=["RD"], tries = 1, flex=False, res=None):
"""Convenience function. Creates a resolver and then does a DNSSEC query. Refer to resolver.query()
* name -- domain to query for
* rr_type -- rr_type to query for
* flags -- flags for query (list of strings)
* tries -- number of times to retry the query on failure
* flex -- if we can't verify data, exception or warning?
* res -- configurations for the resolver as a dict -- see resolver()"""
if isinstance(res, list) or isinstance(res, tuple):
res = resolver(*res)
elif isinstance(res, dict):
res = resolver(**res)
else:
res = resolver(res)
pkt = res.query(name, rr_type, rr_class, flags, tries)
if pkt.rcode() == "SERVFAIL":
raise Exception("%s lookup failed (server error or dnssec validation failed)" % name)
if pkt.rcode() == "NXDOMAIN":
if "AD" in pkt.flags():
raise Exception("%s lookup failed (non-existence proven by DNSSEC)" % name )
else:
raise Exception("%s lookup failed" % name )
if pkt.rcode() == "NOERROR":
if "AD" not in pkt.flags():
if not flex:
raise Exception("DNS lookup was insecure")
else:
warnings.warn("DNS lookup was insecure")
return pkt
else:
raise Exception("unknown ldns error, %s" % pkt.rcode())
class resolver:
""" A wrapper around ldns.ldns_resolver.
**Examples**
Making resolvers is easy!
>>> from ldnsx import resolver
>>> resolver() # from /etc/resolv.conf
<resolver: 192.168.111.9>
>>> resolver("") # resolver with no nameservers
<resolver: >
>>> resolver("193.110.157.135") #resolver pointing to ip addr
<resolver: 193.110.157.135>
>>> resolver("f.root-servers.net") # resolver pointing ip address(es) resolved from name
<resolver: 2001:500:2f::f, 192.5.5.241>
>>> resolver("193.110.157.135, 193.110.157.136")
>>> # resolver pointing to multiple ip addr, first takes precedence.
<resolver: 193.110.157.136, 193.110.157.135>
So is playing around with their nameservers!
>>> import ldnsx
>>> res = ldnsx.resolver("192.168.1.1")
>>> res.add_nameserver("192.168.1.2")
>>> res.add_nameserver("192.168.1.3")
>>> res.nameservers_ip()
["192.168.1.1","192.168.1.2","192.168.1.3"]
And querying!
>>> from ldnsx import resolver
>>> res= resolver()
>>> res.query("cow.com","A")
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 7663
;; flags: qr rd ra ; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;; cow.com. IN A
;; ANSWER SECTION:
cow.com. 300 IN A 208.87.34.18
;; AUTHORITY SECTION:
;; ADDITIONAL SECTION:
;; Query time: 313 msec
;; SERVER: 192.168.111.9
;; WHEN: Fri Jun 3 11:01:02 2011
;; MSG SIZE rcvd: 41
"""
def __init__(self, ns = None, dnssec = False, tcp = False, port = 53):
"""resolver constructor
* ns -- the nameserver/comma delimited nameserver list
defaults to settings from /etc/resolv.conf
* dnssec -- should the resolver try and use dnssec or not?
* tcp -- should the resolver use TCP
'auto' is a deprecated work around for old ldns problems
* port -- the port to use, must be the same for all nameservers
"""
# We construct based on a file and dump the nameservers rather than using
# ldns_resolver_new() to avoid environment/configuration/magic specific
# bugs.
self._ldns_resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf")
if ns != None:
self.drop_nameservers()
nm_list = ns.split(',')
nm_list = map(lambda s: s.strip(), nm_list)
nm_list = list(filter(lambda s: s != "", nm_list))
nm_list.reverse()
for nm in nm_list:
self.add_nameserver(nm)
# Configure DNSSEC, tcp and port
self.set_dnssec(dnssec)
if tcp == 'auto':
self.autotcp = True
self._ldns_resolver.set_usevc(False)
else:
self.autotcp = False
self._ldns_resolver.set_usevc(tcp)
self._ldns_resolver.set_port(port)
def query(self, name, rr_type, rr_class="IN", flags=["RD"], tries = 3):
"""Run a query on the resolver.
* name -- name to query for
* rr_type -- the record type to query for
* rr_class -- the class to query for, defaults to IN (Internet)
* flags -- the flags to send the query with
* tries -- the number of times to attempt to achieve query in case of packet loss, etc
**Examples**
Let's get some A records!
>>> google_a_records = resolver.query("google.com","A").answer()
Using DNSSEC is easy :)
>>> dnssec_pkt = ldnsx.resolver(dnssec=True).query("xelerance.com")
We let you use strings to make things easy, but if you prefer stay close to DNS...
>>> AAAA = 28
>>> resolver.query("ipv6.google.com", AAAA)
**More about rr_type**
rr_type must be a supported resource record type. There are a large number of RR types:
=========== =================================== ==================
TYPE Value and meaning Reference
=========== =================================== ==================
A 1 a host address [RFC1035]
NS 2 an authoritative name server [RFC1035]
...
AAAA 28 IP6 Address [RFC3596]
...
DS 43 Delegation Signer [RFC4034][RFC3658]
...
DNSKEY 48 DNSKEY [RFC4034][RFC3755]
...
Unassigned 32770-65279
Private use 65280-65534
Reserved 65535
=========== =================================== ==================
(From http://www.iana.org/assignments/dns-parameters)
RR types are given as a string (eg. "A"). In the case of Unassigned/Private use/Reserved ones,
they are given as "TYPEXXXXX" where XXXXX is the number. ie. RR type 65280 is "TYPE65280". You
may also pass the integer, but you always be given the string.
If the version of ldnsx you are using is old, it is possible that there could be new rr_types that
we don't recognise mnemonic for. You can still use the number XXX or the string "TYPEXXX". To
determine what rr_type mnemonics we support, please refer to resolver.supported_rr_types()
"""
# Determine rr_type int
if rr_type in _rr_types.keys():
_rr_type = _rr_types[rr_type]
elif isinstance(rr_type,int):
_rr_type = rr_type
elif isinstance(rr_type,str) and rr_type[0:4] == "TYPE":
try:
_rr_type = int(rr_type[4:])
except:
raise Exception("%s is a bad RR type. TYPEXXXX: XXXX must be a number")
else:
raise Exception("ldnsx (version %s) does not support the RR type %s." % (__version__, str(rr_type)) )
# Determine rr_class int
if rr_class == "IN": _rr_class = ldns.LDNS_RR_CLASS_IN
elif rr_class == "CH": _rr_class = ldns.LDNS_RR_CLASS_CH
elif rr_class == "HS": _rr_class = ldns.LDNS_RR_CLASS_HS
else:
raise Exception("ldnsx (version %s) does not support the RR class %s." % (__version__, str(rr_class)) )
# Determine flags int
_flags = 0
if "QR" in flags: _flags |= ldns.LDNS_QR
if "AA" in flags: _flags |= ldns.LDNS_AA
if "TC" in flags: _flags |= ldns.LDNS_TC
if "RD" in flags: _flags |= ldns.LDNS_RD
if "CD" in flags: _flags |= ldns.LDNS_CD
if "RA" in flags: _flags |= ldns.LDNS_RA
if "AD" in flags: _flags |= ldns.LDNS_AD
# Query
if tries == 0: return None
try:
pkt = self._ldns_resolver.query(name, _rr_type, _rr_class, _flags)
except KeyboardInterrupt: #Since so much time is spent waiting on ldns, this is very common place for Ctr-C to fall
raise
except: #Since the ldns exception is not very descriptive...
raise Exception("ldns backend ran into problems. Likely, the name you were querying for, %s, was invalid." % name)
#Deal with failed queries
if not pkt:
if tries <= 1:
return None
else:
# One of the major causes of none-packets is truncation of packets
# When autotcp is set, we are in a flexible enough position to try and use tcp
# to get around this.
# Either way, we want to replace the resolver, since resolvers will sometimes
# just freeze up.
if self.autotcp:
self = resolver( ",".join(self.nameservers_ip()),tcp=True, dnssec = self._ldns_resolver.dnssec())
self.autotcp = True
pkt = self.query(name, rr_type, rr_class=rr_class, flags=flags, tries = tries-1)
self._ldns_resolver.set_usevc(False)
return pkt
else:
self = resolver( ",".join(self.nameservers_ip()), tcp = self._ldns_resolver.usevc(), dnssec = self._ldns_resolver.dnssec() )
time.sleep(1) # It could be that things are failing because of a brief outage
return self.query(name, rr_type, rr_class=rr_class, flags=flags, tries = tries-1)
elif self.autotcp:
pkt = packet(pkt)
if "TC" in pkt.flags():
self._ldns_resolver.set_usevc(True)
pkt2 = self.query(name, rr_type, rr_class=rr_class, flags=flags, tries = tries-1)
self._ldns_resolver.set_usevc(False)
if pkt2: return packet(pkt2)
return pkt
return packet(pkt)
#ret = []
#for rr in pkt.answer().rrs():
# ret.append([str(rr.owner()),rr.ttl(),rr.get_class_str(),rr.get_type_str()]+[str(rdf) for rdf in rr.rdfs()])
#return ret
def suported_rr_types(self):
""" Returns the supported DNS resource record types.
Refer to resolver.query() for thorough documentation of resource
record types or refer to:
http://www.iana.org/assignments/dns-parameters
"""
return _rr_types.keys()
def AXFR(self,name):
"""AXFR for name
* name -- name to AXFR for
This function is a generator. As it AXFRs it will yield you the records.
**Example**
Let's get a list of the tlds (gotta catch em all!):
>>> tlds = []
>>> for rr in resolver("f.root-servers.net").AXFR("."):
>>> if rr.rr_type() == "NS":
>>> tlds.append(rr.owner())
"""
#Dname seems to be unnecessary on some computers, but it is on others. Avoid bugs.
if self._ldns_resolver.axfr_start(ldns.ldns_dname(name), ldns.LDNS_RR_CLASS_IN) != ldns.LDNS_STATUS_OK:
raise Exception("Starting AXFR failed. Error: %s" % ldns.ldns_get_errorstr_by_id(status))
pres = self._ldns_resolver.axfr_next()
while pres:
yield resource_record(pres)
pres = self._ldns_resolver.axfr_next()
def nameservers_ip(self):
""" returns a list of the resolvers nameservers (as IP addr)
"""
nm_stack2 =[]
nm_str_stack2=[]
nm = self._ldns_resolver.pop_nameserver()
while nm:
nm_stack2.append(nm)
nm_str_stack2.append(str(nm))
nm = self._ldns_resolver.pop_nameserver()
for nm in nm_stack2:
self._ldns_resolver.push_nameserver(nm)
nm_str_stack2.reverse()
return nm_str_stack2
def add_nameserver(self,ns):
""" Add a nameserver, IPv4/IPv6/name.
"""
if isValidIP(ns) == 4:
address = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_A,ns)
self._ldns_resolver.push_nameserver(address)
elif isValidIP(ns) == 6:
address = ldns.ldns_rdf_new_frm_str(ldns.LDNS_RDF_TYPE_AAAA,ns)
self._ldns_resolver.push_nameserver(address)
else:
resolver = ldns.ldns_resolver.new_frm_file("/etc/resolv.conf")
#address = resolver.get_addr_by_name(ns)
address = resolver.get_addr_by_name(ldns.ldns_dname(ns))
if not address:
address = resolver.get_addr_by_name(ldns.ldns_dname(ns))
if not address:
raise Exception("Failed to resolve address for %s" % ns)
for rr in address.rrs():
self._ldns_resolver.push_nameserver_rr(rr)
def drop_nameservers(self):
"""Drops all nameservers.
This function causes the resolver to forget all nameservers.
"""
while self._ldns_resolver.pop_nameserver():
pass
def set_nameservers(self, nm_list):
"""Takes a list of nameservers and sets the resolver to use them
"""
self.drop_nameservers()
for nm in nm_list:
self.add_nameserver(nm)
def __repr__(self):
return "<resolver: %s>" % ", ".join(self.nameservers_ip())
__str__ = __repr__
def set_dnssec(self,new_dnssec_status):
"""Set whether the resolver uses DNSSEC.
"""
self._ldns_resolver.set_dnssec(new_dnssec_status)
class packet:
def _construct_rr_filter(self, **kwds):
def match(pattern, target):
if pattern[0] in ["<",">","!"]:
rel = pattern[0]
pattern=pattern[1:]
elif pattern[0:2] in ["<=","=>"]:
rel = pattern[0:2]
pattern=pattern[2:]
else:
rel = "="
for val in pattern.split("|"):
if {"<" : target < val,
">" : target > val,
"!" : target != val,
"=" : target == val,
">=": target >= val,
"<=": target <= val}[rel]:
return True
return False
def f(rr):
for key in kwds.keys():
if ( ( isinstance(kwds[key], list) and str(rr[key]) not in map(str,kwds[key]) )
or ( not isinstance(kwds[key], list) and not match(str(kwds[key]), str(rr[key])))):
return False
return True
return f
def __init__(self, pkt):
self._ldns_pkt = pkt
def __repr__(self):
return str(self._ldns_pkt)
__str__ = __repr__
def rcode(self):
"""Returns the rcode.
Example returned value: "NOERROR"
possible rcodes (via ldns): "FORMERR", "MASK", "NOERROR",
"NOTAUTH", "NOTIMPL", "NOTZONE", "NXDOMAIN",
"NXRSET", "REFUSED", "SERVFAIL", "SHIFT",
"YXDOMAIN", "YXRRSET"
Refer to http://www.iana.org/assignments/dns-parameters
section: DNS RCODEs
"""
return self._ldns_pkt.rcode2str()
def opcode(self):
"""Returns the rcode.
Example returned value: "QUERY"
"""
return self._ldns_pkt.opcode2str()
def flags(self):
"""Return packet flags (as list of strings).
Example returned value: ['QR', 'RA', 'RD']
**What are the flags?**
======== ==== ===================== =========
Bit Flag Description Reference
======== ==== ===================== =========
bit 5 AA Authoritative Answer [RFC1035]
bit 6 TC Truncated Response [RFC1035]
bit 7 RD Recursion Desired [RFC1035]
bit 8 RA Recursion Allowed [RFC1035]
bit 9 Reserved
bit 10 AD Authentic Data [RFC4035]
bit 11 CD Checking Disabled [RFC4035]
======== ==== ===================== =========
(from http://www.iana.org/assignments/dns-parameters)
There is also QR. It is mentioned in other sources,
though not the above page. It being false means that
the packet is a query, it being true means that it is
a response.
"""
ret = []
if self._ldns_pkt.aa(): ret += ["AA"]
if self._ldns_pkt.ad(): ret += ["AD"]
if self._ldns_pkt.cd(): ret += ["CD"]
if self._ldns_pkt.qr(): ret += ["QR"]
if self._ldns_pkt.ra(): ret += ["RA"]
if self._ldns_pkt.rd(): ret += ["RD"]
if self._ldns_pkt.tc(): ret += ["TC"]
return ret
def answer(self, **filters):
"""Returns the answer section.
* filters -- a filtering mechanism
Since a very common desire is to filter the resource records in a packet
section, we provide a special tool for doing this: filters. They are a
lot like regular python filters, but more convenient. If you set a
field equal to some value, you will only receive resource records for which
it holds true.
**Examples**
>>> res = ldnsx.resolver()
>>> pkt = res.query("google.ca","A")
>>> pkt.answer()
[google.ca. 28 IN A 74.125.91.99
, google.ca. 28 IN A 74.125.91.105
, google.ca. 28 IN A 74.125.91.147
, google.ca. 28 IN A 74.125.91.103
, google.ca. 28 IN A 74.125.91.104
, google.ca. 28 IN A 74.125.91.106
]
To understand filters, consider the following:
>>> pkt = ldnsx.query("cow.com","ANY")
>>> pkt.answer()
[cow.com. 276 IN A 208.87.32.75
, cow.com. 3576 IN NS sell.internettraffic.com.
, cow.com. 3576 IN NS buy.internettraffic.com.
, cow.com. 3576 IN SOA buy.internettraffic.com. hostmaster.hostingnet.com. 1308785320 10800 3600 604800 3600
]
>>> pkt.answer(rr_type="A")
[cow.com. 276 IN A 208.87.32.75
]
>>> pkt.answer(rr_type="A|NS")
[cow.com. 276 IN A 208.87.32.75
, cow.com. 3576 IN NS sell.internettraffic.com.
, cow.com. 3576 IN NS buy.internettraffic.com.
]
>>> pkt.answer(rr_type="!NS")
[cow.com. 276 IN A 208.87.32.75
, cow.com. 3576 IN SOA buy.internettraffic.com. hostmaster.hostingnet.com. 1308785320 10800 3600 604800 3600
]
fields are the same as when indexing a resource record.
note: ordering is alphabetical.
"""
ret = [resource_record(rr) for rr in self._ldns_pkt.answer().rrs()]
return filter(self._construct_rr_filter(**filters), ret)
def authority(self, **filters):
"""Returns the authority section.
* filters -- a filtering mechanism
Since a very common desire is to filter the resource records in a packet
section, we provide a special tool for doing this: filters. They are a
lot like regular python filters, but more convenient. If you set a
field equal to some value, you will only receive resource records for which
it holds true. See answer() for details.
**Examples**
>>> res = ldnsx.resolver()
>>> pkt = res.query("google.ca","A")
>>> pkt.authority()
[google.ca. 251090 IN NS ns3.google.com.
, google.ca. 251090 IN NS ns1.google.com.
, google.ca. 251090 IN NS ns2.google.com.
, google.ca. 251090 IN NS ns4.google.com.
]
"""
ret = [resource_record(rr) for rr in self._ldns_pkt.authority().rrs()]
return filter(self._construct_rr_filter(**filters), ret)
def additional(self, **filters):
"""Returns the additional section.
* filters -- a filtering mechanism
Since a very common desire is to filter the resource records in a packet
section, we provide a special tool for doing this: filters. They are a
lot like regular python filters, but more convenient. If you set a
field equal to some value, you will only receive resource records for which
it holds true. See answer() for details.
**Examples**
>>> res = ldnsx.resolver()
>>> pkt = res.query("google.ca","A")
>>> pkt.additional()
[ns3.google.com. 268778 IN A 216.239.36.10
, ns1.google.com. 262925 IN A 216.239.32.10
, ns2.google.com. 255659 IN A 216.239.34.10
, ns4.google.com. 264489 IN A 216.239.38.10
]
"""
ret = [resource_record(rr) for rr in self._ldns_pkt.additional().rrs()]
return filter(self._construct_rr_filter(**filters), ret)
def question(self, **filters):
"""Returns the question section.
* filters -- a filtering mechanism
Since a very common desire is to filter the resource records in a packet
section, we provide a special tool for doing this: filters. They are a
lot like regular python filters, but more convenient. If you set a
field equal to some value, you will only receive resource records for which
it holds true. See answer() for details.
"""
ret = [resource_record(rr) for rr in self._ldns_pkt.question().rrs()]
return filter(self._construct_rr_filter(**filters), ret)
class resource_record:
_rdfs = None
_iter_pos = None
def __init__(self, rr):
self._ldns_rr = rr
self._rdfs = [str(rr.owner()),rr.ttl(),rr.get_class_str(),rr.get_type_str()]+[str(rdf) for rdf in rr.rdfs()]
def __repr__(self):
return str(self._ldns_rr)
__str__ = __repr__
def __iter__(self):
self._iter_pos = 0
return self
def next(self):
if self._iter_pos < len(self._rdfs):
self._iter_pos += 1
return self._rdfs[self._iter_pos-1]
else:
raise StopIteration
def __len__(self):
try:
return len(self._rdfs)
except:
return 0
def __getitem__(self, n):
if isinstance(n, int):
return self._rdfs[n]
elif isinstance(n, str):
n = n.lower()
if n in ["owner"]:
return self.owner()
elif n in ["rr_type", "rr type", "type"]:
return self.rr_type()
elif n in ["rr_class", "rr class", "class"]:
return self.rr_class()
elif n in ["covered_type", "covered type", "type2"]:
return self.covered_type()
elif n in ["ttl"]:
return self.ttl()
elif n in ["ip"]:
return self.ip()
elif n in ["alg", "algorithm"]:
return self.alg()
elif n in ["protocol"]:
return self.protocol()
elif n in ["flags"]:
return self.flags()
else:
raise Exception("ldnsx (version %s) does not recognize the rr field %s" % (__version__,n) )
else:
raise TypeError("bad type %s for index resource record" % type(n) )
#def rdfs(self):
# return self._rdfs.clone()
def owner(self):
"""Get the RR's owner"""
return str(self._ldns_rr.owner())
def rr_type(self):
"""Get a RR's type """
return self._ldns_rr.get_type_str()
def covered_type(self):
"""Get an RRSIG RR's covered type"""
if self.rr_type() == "RRSIG":
return self[4]
else:
return ""
def rr_class(self):
"""Get the RR's collapse"""
return self._ldns_rr.get_class_str()
def ttl(self):
"""Get the RR's TTL"""
return self._ldns_rr.ttl()
def inception(self, out_format="UTC"):
"""returns the inception time in format out_format, defaulting to a UTC string.
options for out_format are:
UTC -- a UTC string eg. 20110712192610 (2011/07/12 19:26:10)
unix -- number of seconds since the epoch, Jan 1, 1970
struct_time -- the format used by python's time library
"""
# Something very strange is going on with inception/expiration dates in DNS.
# According to RFC 4034 section 3.1.5 (http://tools.ietf.org/html/rfc4034#page-9)
# the inception/expiration fields should be in seconds since Jan 1, 1970, the Unix
# epoch (as is standard in unix). Yet all the packets I've seen provide UTC encoded
# as a string instead, eg. "20110712192610" which is 2011/07/12 19:26:10.
#
# It turns out that this is a standard thing that ldns is doing before the data gets
# to us.
if self.rr_type() == "RRSIG":
if out_format.lower() in ["utc", "utc str", "utc_str"]:
return self[9]
elif out_format.lower() in ["unix", "posix", "ctime"]:
return calendar.timegm(time.strptime(self[9], "%Y%m%d%H%M%S"))
elif out_format.lower() in ["relative"]:
return calendar.timegm(time.strptime(self[9], "%Y%m%d%H%M%S")) - time.time()
elif out_format.lower() in ["struct_time", "time.struct_time"]:
return time.strptime(self[9], "%Y%m%d%H%M%S")
else:
raise Exception("unrecognized time format")
else:
return ""
def expiration(self, out_format="UTC"):
"""get expiration time. see inception() for more information"""
if self.rr_type() == "RRSIG":
if out_format.lower() in ["utc", "utc str", "utc_str"]:
return self[8]
elif out_format.lower() in ["unix", "posix", "ctime"]:
return calendar.timegm(time.strptime(self[8], "%Y%m%d%H%M%S"))
elif out_format.lower() in ["relative"]:
return calendar.timegm(time.strptime(self[8], "%Y%m%d%H%M%S")) - time.time()
elif out_format.lower() in ["struct_time", "time.struct_time"]:
return time.strptime(self[8], "%Y%m%d%H%M%S")
else:
raise Exception("unrecognized time format")
else:
return ""
def ip(self):
""" IP address form A/AAAA record"""
if self.rr_type() in ["A", "AAAA"]:
return self[4]
else:
raise Exception("ldnsx does not support ip for records other than A/AAAA")
def alg(self):
"""Returns algorithm of RRSIG/DNSKEY/DS"""
t = self.rr_type()
if t == "RRSIG":
return int(self[5])
elif t == "DNSKEY":
return int(self[6])
elif t == "DS":
return int(self[5])
else:
return -1
def protocol(self):
""" Returns protocol of the DNSKEY"""
t = self.rr_type()
if t == "DNSKEY":
return int(self[5])
else:
return -1
def flags(self):
"""Return RR flags for DNSKEY """
t = self.rr_type()
if t == "DNSKEY":
ret = []
n = int(self[4])
for m in range(1):
if 2**(15-m) & n:
if m == 7: ret.append("ZONE")
elif m == 8: ret.append("REVOKE")
elif m ==15: ret.append("SEP")
else: ret.append(m)
return ret
else:
return []
_rr_types={
"A" : ldns.LDNS_RR_TYPE_A,
"A6" : ldns.LDNS_RR_TYPE_A6,
"AAAA" : ldns.LDNS_RR_TYPE_AAAA,
"AFSDB": ldns.LDNS_RR_TYPE_AFSDB,
"ANY" : ldns.LDNS_RR_TYPE_ANY,
"APL" : ldns.LDNS_RR_TYPE_APL,
"ATMA" : ldns.LDNS_RR_TYPE_ATMA,
"AXFR" : ldns.LDNS_RR_TYPE_AXFR,
"CDNSKEY" : ldns.LDNS_RR_TYPE_CDNSKEY,
"CDS" : ldns.LDNS_RR_TYPE_CDS,
"CERT" : ldns.LDNS_RR_TYPE_CERT,
"CNAME": ldns.LDNS_RR_TYPE_CNAME,
"COUNT": ldns.LDNS_RR_TYPE_COUNT,
"DHCID": ldns.LDNS_RR_TYPE_DHCID,
"DLV" : ldns.LDNS_RR_TYPE_DLV,
"DNAME": ldns.LDNS_RR_TYPE_DNAME,
"DNSKEY": ldns.LDNS_RR_TYPE_DNSKEY,
"DS" : ldns.LDNS_RR_TYPE_DS,
"EID" : ldns.LDNS_RR_TYPE_EID,
"FIRST": ldns.LDNS_RR_TYPE_FIRST,
"GID" : ldns.LDNS_RR_TYPE_GID,
"GPOS" : ldns.LDNS_RR_TYPE_GPOS,
"HINFO": ldns.LDNS_RR_TYPE_HINFO,
"IPSECKEY": ldns.LDNS_RR_TYPE_IPSECKEY,
"ISDN" : ldns.LDNS_RR_TYPE_ISDN,
"IXFR" : ldns.LDNS_RR_TYPE_IXFR,
"KEY" : ldns.LDNS_RR_TYPE_KEY,
"KX" : ldns.LDNS_RR_TYPE_KX,
"LAST" : ldns.LDNS_RR_TYPE_LAST,
"LOC" : ldns.LDNS_RR_TYPE_LOC,
"MAILA": ldns.LDNS_RR_TYPE_MAILA,
"MAILB": ldns.LDNS_RR_TYPE_MAILB,
"MB" : ldns.LDNS_RR_TYPE_MB,
"MD" : ldns.LDNS_RR_TYPE_MD,
"MF" : ldns.LDNS_RR_TYPE_MF,
"MG" : ldns.LDNS_RR_TYPE_MG,
"MINFO": ldns.LDNS_RR_TYPE_MINFO,
"MR" : ldns.LDNS_RR_TYPE_MR,
"MX" : ldns.LDNS_RR_TYPE_MX,
"NAPTR": ldns.LDNS_RR_TYPE_NAPTR,
"NIMLOC": ldns.LDNS_RR_TYPE_NIMLOC,
"NS" : ldns.LDNS_RR_TYPE_NS,
"NSAP" : ldns.LDNS_RR_TYPE_NSAP,
"NSAP_PTR" : ldns.LDNS_RR_TYPE_NSAP_PTR,
"NSEC" : ldns.LDNS_RR_TYPE_NSEC,
"NSEC3": ldns.LDNS_RR_TYPE_NSEC3,
"NSEC3PARAM" : ldns.LDNS_RR_TYPE_NSEC3PARAM,
"NSEC3PARAMS" : ldns.LDNS_RR_TYPE_NSEC3PARAMS,
"NULL" : ldns.LDNS_RR_TYPE_NULL,
"NXT" : ldns.LDNS_RR_TYPE_NXT,
"OPENPGPKEY" : ldns.LDNS_RR_TYPE_OPENPGPKEY,
"OPT" : ldns.LDNS_RR_TYPE_OPT,
"PTR" : ldns.LDNS_RR_TYPE_PTR,
"PX" : ldns.LDNS_RR_TYPE_PX,
"RP" : ldns.LDNS_RR_TYPE_RP,
"RRSIG": ldns.LDNS_RR_TYPE_RRSIG,
"RT" : ldns.LDNS_RR_TYPE_RT,
"SIG" : ldns.LDNS_RR_TYPE_SIG,
"SINK" : ldns.LDNS_RR_TYPE_SINK,
"SOA" : ldns.LDNS_RR_TYPE_SOA,
"SRV" : ldns.LDNS_RR_TYPE_SRV,
"SSHFP": ldns.LDNS_RR_TYPE_SSHFP,
"TLSA" : ldns.LDNS_RR_TYPE_TLSA,
"TSIG" : ldns.LDNS_RR_TYPE_TSIG,
"TXT" : ldns.LDNS_RR_TYPE_TXT,
"UID" : ldns.LDNS_RR_TYPE_UID,
"UINFO": ldns.LDNS_RR_TYPE_UINFO,
"UNSPEC": ldns.LDNS_RR_TYPE_UNSPEC,
"WKS" : ldns.LDNS_RR_TYPE_WKS,
"X25" : ldns.LDNS_RR_TYPE_X25
}

View File

@@ -0,0 +1,15 @@
LDNSX API Reference
===================
.. automodule:: ldnsx
:members: query, get_rrs, secure_query
Classes
-------
.. toctree::
:maxdepth: 1
:glob:
resolver
packet
resource_record

View File

@@ -0,0 +1,6 @@
Class packet
==============
.. autoclass:: ldnsx.packet
:members:
:undoc-members:

View File

@@ -0,0 +1,6 @@
Class resolver
===============
.. autoclass:: ldnsx.resolver
:members:
:undoc-members:

View File

@@ -0,0 +1,6 @@
Class resource_record
=====================
.. autoclass:: ldnsx.resource_record
:members:
:undoc-members:

View File

@@ -0,0 +1,194 @@
# -*- coding: utf-8 -*-
#
# ldnsx documentation build configuration file, created by
# sphinx-quickstart on Mon May 30 16:56:19 2011.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path 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('..'))
# -- 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']#, 'sphinx.ext.jsmath']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'ldnsx'
copyright = u'2011, Christopher Olah'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '0.0'
# The full version, including alpha/beta/rc tags.
release = '-1'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# 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 directory, that shouldn't be searched
# for source files.
exclude_trees = []
# 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'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# -- Options for HTML output ---------------------------------------------------
# The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'.
html_theme = 'default'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# 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 (relative to this directory) 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 = True
# 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, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# 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 = 'ldnsxdoc'
# -- 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, documentclass [howto/manual]).
latex_documents = [
('index', 'ldnsx.tex', u'ldnsx Documentation',
u'Christopher Olah', '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,6 @@
AXFR Example
============
.. literalinclude:: ../../examples/ldnsx-axfr.py
:language: python
:linenos:

View File

@@ -0,0 +1,6 @@
DNSSEC Example
==============
.. literalinclude:: ../../examples/ldnsx-dnssec.py
:language: python
:linenos:

View File

@@ -0,0 +1,6 @@
MX1
===
.. literalinclude:: ../../examples/ldnsx-mx1.py
:language: python
:linenos:

View File

@@ -0,0 +1,6 @@
MX2
===
.. literalinclude:: ../../examples/ldnsx-mx2.py
:language: python
:linenos:

View File

@@ -0,0 +1,6 @@
NSEC Walker
===========
.. literalinclude:: ../../examples/ldnsx-walk.py
:language: python
:linenos:

View File

@@ -0,0 +1,57 @@
Welcome to ldnsx's documentation!
=================================
LDNSX: Easy DNS (including DNSSEC) via ldns.
ldns is a great library. It is a powerful tool for
working with DNS. python-ldns it is a straight up clone of the C
interface, however that is not a very good interface for python. Its
documentation is incomplete and some functions don't work as
described. And some objects don't have a full python API.
ldnsx aims to fix this. It wraps around the ldns python bindings,
working around its limitations and providing a well-documented, more
pythonistic interface.
Reference
=========
.. toctree::
:maxdepth: 1
api/ldnsx
.. toctree::
:maxdepth: 2
api/resolver
api/packet
api/resource_record
Examples
========
Examples translated from ldns examples:
.. toctree::
:maxdepth: 1
examples/ldnsx-axfr
examples/ldnsx-dnssec
examples/ldnsx-mx1
examples/ldnsx-mx2
Others:
.. toctree::
:maxdepth: 1
examples/ldnsx-walk
Indices and tables
==================
* :ref:`genindex`
* :ref:`search`

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

Some files were not shown because too many files have changed in this diff Show More