Import LDNS and build it as an internal library.

This commit is contained in:
Dag-Erling Smørgrav 2013-02-15 13:44:18 +00:00
commit 7b5038d71c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=246827
125 changed files with 99951 additions and 0 deletions

704
contrib/ldns/Changelog Normal file
View file

@ -0,0 +1,704 @@
1.6.13 2012-05-21
* New -S option for ldns-verify-zone to chase signatures online.
* New -k option for ldns-verify-zone to validate using a trusted key.
* New inception and expiration margin options (-i and -e) to
ldns-verify-zone.
* New ldns_dnssec_zone_new_frm_fp and ldns_dnssec_zone_new_frm_fp_l
functions.
* New ldns_duration* functions (copied from OpenDNSSEC source)
* fix ldns-verify-zone to allow NSEC3 signatures to come before
the NSEC3 RR in all cases. Thanks Wolfgang Nagele.
* Zero the correct flag (opt-out) when creating NSEC3PARAMS.
Thanks Peter van Dijk.
* Canonicalize RRSIG's Signer's name too when validating, because
bind and unbound do that too. Thanks Peter van Dijk.
* bugfix #433: Allocate rdf using ldns_rdf_new in ldns_dname_label
* bugfix #432: Use LDNS_MALLOC & LDNS_FREE i.s.o. malloc & free
* bugfix #431: Added error message for LDNS_STATUS_INVALID_B32_EXT
* bugfix #427: Explicitely link ssl with the programs that use it.
* Fix reading \DDD: Error on values that are outside range (>255).
* bugfix #429: fix doxyparse.pl fails on NetBSD because specified
path to perl.
* New ECDSA support (RFC 6605), use --disable-ecdsa for older openssl.
* fix verifying denial of existence for DS's in NSEC3 Opt-Out zones.
Thanks John Barnitz
1.6.12 2012-01-11
* bugfix #413: Fix manpage source for srcdir != builddir
* Canonicalize the signers name rdata field in RRSIGs when signing
* Ignore minor version of Private-key-format (so v1.3 may be used)
* Allow a check_time to be given in stead of always checking against
the current time. With ldns-verify-zone the check_time can be set
with the -t option.
* Added functions for updating and manipulating SOA serial numbers.
ldns-read-zone has an option -S for updating and manipulating the
serial numbers.
* The library Makefile is now GNU and BSD make compatible.
* bugfix #419: NSEC3 validation of a name covered by a wildcard with
no data.
* Two new options (--with-drill and --with-examples) to the main
configure script (in the root of the source tree) to build drill
and examples too.
* Fix days_since_epoch to year_yday calculation on 32bits systems.
1.6.11 2011-09-29
* bugfix #394: Fix socket leak on errors
* bugfix #392: Apex only and percentage checks for ldns-verify-zone
(thanks Miek Gieben)
* bugfix #398: Allow NSEC RRSIGs before the NSEC3 in ldns-verify-zone
* Fix python site package path from sitelib to sitearch for pyldns.
* Fix python api to support python2 and python3 (thanks Karel Slany).
* bugfix #401: Correction of date/time functions algorithm and
prevention of an infinite loop therein
* bugfix #402: Correct the minimum and maximum number of rdata fields
in TSIG. (thanks David Keeler)
* bugfix #403: Fix heap overflow (thanks David Keeler)
* bugfix #404: Make parsing APL strings more robust
(thanks David Keeler)
* bugfix #391: Complete library assessment to prevent assertion errors
through ldns_rdf_size usage.
* Slightly more specific error messaging on wrong number of rdata
fields with the LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG and
LDNS_STATUS_MISSING_RDATA_FIELDS_KEY result codes.
* bugfix #406: More rigorous openssl result code handling to prevent
future crashes within openssl.
* Fix ldns_fetch_valid_domain_keys to search deeper than just one level
for a DNSKEY that signed a DS RR. (this function was used in the
check_dnssec_trace nagios module)
* bugfix #407: Canonicalize TSIG dnames and algorithm fields
* A new output specifier to accommodate configuration of what to show
in comment texts when converting host and/or wire-format data to
string. All conversion to string and printing functions have a new
version that have such a format specifier as an extra argument.
The default is changed so that only DNSKEY RR's are annotated with
an comment show the Key Tag of the DNSKEY.
* Fixed the ldns resolver to not mark a nameserver unreachable when
edns0 is tried unsuccessfully with size 4096 (no return packet came),
but to still try TCP. A big UDP packet might have been corrupted by
fragments dropping firewalls.
* Update of libdns.vim (thanks Miek Gieben)
* Added the ldnsx Python module to our contrib section, which adds even
more pythonisticism to the usage of ldns with Python. (Many thanks
to Christpher Olah and Paul Wouters)
The ldnsx module is automatically installed when --with-pyldns is
used with configuring, but may explicitly be excluded with the
--without-pyldnsx option to configure.
* bugfix #410: Fix clearing out temporary data on stack in sha2.c
* bugfix #411: Don't let empty non-terminal NSEC3s cause assertion failure.
1.6.10 2011-05-31
* New example tool added: ldns-gen-zone.
* bugfix #359: Serial-arithmetic for the inception and expiration
fields of a RRSIG and correctly converting them to broken-out time
information.
* bugfix #364: Slight performance increase of ldns-verifyzone.
* bugfix #367: Fix to allow glue records with the same name as the
delegation.
* Fix ldns-verifyzone to allow NSEC3-less records for NS rrsets *and*
glue when the zone is opt-out.
* bugfix #376: Adapt ldns_nsec3_salt, ldns_nsec3_iterations,
ldns_nsec3_flags and ldns_nsec3_algorithm to work for NSEC3PARAMS too.
* pyldns memory leaks fixed by Bedrich Kosata (at the cost of a bit
performance)
* Better handling of reference variables in ldns_rr_new_frm_fp_l from
pyldns, with a very nice generator function by Bedrich Kosata.
* Decoupling of the rdfs in rrs in the python wrappers to enable
the python garbage collector by Bedrich Kosata.
* bugfix #380: Minimizing effect of discrepancies in sizeof(bool) at
build time and when used.
* bugfix #383: Fix detection of empty nonterminals of multiple labels.
* Fixed the ommission of rrsets in nsec(3)s and rrsigs to all occluded
names (in stead of just the ones that contain glue only) and all
occluded records on the delegation points (in stead of just the glue).
* Clarify the operation of ldns_dnssec_mark_glue and the usage of
ldns_dnssec_node_next_nonglue functions in the documentation.
* Added function ldns_dnssec_mark_and_get_glue as an real fast
alternative for ldns_zone_glue_rr_list.
* Fix parse buffer overflow for max length domain names.
* Fix Makefile for U in environment, since wrong U is more common than
deansification necessity.
1.6.9 2011-03-16
* Fix creating NSEC(3) bitmaps: make array size 65536,
don't add doubles.
* Fix printout of escaped binary in TXT records.
* Parsing TXT records: don't skip starting whitespace that is quoted.
* bugfix #358: Check if memory was successfully allocated in
ldns_rdf2str().
* Added more memory allocation checks in host2str.c
* python wrapper for ldns_fetch_valid_domain_keys by Bedrich Kosata.
* fix to compile python wrapper with swig 2.0.2.
* Don't fallback to SHA-1 when creating NSEC3 hash with another
algorithm identifier, fail instead (no other algorithm identifiers
are assigned yet).
1.6.8 2011-01-24
* Fix ldns zone, so that $TTL definition match RFC 2308.
* Fix lots of missing checks on allocation failures and parse of
NSEC with many types and max parse length in hosts_frm_fp routine
and off by one in read_anchor_file routine (thanks Dan Kaminsky and
Justin Ferguson).
* bugfix #335: Drill: Print both SHA-1 and SHA-256 corresponding DS
records.
* Print correct WHEN in query packet (is not always 1-1-1970)
* ldns-test-edns: new example tool that detects EDNS support.
* fix ldns_resolver_send without openssl.
* bugfix #342: patch for support for more CERT key types (RFC4398).
* bugfix #351: fix udp_send hang if UDP checksum error.
* fix set_bit (from NSEC3 sign) patch from Jan Komissar.
1.6.7 2010-11-08
* EXPERIMENTAL ecdsa implementation, please do not enable on real
servers.
* GOST code enabled by default (RFC 5933).
* bugfix #326: ignore whitespace between directives and their values.
* Header comment to advertise ldns_axfr_complete to check for
successfully completed zone transfers.
* read resolv.conf skips interface labels, e.g. %eth0.
* Fix drill verify NSEC3 denials.
* Use closesocket() on windows.
* Add ldns_get_signing_algorithm_by_name that understand aliases,
names changed to RFC names and aliases for compatibility added.
* bugfix: don't print final dot if the domain is relative.
* bugfix: resolver search continue when packet rcode != NOERROR.
* bugfix: resolver push all domains in search directive to list.
* bugfix: resolver search by default includes the root domain.
* bugfix: tcp read could fail on single octet recv.
* bugfix: read of RR in unknown syntax with missing fields.
* added ldns_pkt_tsig_sign_next() and ldns_pkt_tsig_verify_next()
to sign and verify TSIG RRs on subsequent messages
(section 4.4, RFC 2845, thanks to Michael Sheldon).
* bugfix: signer sigs nsecs with zsks only.
* bugfix #333: fix ldns_dname_absolute for name ending with backslash.
1.6.6 2010-08-09
* Fix ldns_rr_clone to copy question rrs properly.
* Fix ldns_sign_zone(_nsec3) to clone the soa for the new zone.
* Fix ldns_wire2dname size check from reading 1 byte beyond buffer end.
* Fix ldns_wire2dname from reading 1 byte beyond end for pointer.
* Fix crash using GOST for particular platform configurations.
* extern C declarations used in the header file.
* Removed debug fprintf from resolver.c.
* ldns-signzone checks if public key file is for the right zone.
* NETLDNS, .NET port of ldns functionality, by Alex Nicoll, in contrib.
* Fix handling of comments in resolv.conf parse.
* GOST code enabled if SSL recent, RFC 5933.
* bugfix #317: segfault util.c ldns_init_random() fixed.
* Fix ldns_tsig_mac_new: allocate enough memory for the hash, fix use of
b64_pton_calculate_size.
* Fix ldns_dname_cat: size calculation and handling of realloc().
* Fix ldns_rr_pop_rdf: fix handling of realloc().
* Fix ldns-signzone for single type key scheme: sign whole zone if there
are only KSKs.
* Fix ldns_resolver: also close socket if AXFR failed (if you don't,
it would block subsequent transfers (thanks Roland van Rijswijk).
* Fix drill: allow for a secure trace if you use DS records as trust
anchors (thanks Jan Komissar).
1.6.5 2010-06-15
* Catch \X where X is a digit as an error.
* Fix segfault when ip6 ldns resolver only has ip4 servers.
* Fix NSEC record after DNSKEY at zone apex not properly signed.
* Fix syntax error if last label too long and no dot at end of domain.
* Fix parse of \# syntax with space for type LOC.
* Fix ldns_dname_absolute for escape sequences, fixes some parse errs.
* bugfix #297: linking ssl, bug due to patch submitted as #296.
* bugfix #299: added missing declarations to host2str.h
* ldns-compare-zones -s to not exclude SOA record from comparison.
* --disable-rpath fix
* fix ldns_pkt_empty(), reported by Alex Nicoll.
* fix ldns_resolver_new_frm_fp not ignore lines after a comment.
* python code for ldns_rr.new_question_frm_str()
* Fix ldns_dnssec_verify_denial: the signature selection routine.
* Type TALINK parsed (draft-ietf-dnsop-trust-history).
* bugfix #304: fixed dead loop in ldns_tcp_read_wire() and
ldns_tcp_read_wire_timeout().
* GOST support with correct algorithm numbers. The plan is to make it
enabled if openssl support is detected, but it is disabled by
default in this release because the RFC is not ready.
* Fixed comment in rbtree.h about being first member and data ptr.
* Fixed possibly leak in case of out of memory in ldns_native2rdf...
* ldns_dname_is_wildcard added.
* Fixed: signatures over wildcards had the wrong labelcount.
* Fixed ldns_verify() inconsistent return values.
* Fixed ldns_resolver to copy and free tsig name, data and algorithm.
* Fixed ldns_resolver to push search onto searchlist.
* A ldns resolver now defaults to a non-recursive resolver that handles
the TC bit.
* ldns_resolver_print() prints more details.
* Fixed ldns_rdf2buffer_str_time(), which did not print timestamps
on 64bit systems.
* Make ldns_resolver_nameservers_randomize() more random.
* bugfix #310: POSIX specifies NULL second argument of gettimeofday.
* fix compiler warnings from llvm clang compiler.
* bugfix #309: ldns_pkt_clone did not clone the tsig_rr.
* Fix gentoo ebuild for drill, 'no m4 directory'.
* bugfix #313: drill trace on an empty nonterminal continuation.
1.6.4 2010-01-20
* Imported pyldns contribution by Zdenek Vasicek and Karel Slany.
Changed its configure and Makefile to fit into ldns.
Added its dname_* methods to the rdf_* class (as is the ldns API).
Changed swig destroy of ldns_buffer class to ldns_buffer_free.
Declared ldns_pkt_all and ldns_pkt_all_noquestion so swig sees them.
* Bugfix: parse PTR target of .tomhendrikx.nl with error not crash.
* Bugfix: handle escaped characters in TXT rdata.
* bug292: no longer crash on malformed domain names where a label is
on position 255, which was a buffer overflow by one.
* Fix ldns_get_rr_list_hosts_frm_fp_l (strncpy to strlcpy change),
which fixes resolv.conf reading badly terminated string buffers.
* Fix ldns_pkt_set_random_id to be more random, and a little faster,
it did not do value 0 statistically correctly.
* Fix ldns_rdf2native_sockaddr_storage to set sockaddr type to zeroes,
for portability.
* bug295: nsec3-hash routine no longer case sensitive.
* bug298: drill failed nsec3 denial of existence proof.
1.6.3 2009-12-04
* Bugfix: allow for unknown resource records in zonefile with rdlen=0.
* Bugfix: also mark an RR as question if it comes from the wire
* Bugfix: NSEC3 bitmap contained NSEC
* Bugfix: Inherit class when creating signatures
1.6.2 2009-11-12
* Fix Makefile patch from Havard Eidnes, better install.sh usage.
* Fix parse error on SOA serial of 2910532839.
Fix print of ';' and readback of '\;' in names, also for '\\'.
Fix parse of '\(' and '\)' in names. Also for file read. Also '\.'
* Fix signature creation when TTLs are different for RRs in RRset.
* bug273: fix so EDNS rdata is included in pkt to wire conversion.
* bug274: fix use of c++ keyword 'class' for RR class in the code.
* bug275: fix memory leak of packet edns rdata.
* Fix timeout procedure for TCP and AXFR on Solaris.
* Fix occasional NSEC bitmap bogus
* Fix rr comparing (was in reversed order since 1.6.0)
* bug278: fix parsing HINFO rdata (and other cases).
* Fix previous owner name: also pick up if owner name is @.
* RFC5702: enabled sha2 functions by default. This requires OpenSSL 0.9.8 or higher.
Reason for this default is the root to be signed with RSASHA256.
* Fix various LDNS RR parsing issues: IPSECKEY, WKS, NSAP, very long lines
* Fix: Make ldns_dname_is_subdomain case insensitive.
* Fix ldns-verify-zone so that address records at zone NS set are not considered glue
(Or glue records fall below delegation)
* Fix LOC RR altitude printing.
* Feature: Added period (e.g. '3m6d') support at explicit TTLs.
* Feature: DNSKEY rrset by default signed with minimal signatures
but -A option for ldns-signzone to sign it with all keys.
This makes the DNSKEY responses smaller for signed domains.
1.6.1 2009-09-14
* --enable-gost : use the GOST algorithm (experimental).
* Added some missing options to drill manpage
* Some fixes to --without-ssl option
* Fixed quote parsing withing strings
* Bitmask fix in EDNS handling
* Fixed non-fqdn domain name completion for rdata field domain
names of length 1
* Fixed chain validation with SHA256 DS records
1.6.0
Additions:
* Addition of an ldns-config script which gives cflags and libs
values, for use in configure scripts for applications that use
use ldns. Can be disabled with ./configure --disable-ldns-config
* Added direct sha1, sha256, and sha512 support in ldns.
With these functions, all NSEC3 functionality can still be
used, even if ldns is built without OpenSSL. Thanks to OpenBSD,
Steve Reid, and Aaron D. Gifford for the code.
* Added reading/writing support for the SPF Resource Record
* Base32 functions are now exported
Bugfixes:
* ldns_is_rrset did not go through the complete rrset, but
only compared the first two records. Thanks to Olafur
Gudmundsson for report and patch
* Fixed a small memory bug in ldns_rr_list_subtype_by_rdf(),
thanks to Marius Rieder for finding an patching this.
* --without-ssl should now work. Make sure that examples/ and
drill also get the --without-ssl flag on their configure, if
this is used.
* Some malloc() return value checks have been added
* NSEC3 creation has been improved wrt to empty nonterminals,
and opt-out.
* Fixed a bug in the parser when reading large NSEC3 salt
values.
* Made the allowed length for domain names on wire
and presentation format the same.
Example tools:
* ldns-key2ds can now also generate DS records for keys without
the SEP flag
* ldns-signzone now equalizes the TTL of the DNSKEY RRset (to
the first non-default DNSKEY TTL value it sees)
1.5.1
Example tools:
* ldns-signzone was broken in 1.5.0 for multiple keys, this
has been repaired
Build system:
* Removed a small erroneous output warning in
examples/configure and drill/configure
1.5.0
Bug fixes:
* fixed a possible memory overflow in the RR parser
* build flag fix for Sun Studio
* fixed a building race condition in the copying of header
files
* EDNS0 extended rcode; the correct assembled code number
is now printed (still in the EDNS0 field, though)
* ldns_pkt_rr no longer leaks memory (in fact, it no longer
copies anything all)
API addition:
* ldns_key now has support for 'external' data, in which
case the OpenSSL EVP structures are not used;
ldns_key_set_external_key() and ldns_key_external_key()
* added ldns_key_get_file_base_name() which creates a
'default' filename base string for key storage, of the
form "K<zone>+<algorithm>+<keytag>"
* the ldns_dnssec_* family of structures now have deep_free()
functions, which also free the ldns_rr's contained in them
* there is now an ldns_match_wildcard() function, which checks
whether a domain name matches a wildcard name
* ldns_sign_public has been split up; this resulted in the
addition of ldns_create_empty_rrsig() and
ldns_sign_public_buffer()
Examples:
* ldns-signzone can now automatically add DNSKEY records when
using an OpenSSL engine, as it already did when using key
files
* added new example tool: ldns-nsec3-hash
* ldns-dpa can now filter on specific query name and types
* ldnsd has fixes for the zone name, a fix for the return
value of recvfrom(), and an memory initialization fix
(Thanks to Colm MacCárthaigh for the patch)
* Fixed memory leaks in ldnsd
1.4.1
Bug fixes:
* fixed a build issue where ldns lib existence was done too early
* removed unnecessary check for pcap.h
* NSEC3 optout flag now correctly printed in string output
* inttypes.h moved to configured inclusion
* fixed NSEC3 type bitmaps for empty nonterminals and unsigned
delegations
API addition:
* for that last fix, we added a new function
ldns_dname_add_from() that can clone parts of a dname
1.4.0
Bug fixes:
* sig chase return code fix (patch from Rafael Justo, bug id 189)
* rdata.c memory leaks on error and allocation checks fixed (patch
from Shane Kerr, bug id 188)
* zone.c memory leaks on error and allocation checks fixed (patch
from Shane Kerr, bug id 189)
* ldns-zplit output and error messages fixed (patch from Shane Kerr,
bug id 190)
* Fixed potential buffer overflow in ldns_str2rdf_dname
* Signing code no longer signs delegation NS rrsets
* Some minor configure/makefile updates
* Fixed a bug in the randomness initialization
* Fixed a bug in the reading of resolv.conf
* Fixed a bug concerning whitespace in zone data (with patch from Ondrej
Sury, bug 213)
* Fixed a small fallback problem in axfr client code
API CHANGES:
* added 2str convenience functions:
- ldns_rr_type2str
- ldns_rr_class2str
- ldns_rr_type2buffer_str
- ldns_rr_class2buffer_str
* buffer2str() is now called ldns_buffer2str
* base32 and base64 function names are now also prepended with ldns_
* ldns_rr_new_frm_str() now returns an error on missing RDATA fields.
Since you cannot read QUESTION section RRs with this anymore,
there is now a function called ldns_rr_new_question_frm_str()
LIBRARY FEATURES:
* DS RRs string representation now add bubblebabble in a comment
(patch from Jakob Schlyter)
* DLV RR type added
* TCP fallback system has been improved
* HMAC-SHA256 TSIG support has been added.
* TTLS are now correcly set in NSEC(3) records when signing zones
EXAMPLE TOOLS:
* New example: ldns-revoke to revoke DNSKEYs according to RFC5011
* ldns-testpkts has been fixed and updated
* ldns-signzone now has the option to not add the DNSKEY
* ldns-signzone now has an (full zone only) opt-out option for
NSEC3
* ldns-keygen can create HMAC-SHA1 and HMAC-SHA256 symmetric keys
* ldns-walk output has been fixed
* ldns-compare-zones has been fixed, and now has an option
to show all differences (-a)
* ldns-read-zone now has an option to print DNSSEC records only
1.3
Base library:
* Added a new family of functions based around ldns_dnssec_zone,
which is a new structure that keeps a zone sorted through an
rbtree and links signatures and NSEC(3) records directly to their
RRset. These functions all start with ldns_dnssec_
* ldns_zone_sign and ldns_zone_sign_nsec3 are now deprecated, but
have been changed to internally use the new
ldns_dnssec_zone_sign(_nsec3)
* Moved some ldns_buffer functions inline, so a clean rebuild of
applications relying on those is needed (otherwise you'll get
linker errors)
* ldns_dname_label now returns one extra (zero)
byte, so it can be seen as an fqdn.
* NSEC3 type code update for signing algorithms.
* DSA key generation of DNSKEY RRs fixed (one byte too small).
* Added support for RSA/SHA256 and RSA/SHA512, as specified in
draft-ietf-dnsext-dnssec-rsasha256-04. The typecodes are not
final, and this feature is not enabled by default. It can be
enabled at compilation time with the flag --with-sha2
* Added 2wire_canonical family of functions that lowercase dnames
in rdata fields in resource records of the types in the list in
rfc3597
* Added base32 conversion functions.
* Fixed DSA RRSIG conversion when calling OpenSSL
Drill:
* Chase output is completely different, it shows, in ascii, the
relations in the trust hierarchy.
Examples:
* Added ldns-verify-zone, that can verify the internal DNSSEC records
of a signed BIND-style zone file
* ldns-keygen now takes an -a argument specifying the algorithm,
instead of -R or -D. -a list show a list of supported algorithms
* ldns-keygen now defaults to the exponent RSA_F4 instead of RSA_3
for RSA key generation
* ldns-signzone now has support for HSMs
* ldns-signzone uses the new ldns_dnssec_ structures and functions
which improves its speed, and output; RRSIGS are now placed
directly after their RRset, NSEC(3) records directly after the
name they handle
Contrib:
* new contrib/ dir with user contributions
* added compilation script for solaris (thanks to Jakob Schlyter)
28 Nov 2007 1.2.2:
* Added support for HMAC-MD5 keys in generator
* Added a new example tool (written by Ondrej Sury): ldns-compare-zones
* ldns-keygen now checks key sizes for rfc conformancy
* ldns-signzone outputs SSL error if present
* Fixed manpages (thanks to Ondrej Sury)
* Fixed Makefile for -j <x>
* Fixed a $ORIGIN error when reading zones
* Fixed another off-by-one error
03 Oct 2007 1.2.1:
* Fixed an offset error in rr comparison
* Fixed ldns-read-zone exit code
* Added check for availability of SHA256 hashing algorithm
* Fixed ldns-key2ds -2 argument
* Fixed $ORIGIN bug in .key files
* Output algorithms as an integer instead of their mnemonic
* Fixed a memory leak in dnssec code when SHA256 is not available
* Updated fedora .spec file
11 Apr 2007 1.2.0:
* canonicalization of rdata in DNSSEC functions now adheres to the
rr type list in rfc3597, not rfc4035, which will be updated
(see http://www.ops.ietf.org/lists/namedroppers/namedroppers.2007/msg00183.html)
* ldns-walk now support dnames with maximum label length
* ldnsd now takes an extra argument containing the address to listen on
* signing no longer signs every rrset with KSK's, but only the DNSKEY rrset
* ported to Solaris 10
* added ldns_send_buffer() function
* added ldns-testpkts fake packet server
* added ldns-notify to send NOTIFY packets
* ldns-dpa can now accurately calculate the number of matches per
second
* libtool is now used for compilation too (still gcc, but not directly)
* Bugfixes:
- TSIG signing buffer size
- resolv.conf reading (comments)
- dname comparison off by one error
- typo in keyfetchers output file name fixed (a . too much)
- fixed zone file parser when comments contain ( or )
- fixed LOC RR type
- fixed CERT RR type
Drill:
* drill prints error on failed axfr.
* drill now accepts mangled packets with -f
* old -c option (use tcp) changed to -t
* -c option to specify alternative resolv.conf file added
* feedback of signature chase improved
* chaser now stops at root when no trusted keys are found
instead of looping forever trying to find the DS for .
* Fixed bugs:
- wildcard on multiple labels signature verification
- error in -f packet writing for malformed packets
- made KSK check more resilient
7 Jul 2006: 1.1.0: ldns-team
* Added tutorials and an introduction to the documentation
* Added include/ and lib/ dirs so that you can compile against ldns
without installing ldns on your system
* Makefile updates
* Starting usage of assert throughout the library to catch illegal calls
* Solaris 9 testing was carried out. Ldns now compiles on that
platform; some gnuism were identified and fixed.
* The ldns_zone structure was stress tested. The current setup
(ie. just a list of rrs) can scale to zone file in order of
megabytes. Sorting such zone is still difficult.
* Reading multiline b64 encoded rdata works.
* OpenSSL was made optional, configure --without-ssl.
Ofcourse all dnssec/tsig related functions are disabled
* Building of examples and drill now happens with the same
defines as the building of ldns itself.
* Preliminary sha-256 support was added. Currently is your
OpenSSL supports it, it is supported in the DS creation.
* ldns_resolver_search was implemented
* Fixed a lot of bugs
Drill:
* -r was killed in favor of -o <header bit mnemonic> which
allows for a header bits setting (and maybe more in the
future)
* DNSSEC is never automaticaly set, even when you query
for DNSKEY/RRSIG or DS.
* Implement a crude RTT check, it now distinguishes between
reachable and unreachable.
* A form of secure tracing was added
* Secure Chasing has been improved
* -x does a reverse lookup for the given IP address
Examples:
* ldns-dpa was added to the examples - this is the Dns Packet
Analyzer tool.
* ldnsd - as very, very simple nameserver impl.
* ldns-zsplit - split zones for parrallel signing
* ldns-zcat - cat split zones back together
* ldns-keyfetcher - Fetches DNSKEY records with a few (non-strong,
non-DNSSEC) anti-spoofing techniques.
* ldns-walk - 'Walks' a DNSSEC signed zone
* Added an all-static target to the makefile so you can use examples
without installing the library
* When building in the source tree or in a direct subdirectory of
the build dir, configure does not need --with-ldns=../ anymore
Code:
* All networking code was moved to net.c
* rdata.c: added asserts to the rdf set/get functions
* const keyword was added to pointer arguments that
aren't changed
API:
Changed:
* renamed ldns/dns.h to ldns/ldns.h
* ldns_rr_new_frm_str() is extented with an extra variable which
in common use may be NULL. This trickles through to:
o ldns_rr_new_frm_fp
o ldns_rr_new_frm_fp_l
Which also get an extra variable
Also the function has been changed to return a status message.
The compiled RR is returned in the first argument.
* ldns_zone_new_frm_fp_l() and ldns_zone_new_frm_fp() are
changed to return a status msg.
* ldns_key_new_frm_fp is changed to return ldns_status and
the actual key list in the first argument
* ldns_rdata_new_frm_fp[_l]() are changed to return a status.
the rdf is return in the first argument
* ldns_resolver_new_frm_fp: same treatment: return status and
the new resolver in the first argument
* ldns_pkt_query_new_frm_str(): same: return status and the
packet in the first arg
* tsig.h: internal used functions are now static:
ldns_digest_name and ldns_tsig_mac_new
* ldns_key_rr2ds has an extra argument to specify the hash to
use.
* ldns_pkt_rcode() is renamed to ldns_pkt_get_rcode, ldns_pkt_rcode
is now the rcode type, like ldns_pkt_opcode
New:
* ldns_resolver_searchlist_count: return the searchlist counter
* ldns_zone_sort: Sort a zone
* ldns_bgsend(): background send, returns a socket.
* ldns_pkt_empty(): check is a packet is empty
* ldns_rr_list_pop_rr_list(): pop multiple rr's from another rr_list
* ldns_rr_list_push_rr_list(): push multiple rr's to an rr_list
* ldns_rr_list_compare(): compare 2 ldns_rr_lists
* ldns_pkt_push_rr_list: rr_list equiv for rr
* ldns_pkt_safe_push_rr_list: rr_list equiv for rr
Removed:
* ldns_resolver_bgsend(): was not used in 1.0.0 and is not used now
* ldns_udp_server_connect(): was faulty and isn't really part of
the core ldns idea any how.
* ldns_rr_list_insert_rr(): obsoleted, because not used.
* char *_when was removed from the ldns_pkt structure
18 Oct 2005: 1.0.0: ldns-team
* Commited a patch from Håkan Olsson
* Added UPDATE support (Jakob Schlyter and Håkan Olsson)
* License change: ldns is now BSD licensed
* ldns now depends on SSL
* Networking code cleanup, added (some) server udp/tcp support
* A zone type is introduced. Currently this is a list
of RRs, so it will not scale well.
* [beta] Zonefile parsing was added
* [tools] Drill was added to ldns - see drill/
* [tools] experimental signer was added
* [building] better check for ssl
* [building] major revision of build system
* [building] added rpm .spec in packaging/ (thanks to Paul Wouters)
* [building] A lot of cleanup in the build scripts (thanks to Jakob Schlyter
and Paul Wouters)
28 Jul 2005: 0.70: ldns-team
* [func] ldns_pkt_get_section now returns copies from the rrlists
in the packet. This can be freed by the user program
* [code] added ldns_ prefixes to function from util.h
* [inst] removed documentation from default make install
* Usual fixes in documentation and code
20 Jun 2005: 0.66: ldns-team
Rel. Focus: drill-pre2 uses some functions which are
not in 0.65
* dnssec_cd bit function was added
* Zone infrastructure was added
* Usual fixes in documentation and code
13 Jun 2005: 0.65: ldns-team
* Repository is online at:
http://www.nlnetlabs.nl/ldns/svn/
* Apply reference copying throuhgout ldns, except in 2
places in the ldns_resolver structure (._domain and
._nameservers)
* Usual array of bugfixes
* Documentation added
* keygen.c added as an example for DNSSEC programming
23 May 2005: 0.60: ldns-team
* Removed config.h from the header installed files
(you're not supposed to include that in a libary)
* Further tweaking
- DNSSEC signing/verification works
- Assorted bug fixes and tweaks (memory management)
May 2005: 0.50: ldns-team
* First usable release
* Basic DNS functionality works
* DNSSEC validation works

26
contrib/ldns/LICENSE Normal file
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.

1098
contrib/ldns/Makefile.in Normal file

File diff suppressed because it is too large Load diff

144
contrib/ldns/README Normal file
View file

@ -0,0 +1,144 @@
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)
- 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
4. gmake (it needs gnu make to compile, on systems where GNU make is the
default you can just use 'make')
5. sudo gmake install
6. Optional. (cd examples; ./configure; gmake), make example programs included.
7. Optional. (cd drill; ./configure; gmake; gmake install), to build drill.
You can configure and compile it in a separate build directory.
* Examples
There are some examples and dns related tools in the examples/ directory.
These can be built with:
1. cd examples/
2. ./configure [--with-ldns=<path to ldns installation or build>]
3. gmake
* Drill
Drill can be built with:
1. cd drill/
2. ./configure [--with-ldns=<path to ldns installation or build>]
3. gmake
Note that you need to set LD_LIBRARY_PATH if you want to run the binaries
and you have not installed the library to a system directory. You can use
the make target all-static for the examples to run them if you don't want to
install the library.
* Building from subversion 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.svn. Note that the actual
commands may be a little bit different on your machine. Most notable, 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
o Matthijs Mekking
Former main developers:
o Jelte Jansen
o Miek Gieben
* 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ý
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 (that 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:
http://www.nlnetlabs.nl/projects/ldns/bugs
* pyldns
Compiling pyldns produces many ``unused parameter'' warnings. Those are
harmless and may safely be ignored.
Also when building with Swig which version is before 2.0.4, compiling
pyldns produces many ``missing initializer'' warnings. Those are harmless
too.
Your Support
NLnet Labs offers all of its software products as open source, most are
published under a BDS license. You can download them, not only from the
NLnet Labs website but also through the various OS distributions for
which NSD, ldns, and Unbound are packaged. We therefore have little idea
who uses our software in production environments and have no direct ties
with 'our customers'.
Therefore, we ask you to contact us at users@NLnetLabs.nl and tell us
whether you use one of our products in your production environment,
what that environment looks like, and maybe even share some praise.
We would like to refer to the fact that your organization is using our
products. We will only do that if you explicitly allow us. In all other
cases we will keep the information you share with us to ourselves.
In addition to the moral support you can also support us
financially. NLnet Labs is a recognized not-for-profit charity foundation
that is chartered to develop open-source software and open-standards
for the Internet. If you use our software to satisfaction please express
that by giving us a donation. For small donations PayPal can be used. For
larger and regular donations please contact us at users@NLnetLabs.nl. Also
see http://www.nlnetlabs.nl/labs/contributors/.

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 the tar file name.
They should not be used for packaging in distributions.

26
contrib/ldns/README.svn Normal file
View file

@ -0,0 +1,26 @@
# The ldns subversion repository can found at:
# www.nlnetlabs.nl/ldns/svn/
# 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
# (and these systems probably need gmake instead of make)
# older versions of libtoolize do not support --install
# so you might need to remove that (with newer versions
# it is needed)
libtoolize -c --install
autoreconf --install
./configure
make
make doc # needs doxygen for the html pages
(cd examples && autoreconf && ./configure && make)
(cd drill && autoreconf && ./configure && make)
(cd pcat && autoreconf && ./configure && make)
(cd examples/nsd-test && autoreconf && ./configure && make)

8620
contrib/ldns/aclocal.m4 vendored Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

135
contrib/ldns/ax_pkg_swig.m4 Normal file
View file

@ -0,0 +1,135 @@
# ===========================================================================
# http://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 <irwin@beluga.phys.uvic.ca>
# Copyright (c) 2008 Rafael Laboissiere <rafael@laboissiere.net>
# Copyright (c) 2008 Andrew Collier <colliera@ukzn.ac.za>
# 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 <http://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 8
AC_DEFUN([AX_PKG_SWIG],[
# Ubuntu has swig 2.0 as /usr/bin/swig2.0
AC_PATH_PROGS([SWIG],[swig2.0 swig])
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,327 @@
# ===========================================================================
# http://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_LDFLAGS)
# 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 <irwin@beluga.phys.uvic.ca>
# Copyright (c) 2009 Rafael Laboissiere <rafael@laboissiere.net>
# Copyright (c) 2009 Andrew Collier <colliera@ukzn.ac.za>
# Copyright (c) 2009 Matteo Settenvini <matteo@member.fsf.org>
# Copyright (c) 2009 Horst Knorr <hk_classes@knoda.org>
#
# 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 <http://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 8
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_LDFLAGS, 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
#
if test -n "$1"; then
AC_MSG_CHECKING([for a version of Python $1])
ac_supports_python_ver=`$PYTHON -c "import sys; \
ver = sys.version.split ()[[0]]; \
print (ver $1)"`
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 distutils Python package])
ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
if test -z "$ac_distutils_result"; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
AC_MSG_ERROR([cannot import Python module "distutils".
Please check your Python installation. The error was:
$ac_distutils_result])
PYTHON_VERSION=""
fi
#
# Check for Python include path
#
AC_MSG_CHECKING([for Python include path])
if test -z "$PYTHON_CPPFLAGS"; then
python_path=`$PYTHON -c "import distutils.sysconfig; \
print (distutils.sysconfig.get_python_inc ());"`
if test -n "${python_path}"; then
python_path="-I$python_path"
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_LDFLAGS"; 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 distutils.sysconfig import *
ret = ''
for e in get_config_vars ('VERSION'):
if (e != None):
ret += e
print (ret)
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 (sys.version[[:3]])"`
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 distutils.sysconfig
for e in distutils.sysconfig.get_config_vars ('LIBDIR'):
if e != None:
print (e)
break
EOD
`
# Before checking for libpythonX.Y, we need to know
# the extension the OS we're on uses for libraries
# (we take the first one, if there's more than one fix me!):
ac_python_soext=`$PYTHON -c \
"import distutils.sysconfig; \
print (distutils.sysconfig.get_config_vars('SO')[[0]])"`
# Now, for the library:
ac_python_soname=`$PYTHON -c \
"import distutils.sysconfig; \
print (distutils.sysconfig.get_config_vars('LDLIBRARY')[[0]])"`
# Strip away extension from the end to canonicalize its name:
ac_python_library=`echo "$ac_python_soname" | sed "s/${ac_python_soext}$//"`
# 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" \
-a x"$ac_python_library" != x"$ac_python_soname"
then
# use the official shared library
ac_python_library=`echo "$ac_python_library" | sed "s/^lib//"`
PYTHON_LDFLAGS="-L$ac_python_libdir -l$ac_python_library"
else
# old way: use libpython from python_configdir
ac_python_libdir=`$PYTHON -c \
"from distutils.sysconfig import get_python_lib as f; \
import os; \
print (os.path.join(f(plat_specific=1, standard_lib=1), 'config'));"`
PYTHON_LDFLAGS="-L$ac_python_libdir -lpython$ac_python_version"
fi
if test -z "PYTHON_LDFLAGS"; then
AC_MSG_ERROR([
Cannot determine location of your Python DSO. Please check it was installed with
dynamic libraries enabled, or try setting PYTHON_LDFLAGS by hand.
])
fi
fi
AC_MSG_RESULT([$PYTHON_LDFLAGS])
AC_SUBST([PYTHON_LDFLAGS])
#
# Check for site packages
#
AC_MSG_CHECKING([for Python site-packages path])
if test -z "$PYTHON_SITE_PKG"; then
PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
print (distutils.sysconfig.get_python_lib(1,0));"`
fi
AC_MSG_RESULT([$PYTHON_SITE_PKG])
AC_SUBST([PYTHON_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 distutils.sysconfig; \
conf = distutils.sysconfig.get_config_var; \
print (conf('LOCALMODLIBS') + ' ' + conf('LIBS'))"`
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 distutils.sysconfig; \
conf = distutils.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_CPPFLAGS="$CPPFLAGS"
LIBS="$ac_save_LIBS $PYTHON_LDFLAGS $PYTHON_EXTRA_LDFLAGS $PYTHON_EXTRA_LIBS"
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"
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 LDFLAGS environment variable.
Example: ./configure LDFLAGS="-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!
#
])

176
contrib/ldns/buffer.c Normal file
View file

@ -0,0 +1,176 @@
/*
* 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, 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);
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);
assert(!buffer->_fixed);
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;
}
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, 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,333 @@
/*
* 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 <sys/types.h>
#include <sys/param.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
static const char Base32[] =
"abcdefghijklmnopqrstuvwxyz234567";
/* "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";*/
/* 00000000001111111111222222222233
01234567890123456789012345678901*/
static const char Base32_extended_hex[] =
/* "0123456789ABCDEFGHIJKLMNOPQRSTUV";*/
"0123456789abcdefghijklmnopqrstuv";
static const char Pad32 = '=';
/* (From RFC3548 and draft-josefsson-rfc3548bis-00.txt)
5. Base 32 Encoding
The Base 32 encoding is designed to represent arbitrary sequences of
octets in a form that needs to be case insensitive but need not be
humanly readable.
A 33-character subset of US-ASCII is used, enabling 5 bits to be
represented per printable character. (The extra 33rd character, "=",
is used to signify a special processing function.)
The encoding process represents 40-bit groups of input bits as output
strings of 8 encoded characters. Proceeding from left to right, a
40-bit input group is formed by concatenating 5 8bit input groups.
These 40 bits are then treated as 8 concatenated 5-bit groups, each
of which is translated into a single digit in the base 32 alphabet.
When encoding a bit stream via the base 32 encoding, the bit stream
must be presumed to be ordered with the most-significant-bit first.
That is, the first bit in the stream will be the high-order bit in
the first 8bit byte, and the eighth bit will be the low-order bit in
the first 8bit byte, and so on.
Each 5-bit group is used as an index into an array of 32 printable
characters. The character referenced by the index is placed in the
output string. These characters, identified in Table 3, below, are
selected from US-ASCII digits and uppercase letters.
Table 3: The Base 32 Alphabet
Value Encoding Value Encoding Value Encoding Value Encoding
0 A 9 J 18 S 27 3
1 B 10 K 19 T 28 4
2 C 11 L 20 U 29 5
3 D 12 M 21 V 30 6
4 E 13 N 22 W 31 7
5 F 14 O 23 X
6 G 15 P 24 Y (pad) =
7 H 16 Q 25 Z
8 I 17 R 26 2
Special processing is performed if fewer than 40 bits are available
at the end of the data being encoded. A full encoding quantum is
always completed at the end of a body. When fewer than 40 input bits
are available in an input group, zero bits are added (on the right)
to form an integral number of 5-bit groups. Padding at the end of
the data is performed using the "=" character. Since all base 32
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 40
bits; here, the final unit of encoded output will be an integral
multiple of 8 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 six
"=" padding characters,
(3) the final quantum of encoding input is exactly 16 bits; here, the
final unit of encoded output will be four characters followed by four
"=" padding characters,
(4) the final quantum of encoding input is exactly 24 bits; here, the
final unit of encoded output will be five characters followed by
three "=" padding characters, or
(5) the final quantum of encoding input is exactly 32 bits; here, the
final unit of encoded output will be seven characters followed by one
"=" padding character.
6. Base 32 Encoding with Extended Hex Alphabet
The following description of base 32 is due to [7]. This encoding
should not be regarded as the same as the "base32" encoding, and
should not be referred to as only "base32".
One property with this alphabet, that the base64 and base32 alphabet
lack, is that encoded data maintain its sort order when the encoded
data is compared bit-wise.
This encoding is identical to the previous one, except for the
alphabet. The new alphabet is found in table 4.
Table 4: The "Extended Hex" Base 32 Alphabet
Value Encoding Value Encoding Value Encoding Value Encoding
0 0 9 9 18 I 27 R
1 1 10 A 19 J 28 S
2 2 11 B 20 K 29 T
3 3 12 C 21 L 30 U
4 4 13 D 22 M 31 V
5 5 14 E 23 N
6 6 15 F 24 O (pad) =
7 7 16 G 25 P
8 8 17 H 26 Q
*/
int
ldns_b32_ntop_ar(uint8_t const *src, size_t srclength, char *target, size_t targsize, const char B32_ar[]) {
size_t datalength = 0;
uint8_t input[5];
uint8_t output[8];
size_t i;
memset(output, 0, 8);
while (4 < srclength) {
input[0] = *src++;
input[1] = *src++;
input[2] = *src++;
input[3] = *src++;
input[4] = *src++;
srclength -= 5;
output[0] = (input[0] & 0xf8) >> 3;
output[1] = ((input[0] & 0x07) << 2) + ((input[1] & 0xc0) >> 6);
output[2] = (input[1] & 0x3e) >> 1;
output[3] = ((input[1] & 0x01) << 4) + ((input[2] & 0xf0) >> 4);
output[4] = ((input[2] & 0x0f) << 1) + ((input[3] & 0x80) >> 7);
output[5] = (input[3] & 0x7c) >> 2;
output[6] = ((input[3] & 0x03) << 3) + ((input[4] & 0xe0) >> 5);
output[7] = (input[4] & 0x1f);
assert(output[0] < 32);
assert(output[1] < 32);
assert(output[2] < 32);
assert(output[3] < 32);
assert(output[4] < 32);
assert(output[5] < 32);
assert(output[6] < 32);
assert(output[7] < 32);
if (datalength + 8 > targsize) {
return (-1);
}
target[datalength++] = B32_ar[output[0]];
target[datalength++] = B32_ar[output[1]];
target[datalength++] = B32_ar[output[2]];
target[datalength++] = B32_ar[output[3]];
target[datalength++] = B32_ar[output[4]];
target[datalength++] = B32_ar[output[5]];
target[datalength++] = B32_ar[output[6]];
target[datalength++] = B32_ar[output[7]];
}
/* Now we worry about padding. */
if (0 != srclength) {
/* Get what's left. */
input[0] = input[1] = input[2] = input[3] = input[4] = (uint8_t) '\0';
for (i = 0; i < srclength; i++)
input[i] = *src++;
output[0] = (input[0] & 0xf8) >> 3;
assert(output[0] < 32);
if (srclength >= 1) {
output[1] = ((input[0] & 0x07) << 2) + ((input[1] & 0xc0) >> 6);
assert(output[1] < 32);
output[2] = (input[1] & 0x3e) >> 1;
assert(output[2] < 32);
}
if (srclength >= 2) {
output[3] = ((input[1] & 0x01) << 4) + ((input[2] & 0xf0) >> 4);
assert(output[3] < 32);
}
if (srclength >= 3) {
output[4] = ((input[2] & 0x0f) << 1) + ((input[3] & 0x80) >> 7);
assert(output[4] < 32);
output[5] = (input[3] & 0x7c) >> 2;
assert(output[5] < 32);
}
if (srclength >= 4) {
output[6] = ((input[3] & 0x03) << 3) + ((input[4] & 0xe0) >> 5);
assert(output[6] < 32);
}
if (datalength + 1 > targsize) {
return (-2);
}
target[datalength++] = B32_ar[output[0]];
if (srclength >= 1) {
if (datalength + 1 > targsize) { return (-2); }
target[datalength++] = B32_ar[output[1]];
if (srclength == 1 && output[2] == 0) {
if (datalength + 1 > targsize) { return (-2); }
target[datalength++] = Pad32;
} else {
if (datalength + 1 > targsize) { return (-2); }
target[datalength++] = B32_ar[output[2]];
}
} else {
if (datalength + 1 > targsize) { return (-2); }
target[datalength++] = Pad32;
if (datalength + 1 > targsize) { return (-2); }
target[datalength++] = Pad32;
}
if (srclength >= 2) {
if (datalength + 1 > targsize) { return (-2); }
target[datalength++] = B32_ar[output[3]];
} else {
if (datalength + 1 > targsize) { return (-2); }
target[datalength++] = Pad32;
}
if (srclength >= 3) {
if (datalength + 1 > targsize) { return (-2); }
target[datalength++] = B32_ar[output[4]];
if (srclength == 3 && output[5] == 0) {
if (datalength + 1 > targsize) { return (-2); }
target[datalength++] = Pad32;
} else {
if (datalength + 1 > targsize) { return (-2); }
target[datalength++] = B32_ar[output[5]];
}
} else {
if (datalength + 1 > targsize) { return (-2); }
target[datalength++] = Pad32;
if (datalength + 1 > targsize) { return (-2); }
target[datalength++] = Pad32;
}
if (srclength >= 4) {
if (datalength + 1 > targsize) { return (-2); }
target[datalength++] = B32_ar[output[6]];
} else {
if (datalength + 1 > targsize) { return (-2); }
target[datalength++] = Pad32;
}
if (datalength + 1 > targsize) { return (-2); }
target[datalength++] = Pad32;
}
if (datalength+1 > targsize) {
return (int) (datalength);
}
target[datalength] = '\0'; /* Returned value doesn't count \0. */
return (int) (datalength);
}
int
ldns_b32_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize) {
return ldns_b32_ntop_ar(src, srclength, target, targsize, Base32);
}
/* deprecated, here for backwards compatibility */
int
b32_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize) {
return ldns_b32_ntop_ar(src, srclength, target, targsize, Base32);
}
int
ldns_b32_ntop_extended_hex(uint8_t const *src, size_t srclength, char *target, size_t targsize) {
return ldns_b32_ntop_ar(src, srclength, target, targsize, Base32_extended_hex);
}
/* deprecated, here for backwards compatibility */
int
b32_ntop_extended_hex(uint8_t const *src, size_t srclength, char *target, size_t targsize) {
return ldns_b32_ntop_ar(src, srclength, target, targsize, Base32_extended_hex);
}

View file

@ -0,0 +1,387 @@
/*
* 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 <sys/types.h>
#include <sys/param.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";*/
static const char Base32[] =
"abcdefghijklmnopqrstuvwxyz234567";
/* "0123456789ABCDEFGHIJKLMNOPQRSTUV";*/
static const char Base32_extended_hex[] =
"0123456789abcdefghijklmnopqrstuv";
static const char Pad32 = '=';
/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
5. Base 32 Encoding
The Base 32 encoding is designed to represent arbitrary sequences of
octets in a form that needs to be case insensitive but need not be
humanly readable.
A 33-character subset of US-ASCII is used, enabling 5 bits to be
represented per printable character. (The extra 33rd character, "=",
is used to signify a special processing function.)
The encoding process represents 40-bit groups of input bits as output
strings of 8 encoded characters. Proceeding from left to right, a
40-bit input group is formed by concatenating 5 8bit input groups.
These 40 bits are then treated as 8 concatenated 5-bit groups, each
of which is translated into a single digit in the base 32 alphabet.
When encoding a bit stream via the base 32 encoding, the bit stream
must be presumed to be ordered with the most-significant-bit first.
That is, the first bit in the stream will be the high-order bit in
the first 8bit byte, and the eighth bit will be the low-order bit in
the first 8bit byte, and so on.
Each 5-bit group is used as an index into an array of 32 printable
characters. The character referenced by the index is placed in the
output string. These characters, identified in Table 3, below, are
selected from US-ASCII digits and uppercase letters.
Table 3: The Base 32 Alphabet
Value Encoding Value Encoding Value Encoding Value Encoding
0 A 9 J 18 S 27 3
1 B 10 K 19 T 28 4
2 C 11 L 20 U 29 5
3 D 12 M 21 V 30 6
4 E 13 N 22 W 31 7
5 F 14 O 23 X
6 G 15 P 24 Y (pad) =
7 H 16 Q 25 Z
8 I 17 R 26 2
Special processing is performed if fewer than 40 bits are available
at the end of the data being encoded. A full encoding quantum is
always completed at the end of a body. When fewer than 40 input bits
are available in an input group, zero bits are added (on the right)
to form an integral number of 5-bit groups. Padding at the end of
the data is performed using the "=" character. Since all base 32
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 40
bits; here, the final unit of encoded output will be an integral
multiple of 8 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 six
"=" padding characters,
(3) the final quantum of encoding input is exactly 16 bits; here, the
final unit of encoded output will be four characters followed by four
"=" padding characters,
(4) the final quantum of encoding input is exactly 24 bits; here, the
final unit of encoded output will be five characters followed by
three "=" padding characters, or
(5) the final quantum of encoding input is exactly 32 bits; here, the
final unit of encoded output will be seven characters followed by one
"=" padding character.
6. Base 32 Encoding with Extended Hex Alphabet
The following description of base 32 is due to [7]. This encoding
should not be regarded as the same as the "base32" encoding, and
should not be referred to as only "base32".
One property with this alphabet, that the base32 and base32 alphabet
lack, is that encoded data maintain its sort order when the encoded
data is compared bit-wise.
This encoding is identical to the previous one, except for the
alphabet. The new alphabet is found in table 4.
Table 4: The "Extended Hex" Base 32 Alphabet
Value Encoding Value Encoding Value Encoding Value Encoding
0 0 9 9 18 I 27 R
1 1 10 A 19 J 28 S
2 2 11 B 20 K 29 T
3 3 12 C 21 L 30 U
4 4 13 D 22 M 31 V
5 5 14 E 23 N
6 6 15 F 24 O (pad) =
7 7 16 G 25 P
8 8 17 H 26 Q
*/
/* skips all whitespace anywhere.
converts characters, four at a time, starting at (or after)
src from base - 32 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_b32_pton_ar(char const *src, size_t hashed_owner_str_len, uint8_t *target, size_t targsize, const char B32_ar[])
{
int tarindex, state, ch;
char *pos;
int i = 0;
state = 0;
tarindex = 0;
while ((ch = *src++) != '\0' && (i == 0 || i < (int) hashed_owner_str_len)) {
i++;
ch = tolower(ch);
if (isspace((unsigned char)ch)) /* Skip whitespace anywhere. */
continue;
if (ch == Pad32)
break;
pos = strchr(B32_ar, ch);
if (pos == 0) {
/* A non-base32 character. */
return (-ch);
}
switch (state) {
case 0:
if (target) {
if ((size_t)tarindex >= targsize) {
return (-2);
}
target[tarindex] = (pos - B32_ar) << 3;
}
state = 1;
break;
case 1:
if (target) {
if ((size_t)tarindex + 1 >= targsize) {
return (-3);
}
target[tarindex] |= (pos - B32_ar) >> 2;
target[tarindex+1] = ((pos - B32_ar) & 0x03)
<< 6 ;
}
tarindex++;
state = 2;
break;
case 2:
if (target) {
if ((size_t)tarindex + 1 >= targsize) {
return (-4);
}
target[tarindex] |= (pos - B32_ar) << 1;
}
/*tarindex++;*/
state = 3;
break;
case 3:
if (target) {
if ((size_t)tarindex + 1 >= targsize) {
return (-5);
}
target[tarindex] |= (pos - B32_ar) >> 4;
target[tarindex+1] = ((pos - B32_ar) & 0x0f) << 4 ;
}
tarindex++;
state = 4;
break;
case 4:
if (target) {
if ((size_t)tarindex + 1 >= targsize) {
return (-6);
}
target[tarindex] |= (pos - B32_ar) >> 1;
target[tarindex+1] = ((pos - B32_ar) & 0x01)
<< 7 ;
}
tarindex++;
state = 5;
break;
case 5:
if (target) {
if ((size_t)tarindex + 1 >= targsize) {
return (-7);
}
target[tarindex] |= (pos - B32_ar) << 2;
}
state = 6;
break;
case 6:
if (target) {
if ((size_t)tarindex + 1 >= targsize) {
return (-8);
}
target[tarindex] |= (pos - B32_ar) >> 3;
target[tarindex+1] = ((pos - B32_ar) & 0x07)
<< 5 ;
}
tarindex++;
state = 7;
break;
case 7:
if (target) {
if ((size_t)tarindex + 1 >= targsize) {
return (-9);
}
target[tarindex] |= (pos - B32_ar);
}
tarindex++;
state = 0;
break;
default:
abort();
}
}
/*
* We are done decoding Base-32 chars. Let's see if we ended
* on a byte boundary, and/or with erroneous trailing characters.
*/
if (ch == Pad32) { /* 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 (-10);
case 2: /* Valid, means one byte of info */
case 3:
/* 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 != Pad32) {
return (-11);
}
ch = *src++; /* Skip the = */
/* Fall through to "single trailing =" case. */
/* FALLTHROUGH */
case 4: /* Valid, means two bytes of info */
case 5:
case 6:
/*
* 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) || ch == '=')) {
return (-12);
}
case 7: /* Valid, means three 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 (-13);
}
/*
* 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 (-14);
}
}
} else {
/*
* We ended by seeing the end of the string. Make sure we
* have no partial bytes lying around.
*/
if (state != 0)
return (-15);
}
return (tarindex);
}
int
ldns_b32_pton(char const *src, size_t hashed_owner_str_len, uint8_t *target, size_t targsize)
{
return ldns_b32_pton_ar(src, hashed_owner_str_len, target, targsize, Base32);
}
/* deprecated, here for backwards compatibility */
int
b32_pton(char const *src, size_t hashed_owner_str_len, uint8_t *target, size_t targsize)
{
return ldns_b32_pton_ar(src, hashed_owner_str_len, target, targsize, Base32);
}
int
ldns_b32_pton_extended_hex(char const *src, size_t hashed_owner_str_len, uint8_t *target, size_t targsize)
{
return ldns_b32_pton_ar(src, hashed_owner_str_len, target, targsize, Base32_extended_hex);
}
/* deprecated, here for backwards compatibility */
int
b32_pton_extended_hex(char const *src, size_t hashed_owner_str_len, uint8_t *target, size_t targsize)
{
return ldns_b32_pton_ar(src, hashed_owner_str_len, target, targsize, Base32_extended_hex);
}

View file

@ -0,0 +1,202 @@
/*
* 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 <sys/types.h>
#include <sys/param.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Assert(Cond) if (!(Cond)) abort()
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,260 @@
/*
* 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 <sys/types.h>
#include <sys/param.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Assert(Cond) if (!(Cond)) abort()
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 *src, uint8_t *target, size_t targsize)
{
int tarindex, state, ch;
char *pos;
state = 0;
tarindex = 0;
if (strlen(src) == 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 ();
/* 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);
}

View file

@ -0,0 +1,770 @@
#include <ldns/config.h>
#ifndef HAVE_SNPRINTF
#include <ctype.h>
#include <sys/types.h>
/* Define this as a fall through, HAVE_STDARG_H is probably already set */
#define HAVE_VARARGS_H
/**************************************************************
* Original:
* Patrick Powell Tue Apr 11 09:48:21 PDT 1995
* A bombproof version of doprnt (dopr) included.
* Sigh. This sort of thing is always nasty do deal with. Note that
* the version here does not include floating point...
*
* snprintf() is used instead of sprintf() as it does limit checks
* for string length. This covers a nasty loophole.
*
* The other functions are there to prevent NULL pointers from
* causing nast effects.
*
* More Recently:
* Brandon Long (blong@fiction.net) 9/15/96 for mutt 0.43
* This was ugly. It is still ugly. I opted out of floating point
* numbers, but the formatter understands just about everything
* from the normal C string format, at least as far as I can tell from
* the Solaris 2.5 printf(3S) man page.
*
* Brandon Long (blong@fiction.net) 10/22/97 for mutt 0.87.1
* Ok, added some minimal floating point support, which means this
* probably requires libm on most operating systems. Don't yet
* support the exponent (e,E) and sigfig (g,G). Also, fmtint()
* was pretty badly broken, it just wasn't being exercised in ways
* which showed it, so that's been fixed. Also, formated the code
* to mutt conventions, and removed dead code left over from the
* original. Also, there is now a builtin-test, just compile with:
* gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
* and run snprintf for results.
*
**************************************************************/
/* varargs declarations: */
#if defined(HAVE_STDARG_H)
# include <stdarg.h>
# define HAVE_STDARGS /* let's hope that works everywhere (mj) */
# define VA_LOCAL_DECL va_list ap
# define VA_START(f) va_start(ap, f)
# define VA_SHIFT(v,t) ; /* no-op for ANSI */
# define VA_END va_end(ap)
#else
# if defined(HAVE_VARARGS_H)
# include <varargs.h>
# undef HAVE_STDARGS
# define VA_LOCAL_DECL va_list ap
# define VA_START(f) va_start(ap) /* f is ignored! */
# define VA_SHIFT(v,t) v = va_arg(ap,t)
# define VA_END va_end(ap)
# else
/*XX ** NO VARARGS ** XX*/
# endif
#endif
int snprintf (char *str, size_t count, const char *fmt, ...);
int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
static void dopr (char *buffer, size_t maxlen, const char *format,
va_list args);
static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
char *value, int flags, int min, int max);
static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
long value, int base, int min, int max, int flags);
static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
long double fvalue, int min, int max, int flags);
static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c );
int vsnprintf (char *str, size_t count, const char *fmt, va_list args)
{
str[0] = 0;
dopr(str, count, fmt, args);
return(strlen(str));
}
/* VARARGS3 */
#ifdef HAVE_STDARGS
int snprintf (char *str,size_t count,const char *fmt,...)
#else
int snprintf (va_alist) va_dcl
#endif
{
#ifndef HAVE_STDARGS
char *str;
size_t count;
char *fmt;
#endif
VA_LOCAL_DECL;
VA_START (fmt);
VA_SHIFT (str, char *);
VA_SHIFT (count, size_t );
VA_SHIFT (fmt, char *);
(void) vsnprintf(str, count, fmt, ap);
VA_END;
return(strlen(str));
}
/*
* dopr(): poor man's version of doprintf
*/
/* format read states */
#define DP_S_DEFAULT 0
#define DP_S_FLAGS 1
#define DP_S_MIN 2
#define DP_S_DOT 3
#define DP_S_MAX 4
#define DP_S_MOD 5
#define DP_S_CONV 6
#define DP_S_DONE 7
/* format flags - Bits */
#define DP_F_MINUS 1
#define DP_F_PLUS 2
#define DP_F_SPACE 4
#define DP_F_NUM 8
#define DP_F_ZERO 16
#define DP_F_UP 32
/* Conversion Flags */
#define DP_C_SHORT 1
#define DP_C_LONG 2
#define DP_C_LDOUBLE 3
#define char_to_int(p) (p - '0')
#define MAX(p,q) ((p >= q) ? p : q)
static void dopr (char *buffer, size_t maxlen, const char *format, va_list args)
{
char ch;
long value;
long double fvalue;
char *strvalue;
int min;
int max;
int state;
int flags;
int cflags;
size_t currlen;
state = DP_S_DEFAULT;
currlen = flags = cflags = min = 0;
max = -1;
ch = *format++;
while (state != DP_S_DONE)
{
if ((ch == '\0') || (currlen >= maxlen))
state = DP_S_DONE;
switch(state)
{
case DP_S_DEFAULT:
if (ch == '%')
state = DP_S_FLAGS;
else
dopr_outch (buffer, &currlen, maxlen, ch);
ch = *format++;
break;
case DP_S_FLAGS:
switch (ch)
{
case '-':
flags |= DP_F_MINUS;
ch = *format++;
break;
case '+':
flags |= DP_F_PLUS;
ch = *format++;
break;
case ' ':
flags |= DP_F_SPACE;
ch = *format++;
break;
case '#':
flags |= DP_F_NUM;
ch = *format++;
break;
case '0':
flags |= DP_F_ZERO;
ch = *format++;
break;
default:
state = DP_S_MIN;
break;
}
break;
case DP_S_MIN:
if (isdigit((int) ch))
{
min = 10*min + char_to_int (ch);
ch = *format++;
}
else if (ch == '*')
{
min = va_arg (args, int);
ch = *format++;
state = DP_S_DOT;
}
else
state = DP_S_DOT;
break;
case DP_S_DOT:
if (ch == '.')
{
state = DP_S_MAX;
ch = *format++;
}
else
state = DP_S_MOD;
break;
case DP_S_MAX:
if (isdigit((int) ch))
{
if (max < 0)
max = 0;
max = 10*max + char_to_int (ch);
ch = *format++;
}
else if (ch == '*')
{
max = va_arg (args, int);
ch = *format++;
state = DP_S_MOD;
}
else
state = DP_S_MOD;
break;
case DP_S_MOD:
/* Currently, we don't support Long Long, bummer */
switch (ch)
{
case 'h':
cflags = DP_C_SHORT;
ch = *format++;
break;
case 'l':
cflags = DP_C_LONG;
ch = *format++;
break;
case 'L':
cflags = DP_C_LDOUBLE;
ch = *format++;
break;
default:
break;
}
state = DP_S_CONV;
break;
case DP_S_CONV:
switch (ch)
{
case 'd':
case 'i':
if (cflags == DP_C_SHORT)
value = va_arg (args, int);
else if (cflags == DP_C_LONG)
value = va_arg (args, long int);
else
value = va_arg (args, int);
fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
break;
case 'o':
flags &= ~DP_F_PLUS;
if (cflags == DP_C_SHORT)
value = va_arg (args, unsigned int);
else if (cflags == DP_C_LONG)
value = va_arg (args, unsigned long int);
else
value = va_arg (args, unsigned int);
fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
break;
case 'u':
flags &= ~DP_F_PLUS;
if (cflags == DP_C_SHORT)
value = va_arg (args, unsigned int);
else if (cflags == DP_C_LONG)
value = va_arg (args, unsigned long int);
else
value = va_arg (args, unsigned int);
fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
break;
case 'X':
flags |= DP_F_UP;
case 'x':
flags &= ~DP_F_PLUS;
if (cflags == DP_C_SHORT)
value = va_arg (args, unsigned int);
else if (cflags == DP_C_LONG)
value = va_arg (args, unsigned long int);
else
value = va_arg (args, unsigned int);
fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
break;
case 'f':
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg (args, long double);
else
fvalue = va_arg (args, double);
/* um, floating point? */
fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
break;
case 'E':
flags |= DP_F_UP;
case 'e':
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg (args, long double);
else
fvalue = va_arg (args, double);
break;
case 'G':
flags |= DP_F_UP;
case 'g':
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg (args, long double);
else
fvalue = va_arg (args, double);
break;
case 'c':
dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
break;
case 's':
strvalue = va_arg (args, char *);
if (max < 0)
max = maxlen; /* ie, no max */
fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
break;
case 'p':
strvalue = va_arg (args, void *);
fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
break;
case 'n':
if (cflags == DP_C_SHORT)
{
short int *num;
num = va_arg (args, short int *);
*num = currlen;
}
else if (cflags == DP_C_LONG)
{
long int *num;
num = va_arg (args, long int *);
*num = currlen;
}
else
{
int *num;
num = va_arg (args, int *);
*num = currlen;
}
break;
case '%':
dopr_outch (buffer, &currlen, maxlen, ch);
break;
case 'w':
/* not supported yet, treat as next char */
ch = *format++;
break;
default:
/* Unknown, skip */
break;
}
ch = *format++;
state = DP_S_DEFAULT;
flags = cflags = min = 0;
max = -1;
break;
case DP_S_DONE:
break;
default:
/* hmm? */
break; /* some picky compilers need this */
}
}
if (currlen < maxlen - 1)
buffer[currlen] = '\0';
else
buffer[maxlen - 1] = '\0';
}
static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
char *value, int flags, int min, int max)
{
int padlen, strln; /* amount to pad */
int cnt = 0;
if (value == 0)
{
value = (char *) "<NULL>";
}
for (strln = 0; value[strln]; ++strln); /* strlen */
padlen = min - strln;
if (padlen < 0)
padlen = 0;
if (flags & DP_F_MINUS)
padlen = -padlen; /* Left Justify */
while ((padlen > 0) && (cnt < max))
{
dopr_outch (buffer, currlen, maxlen, ' ');
--padlen;
++cnt;
}
while (*value && (cnt < max))
{
dopr_outch (buffer, currlen, maxlen, *value++);
++cnt;
}
while ((padlen < 0) && (cnt < max))
{
dopr_outch (buffer, currlen, maxlen, ' ');
++padlen;
++cnt;
}
}
/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
long value, int base, int min, int max, int flags)
{
int signvalue = 0;
unsigned long uvalue;
char convert[20];
int place = 0;
int spadlen = 0; /* amount to space pad */
int zpadlen = 0; /* amount to zero pad */
int caps = 0;
if (max < 0)
max = 0;
uvalue = value;
if( value < 0 ) {
signvalue = '-';
uvalue = -value;
}
else
if (flags & DP_F_PLUS) /* Do a sign (+/i) */
signvalue = '+';
else
if (flags & DP_F_SPACE)
signvalue = ' ';
if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
do {
convert[place++] =
(caps? "0123456789ABCDEF":"0123456789abcdef")
[uvalue % (unsigned)base ];
uvalue = (uvalue / (unsigned)base );
} while(uvalue && (place < 20));
if (place == 20) place--;
convert[place] = 0;
zpadlen = max - place;
spadlen = min - MAX (max, place) - (signvalue ? 1 : 0);
if (zpadlen < 0) zpadlen = 0;
if (spadlen < 0) spadlen = 0;
if (flags & DP_F_ZERO)
{
zpadlen = MAX(zpadlen, spadlen);
spadlen = 0;
}
if (flags & DP_F_MINUS)
spadlen = -spadlen; /* Left Justifty */
#ifdef DEBUG_SNPRINTF
dprint (1, (debugfile, "zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
zpadlen, spadlen, min, max, place));
#endif
/* Spaces */
while (spadlen > 0)
{
dopr_outch (buffer, currlen, maxlen, ' ');
--spadlen;
}
/* Sign */
if (signvalue)
dopr_outch (buffer, currlen, maxlen, signvalue);
/* Zeros */
if (zpadlen > 0)
{
while (zpadlen > 0)
{
dopr_outch (buffer, currlen, maxlen, '0');
--zpadlen;
}
}
/* Digits */
while (place > 0)
dopr_outch (buffer, currlen, maxlen, convert[--place]);
/* Left Justified spaces */
while (spadlen < 0) {
dopr_outch (buffer, currlen, maxlen, ' ');
++spadlen;
}
}
static long double abs_val (long double value)
{
long double result = value;
if (value < 0)
result = -value;
return result;
}
static double pow10 (double exp)
{
long double result = 1;
while (exp)
{
result *= 10;
exp--;
}
return result;
}
static double round (double value)
{
long intpart;
intpart = value;
value = value - intpart;
if (value >= 0.5)
intpart++;
return intpart;
}
static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
long double fvalue, int min, int max, int flags)
{
int signvalue = 0;
long double ufvalue;
char iconvert[20];
char fconvert[20];
int iplace = 0;
int fplace = 0;
int padlen = 0; /* amount to pad */
int zpadlen = 0;
int caps = 0;
long intpart;
long fracpart;
/*
* AIX manpage says the default is 0, but Solaris says the default
* is 6, and sprintf on AIX defaults to 6
*/
if (max < 0)
max = 6;
ufvalue = abs_val (fvalue);
if (fvalue < 0)
signvalue = '-';
else
if (flags & DP_F_PLUS) /* Do a sign (+/i) */
signvalue = '+';
else
if (flags & DP_F_SPACE)
signvalue = ' ';
#if 0
if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
#endif
intpart = ufvalue;
/*
* Sorry, we only support 9 digits past the decimal because of our
* conversion method
*/
if (max > 9)
max = 9;
/* We "cheat" by converting the fractional part to integer by
* multiplying by a factor of 10
*/
fracpart = round ((pow10 (max)) * (ufvalue - intpart));
if (fracpart >= pow10 (max))
{
intpart++;
fracpart -= pow10 (max);
}
#ifdef DEBUG_SNPRINTF
dprint (1, (debugfile, "fmtfp: %f =? %d.%d\n", fvalue, intpart, fracpart));
#endif
/* Convert integer part */
do {
iconvert[iplace++] =
(caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10];
intpart = (intpart / 10);
} while(intpart && (iplace < 20));
if (iplace == 20) iplace--;
iconvert[iplace] = 0;
/* Convert fractional part */
do {
fconvert[fplace++] =
(caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10];
fracpart = (fracpart / 10);
} while(fracpart && (fplace < 20));
if (fplace == 20) fplace--;
fconvert[fplace] = 0;
/* -1 for decimal point, another -1 if we are printing a sign */
padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
zpadlen = max - fplace;
if (zpadlen < 0)
zpadlen = 0;
if (padlen < 0)
padlen = 0;
if (flags & DP_F_MINUS)
padlen = -padlen; /* Left Justifty */
if ((flags & DP_F_ZERO) && (padlen > 0))
{
if (signvalue)
{
dopr_outch (buffer, currlen, maxlen, signvalue);
--padlen;
signvalue = 0;
}
while (padlen > 0)
{
dopr_outch (buffer, currlen, maxlen, '0');
--padlen;
}
}
while (padlen > 0)
{
dopr_outch (buffer, currlen, maxlen, ' ');
--padlen;
}
if (signvalue)
dopr_outch (buffer, currlen, maxlen, signvalue);
while (iplace > 0)
dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]);
/*
* Decimal point. This should probably use locale to find the correct
* char to print out.
*/
dopr_outch (buffer, currlen, maxlen, '.');
while (zpadlen > 0)
{
dopr_outch (buffer, currlen, maxlen, '0');
--zpadlen;
}
while (fplace > 0)
dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
while (padlen < 0)
{
dopr_outch (buffer, currlen, maxlen, ' ');
++padlen;
}
}
static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c)
{
if (*currlen < maxlen)
buffer[(*currlen)++] = c;
}
#ifdef TEST_SNPRINTF
#ifndef LONG_STRING
#define LONG_STRING 1024
#endif
int main (void)
{
char buf1[LONG_STRING];
char buf2[LONG_STRING];
char *fp_fmt[] = {
"%-1.5f",
"%1.5f",
"%123.9f",
"%10.5f",
"% 10.5f",
"%+22.9f",
"%+4.9f",
"%01.3f",
"%4f",
"%3.1f",
"%3.2f",
NULL
};
double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996,
0.9996, 1.996, 4.136, 0};
char *int_fmt[] = {
"%-1.5d",
"%1.5d",
"%123.9d",
"%5.5d",
"%10.5d",
"% 10.5d",
"%+22.33d",
"%01.3d",
"%4d",
NULL
};
long int_nums[] = { -1, 134, 91340, 341, 0203, 0};
int x, y;
int fail = 0;
int num = 0;
printf ("Testing snprintf format codes against system sprintf...\n");
for (x = 0; fp_fmt[x] != NULL ; x++)
for (y = 0; fp_nums[y] != 0 ; y++)
{
snprintf (buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]);
sprintf (buf2, fp_fmt[x], fp_nums[y]);
if (strcmp (buf1, buf2))
{
printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
fp_fmt[x], buf1, buf2);
fail++;
}
num++;
}
for (x = 0; int_fmt[x] != NULL ; x++)
for (y = 0; int_nums[y] != 0 ; y++)
{
snprintf (buf1, sizeof (buf1), int_fmt[x], int_nums[y]);
sprintf (buf2, int_fmt[x], int_nums[y]);
if (strcmp (buf1, buf2))
{
printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
int_fmt[x], buf1, buf2);
fail++;
}
num++;
}
printf ("%d tests failed out of %d.\n", fail, num);
}
#endif /* SNPRINTF_TEST */
#endif /* !HAVE_SNPRINTF */

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;
}

1530
contrib/ldns/config.guess vendored Executable file

File diff suppressed because it is too large Load diff

1773
contrib/ldns/config.sub vendored Executable file

File diff suppressed because it is too large Load diff

18779
contrib/ldns/configure vendored Executable file

File diff suppressed because it is too large Load diff

674
contrib/ldns/configure.ac Normal file
View file

@ -0,0 +1,674 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.56)
sinclude(acx_nlnetlabs.m4)
# must be numbers. ac_defun because of later processing.
m4_define([VERSION_MAJOR],[1])
m4_define([VERSION_MINOR],[6])
m4_define([VERSION_MICRO],[13])
AC_INIT(ldns, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), libdns@nlnetlabs.nl, libdns)
AC_CONFIG_SRCDIR([packet.c])
# needed to build correct soname
AC_SUBST(LIBTOOL_VERSION_INFO, VERSION_MAJOR:VERSION_MINOR:VERSION_MICRO)
AC_SUBST(LDNS_VERSION_MAJOR, [VERSION_MAJOR])
AC_SUBST(LDNS_VERSION_MINOR, [VERSION_MINOR])
AC_SUBST(LDNS_VERSION_MICRO, [VERSION_MICRO])
OURCPPFLAGS=''
CPPFLAGS=${CPPFLAGS:-${OURCPPFLAGS}}
CFLAGS="$CFLAGS"
AC_AIX
# Checks for programs.
AC_PROG_CC
ACX_DEPFLAG
AC_PROG_MAKE_SET
# Extra (sp)lint flags for NetBSD
AC_CANONICAL_HOST
case "$host_os" in
netbsd*) LINTFLAGS="'-D__RENAME(x)=' -D_NETINET_IN_H_ $LINTFLAGS"
;;
*) LINTFLAGS="$LINTFLAGS"
;;
esac
AC_SUBST(LINTFLAGS)
AC_DEFINE(WINVER, 0x0502, [the version of the windows API enabled])
ACX_CHECK_COMPILER_FLAG(std=c99, [C99FLAG="-std=c99"])
ACX_CHECK_COMPILER_FLAG(xc99, [C99FLAG="-xc99"])
# routine to copy files
# argument 1 is a list of files (relative to the source dir)
# argument 2 is a destination directory (relative to the current
# working directory
AC_DEFUN([COPY_FILES],
[
for file in $1; do
sh $srcdir/install-sh -m 644 $file $2
done
])
# copy all .h files in the dir at argument 1
# (relative to source) to the dir at argument 2
# (relative to current dir)
AC_DEFUN([COPY_HEADER_FILES],
[
echo "copying header files"
COPY_FILES($srcdir/$1/*.h, $2)
])
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_LANG_C
ACX_CHECK_COMPILER_FLAG(g, [CFLAGS="-g $CFLAGS"])
ACX_CHECK_COMPILER_FLAG(O2, [CFLAGS="-O2 $CFLAGS"])
ACX_CHECK_COMPILER_FLAG(Wall, [CFLAGS="-Wall $CFLAGS"])
ACX_CHECK_COMPILER_FLAG(W, [CFLAGS="-W $CFLAGS"])
ACX_CHECK_COMPILER_FLAG(Wwrite-strings, [CFLAGS="-Wwrite-strings $CFLAGS"])
AC_CHECK_HEADERS([getopt.h time.h],,, [AC_INCLUDES_DEFAULT])
# MinGW32 tests
AC_CHECK_HEADERS([winsock2.h ws2tcpip.h],,, [AC_INCLUDES_DEFAULT])
# end mingw32 tests
ACX_DETERMINE_EXT_FLAGS_UNBOUND
AC_C_INLINE
AC_CHECK_TYPE(int8_t, char)
AC_CHECK_TYPE(int16_t, short)
AC_CHECK_TYPE(int32_t, int)
AC_CHECK_TYPE(int64_t, long long)
AC_CHECK_TYPE(uint8_t, unsigned char)
AC_CHECK_TYPE(uint16_t, unsigned short)
AC_CHECK_TYPE(uint32_t, unsigned int)
AC_CHECK_TYPE(uint64_t, unsigned long long)
# my own checks
AC_CHECK_PROG(doxygen, doxygen, doxygen)
# check to see if libraries are needed for these functions.
AC_SEARCH_LIBS([socket], [socket])
AC_SEARCH_LIBS([inet_pton], [nsl])
AC_ARG_WITH(drill, AC_HELP_STRING([--with-drill],
[Also build drill.]),
[],[with_drill="no"])
if test x_$with_drill != x_no ; then
AC_SUBST(DRILL,[drill])
AC_SUBST(INSTALL_DRILL,[install-drill])
AC_SUBST(UNINSTALL_DRILL,[uninstall-drill])
AC_SUBST(CLEAN_DRILL,[clean-drill])
AC_SUBST(LINT_DRILL,[lint-drill])
if test -e $srcdir/drill/config.h -o -e drill/config.h ; then
AC_MSG_ERROR([
A config.h was detected in the drill subdirectory.
This does not work with the --with-drill option.
Please remove the config.h from the drill subdirectory
or do not use the --with-drill option.])
fi
else
AC_SUBST(DRILL,[""])
AC_SUBST(INSTALL_DRILL,[""])
AC_SUBST(UNINSTALL_DRILL,[""])
AC_SUBST(CLEAN_DRILL,[""])
AC_SUBST(LINT_DRILL,[""])
fi
AC_ARG_WITH(examples, AC_HELP_STRING([--with-examples],
[Also build examples.]),
[],[with_examples="no"])
if test x_$with_examples != x_no ; then
AC_SUBST(EXAMPLES,[examples])
AC_SUBST(INSTALL_EXAMPLES,[install-examples])
AC_SUBST(UNINSTALL_EXAMPLES,[uninstall-examples])
AC_SUBST(CLEAN_EXAMPLES,[clean-examples])
AC_SUBST(LINT_EXAMPLES,[lint-examples])
if test -e $srcdir/examples/config.h -o -e examples/config.h ; then
AC_MSG_ERROR([
A config.h was detected in the examples subdirectory.
This does not work with the --with-examples option.
Please remove the config.h from the examples subdirectory
or do not use the --with-examples option.])
fi
else
AC_SUBST(EXAMPLES,[""])
AC_SUBST(INSTALL_EXAMPLES,[""])
AC_SUBST(UNINSTALL_EXAMPLES,[""])
AC_SUBST(CLEAN_EXAMPLES,[""])
AC_SUBST(LINT_EXAMPLES,[""])
fi
# add option to disable installation of ldns-config script
AC_ARG_ENABLE(ldns-config, [ --disable-ldns-config disable installation of ldns-config (default=enabled)],
enable_ldns_config=$enableval, enable_ldns_config=yes)
if test "x$enable_ldns_config" = xyes; then
AC_SUBST(INSTALL_CONFIG, [install-config])
AC_SUBST(INSTALL_CONFIG_MANPAGE, [install-config-manpage])
AC_SUBST(UNINSTALL_CONFIG, [uninstall-config])
AC_SUBST(UNINSTALL_CONFIG_MANPAGE, [uninstall-config-manpage])
else
AC_SUBST(INSTALL_CONFIG, [""])
AC_SUBST(INSTALL_CONFIG_MANPAGE, [""])
AC_SUBST(UNINSTALL_CONFIG, [""])
AC_SUBST(UNINSTALL_CONFIG_MANPAGE, [""])
fi
# check for python
PYTHON_X_CFLAGS=""
ldns_with_pyldns=no
ldns_with_pyldnsx=no
AC_ARG_WITH(pyldns, AC_HELP_STRING([--with-pyldns],
[generate python library, or --without-pyldns to disable Python support.]),
[],[ withval="no" ])
ldns_have_python=no
if test x_$withval != x_no; then
sinclude(ax_python_devel.m4)
ac_save_LIBS="$LIBS" dnl otherwise AC_PYTHON_DEVEL thrashes $LIBS
AX_PYTHON_DEVEL([>= '2.4.0'])
if test ! -z "$ac_python_version"; then
ldns_have_python=yes
fi
# pass additional Python 3 option to SWIG
if test `$PYTHON -c "import sys; \
ver = sys.version.split()[[0]]; \
print(ver >= '3')"` = "True"; then
AC_SUBST(SWIGPY3, ["-py3 -DPY3"])
fi
# check for SWIG
if test x_$ldns_have_python != x_no; then
sinclude(ax_pkg_swig.m4)
# check for >=SWIG-2.0.4 if Python 3.2 used
if test `$PYTHON -c "import sys; \
ver = sys.version.split()[[0]]; \
print(ver >= '3.2')"` = "True"; then
AX_PKG_SWIG(2.0.4, [], [AC_MSG_ERROR([SWIG-2.0.4 is required to build pyldns for Python 3.2 and greater.])])
else
AX_PKG_SWIG
fi
if test ! -x "$SWIG"; then
AC_MSG_ERROR([failed to find SWIG tool, install it, or do not build pyldns])
else
AC_DEFINE(HAVE_SWIG,1,[Define if you have SWIG libraries and header files.])
AC_SUBST(PYLDNS, "pyldns")
AC_SUBST(swig, "$SWIG")
ldns_with_pyldns=yes
fi
else
AC_MSG_RESULT([*** don't have Python, skipping SWIG, no pyldns ***]) # '
fi
# xtra cflags for pyldns
if test x_$ldns_have_python != x_no; then
ACX_CHECK_COMPILER_FLAG(fno-strict-aliasing, [PYTHON_X_CFLAGS="-fno-strict-aliasing"])
ACX_CHECK_COMPILER_FLAG(Wno-missing-field-initializers, [PYTHON_X_CFLAGS="-Wno-missing-field-initializers $PYTHON_X_CFLAGS"])
ACX_CHECK_COMPILER_FLAG(Wno-unused-parameter, [PYTHON_X_CFLAGS="-Wno-unused-parameter $PYTHON_X_CFLAGS"])
ACX_CHECK_COMPILER_FLAG(Wno-unused-variable, [PYTHON_X_CFLAGS="-Wno-unused-variable $PYTHON_X_CFLAGS"])
fi
fi
AC_SUBST(PYTHON_X_CFLAGS)
# Check for pyldnsx
AC_ARG_WITH(pyldnsx, AC_HELP_STRING([--without-pyldnsx],
[Do not install the ldnsx python module, or --with-pyldnsx to install it.]),
[],[ withval="with_pyldns" ])
if test x_$withval != x_no; then
if test x_$ldns_with_pyldns != x_no; then
AC_SUBST(PYLDNSX, "pyldnsx")
ldns_with_pyldnsx=yes
else
if test x_$withval != x_with_pyldns; then
AC_MSG_ERROR([--with-pyldns is needed for the ldnsx python module])
fi
fi
fi
if test x_$ldns_with_pyldns != x_no; then
AC_SUBST(PYLDNSINST, "install-pyldns")dnl
AC_SUBST(PYLDNSUNINST, "uninstall-pyldns")
else
AC_SUBST(PYLDNSINST, "")dnl
AC_SUBST(PYLDNSUNINST, "")
fi
if test x_$ldns_with_pyldnsx != x_no; then
AC_SUBST(PYLDNSXINST, "install-pyldnsx")dnl
AC_SUBST(PYLDNSXUNINST, "uninstall-pyldnsx")
else
AC_SUBST(PYLDNSXINST, "")dnl
AC_SUBST(PYLDNSXUNINST, "")
fi
# Use libtool
ACX_LIBTOOL_C_ONLY
tmp_CPPFLAGS=$CPPFLAGS
tmp_LDFLAGS=$LDFLAGS
tmp_LIBS=$LIBS
ACX_WITH_SSL_OPTIONAL
AC_CHECK_FUNCS([EVP_sha256])
# for macosx, see if glibtool exists and use that
# BSD's need to know the version...
#AC_CHECK_PROG(glibtool, glibtool, [glibtool], )
#AC_CHECK_PROGS(libtool, [libtool15 libtool], [./libtool])
AC_ARG_ENABLE(sha2, AC_HELP_STRING([--disable-sha2], [Disable SHA256 and SHA512 RRSIG support]))
case "$enable_sha2" in
no)
;;
yes|*)
if test "x$HAVE_SSL" != "xyes"; then
AC_MSG_ERROR([SHA2 enabled, but no SSL support])
fi
AC_MSG_CHECKING(for SHA256 and SHA512)
AC_CHECK_FUNC(SHA256_Init, [], [
AC_MSG_ERROR([No SHA2 functions found in OpenSSL: please upgrade OpenSSL or rerun with --disable-sha2])
])
AC_DEFINE_UNQUOTED([USE_SHA2], [1], [Define this to enable SHA256 and SHA512 support.])
;;
esac
AC_ARG_ENABLE(gost, AC_HELP_STRING([--disable-gost], [Disable GOST support]))
case "$enable_gost" in
no)
;;
*) dnl default
if test "x$HAVE_SSL" != "xyes"; then
AC_MSG_ERROR([GOST enabled, but no SSL support])
fi
AC_MSG_CHECKING(for GOST)
AC_CHECK_FUNC(EVP_PKEY_set_type_str, [],[AC_MSG_ERROR([OpenSSL >= 1.0.0 is needed for GOST support or rerun with --disable-gost])])
AC_CHECK_FUNC(EC_KEY_new, [], [AC_MSG_ERROR([No ECC functions found in OpenSSL: please upgrade OpenSSL or rerun with --disable-gost])])
AC_DEFINE_UNQUOTED([USE_GOST], [1], [Define this to enable GOST support.])
;;
esac
AC_ARG_ENABLE(ecdsa, AC_HELP_STRING([--disable-ecdsa], [Disable ECDSA support]))
case "$enable_ecdsa" in
no)
;;
*) dnl default
if test "x$HAVE_SSL" != "xyes"; then
AC_MSG_ERROR([ECDSA enabled, but no SSL support])
fi
AC_CHECK_FUNC(ECDSA_sign, [], [AC_MSG_ERROR([OpenSSL does not support ECDSA: please upgrade OpenSSL or rerun with --disable-ecdsa])])
AC_CHECK_FUNC(SHA384_Init, [], [AC_MSG_ERROR([OpenSSL does not support SHA384: please upgrade OpenSSL or rerun with --disable-ecdsa])])
AC_CHECK_DECLS([NID_X9_62_prime256v1, NID_secp384r1], [], [AC_MSG_ERROR([OpenSSL does not support the ECDSA curves: please upgrade OpenSSL or rerun with --disable-ecdsa])], [AC_INCLUDES_DEFAULT
#include <openssl/evp.h>
])
# we now know we have ECDSA and the required curves.
AC_DEFINE_UNQUOTED([USE_ECDSA], [1], [Define this to enable ECDSA support.])
;;
esac
AC_SUBST(LIBSSL_CPPFLAGS)
AC_SUBST(LIBSSL_LDFLAGS)
AC_SUBST(LIBSSL_LIBS)
CPPFLAGS=$tmp_CPPFLAGS
LDFLAGS=$tmp_LDFLAGS
LIBS=$tmp_LIBS
# add option to disable the evil rpath
ACX_ARG_RPATH
#AC_RUN_IFELSE([AC_LANG_SOURCE(
#[
#int main()
#{
#short one = 1;
#char *cp = (char*)&one;
#if ( *cp == 0 )
#return(0);
#else
#return(1);
#}
#])], [],[
#AC_DEFINE(CONFCHECK_LITTLE_ENDIAN, 1, [system appears to be little-endian])
#],[])
# should define WORDS_BIGENDIAN if the system is big-endian
AC_C_BIGENDIAN
# Checks for header files.
AC_HEADER_STDC
AC_HEADER_STDBOOL
#AC_HEADER_SYS_WAIT
#AC_CHECK_HEADERS([getopt.h fcntl.h stdlib.h string.h strings.h unistd.h])
# do the very minimum - we can always extend this
AC_CHECK_HEADERS([getopt.h stdarg.h openssl/ssl.h netinet/in.h time.h arpa/inet.h netdb.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_HEADERS(sys/param.h sys/mount.h,,,
[AC_INCLUDES_DEFAULT
[
#if HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
]
])
AC_CHECK_HEADER(sys/socket.h,
[
include_sys_socket_h='#include <sys/socket.h>'
AC_DEFINE(HAVE_SYS_SOCKET_H, 1, [define if you have sys/socket.h])
],[
include_sys_socket_h=''
],[AC_INCLUDES_DEFAULT
[
#if HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
]
])
AC_SUBST(include_sys_socket_h)
AC_CHECK_HEADER(inttypes.h,
[
include_inttypes_h='#include <inttypes.h>'
AC_DEFINE(HAVE_INTTYPES_H, 1, [define if you have inttypes.h])
AC_SUBST(ldns_build_config_have_inttypes_h, 1)
],[
include_inttypes_h=''
AC_SUBST(ldns_build_config_have_inttypes_h, 0)
],[AC_INCLUDES_DEFAULT
])
AC_SUBST(include_inttypes_h)
AC_CHECK_HEADER(sys/types.h,
[
include_systypes_h='#include <sys/types.h>'
AC_DEFINE(HAVE_SYS_TYPES_H, 1, [define if you have sys/types.h])
],[
include_systypes_h=''
],[AC_INCLUDES_DEFAULT
])
AC_SUBST(include_systypes_h)
AC_CHECK_HEADER(unistd.h,
[
include_unistd_h='#include <unistd.h>'
AC_DEFINE(HAVE_UNISTD_H, 1, [define if you have unistd.h])
],[
include_unistd_h=''
],[AC_INCLUDES_DEFAULT
])
AC_SUBST(include_unistd_h)
AC_CHECK_SIZEOF(time_t,,[
AC_INCLUDES_DEFAULT
#ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
])
if test x_$with_examples != x_no; then
AC_CHECK_HEADERS([pcap.h],, [AC_INCLUDES_DEFAULT])
AC_CHECK_LIB(pcap, pcap_open_offline, [
AC_DEFINE([HAVE_LIBPCAP], [1], [Define to 1 if you have the `pcap' library (-lpcap).])dnl`
AC_SUBST([LIBPCAP_LIBS], [-lpcap])
], [
AC_MSG_WARN([Can't find pcap library (needed for ldns-dpa, will not build dpa now.)])dnl'
AC_SUBST([LIBPCAP_LIBS], [])
]
)
AC_CHECK_HEADERS([netinet/in_systm.h net/if.h netinet/ip.h netinet/udp.h netinet/igmp.h netinet/if_ether.h netinet/ip6.h net/ethernet.h netinet/ip_compat.h],,, [
AC_INCLUDES_DEFAULT
#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NET_IF_H
#include <net/if.h>
#endif])
fi
ACX_TYPE_SOCKLEN_T
AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
AC_TYPE_INTPTR_T
AC_CHECK_TYPE(in_addr_t, [], [AC_DEFINE([in_addr_t], [uint32_t], [in_addr_t])], [
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#if HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif])
AC_CHECK_TYPE(in_port_t, [], [AC_DEFINE([in_port_t], [uint16_t], [in_port_t])], [
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#if HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif])
ACX_CHECK_SS_FAMILY
AC_FUNC_MALLOC
AC_FUNC_REALLOC
AC_REPLACE_FUNCS(b64_pton)
AC_REPLACE_FUNCS(b64_ntop)
AC_REPLACE_FUNCS(b32_pton)
AC_REPLACE_FUNCS(b32_ntop)
AC_REPLACE_FUNCS(calloc)
AC_REPLACE_FUNCS(timegm)
AC_REPLACE_FUNCS(gmtime_r)
AC_REPLACE_FUNCS(ctime_r)
AC_REPLACE_FUNCS(localtime_r)
AC_REPLACE_FUNCS(isblank)
AC_REPLACE_FUNCS(isascii)
AC_REPLACE_FUNCS(inet_aton)
AC_REPLACE_FUNCS(inet_pton)
AC_REPLACE_FUNCS(inet_ntop)
AC_REPLACE_FUNCS(snprintf)
AC_REPLACE_FUNCS(strlcpy)
AC_REPLACE_FUNCS(memmove)
AC_FUNC_FORK
AC_CHECK_FUNCS([endprotoent endservent sleep random fcntl strtoul bzero memset])
ACX_CHECK_GETADDRINFO_WITH_INCLUDES
if test $ac_cv_func_getaddrinfo = no; then
AC_LIBOBJ([fake-rfc2553])
fi
if test "$USE_WINSOCK" = 1; then
AC_CHECK_TOOL(WINDRES, windres)
fi
ACX_FUNC_IOCTLSOCKET
#AC_SEARCH_LIBS(RSA_new, [crypto])
ACX_CHECK_FORMAT_ATTRIBUTE
ACX_CHECK_UNUSED_ATTRIBUTE
# check OSX deployment target which is needed
if echo $build_os | grep darwin > /dev/null; then
export MACOSX_DEPLOYMENT_TARGET="10.4"
fi
AC_DEFINE([SYSCONFDIR], [sysconfdir], [System configuration dir])
AH_BOTTOM([
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN 1234
#endif
#ifndef BIG_ENDIAN
#define BIG_ENDIAN 4321
#endif
#ifndef BYTE_ORDER
#ifdef WORDS_BIGENDIAN
#define BYTE_ORDER BIG_ENDIAN
#else
#define BYTE_ORDER LITTLE_ENDIAN
#endif /* WORDS_BIGENDIAN */
#endif /* BYTE_ORDER */
#if STDC_HEADERS
#include <stdlib.h>
#include <stddef.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_WINSOCK2_H
#include <winsock2.h>
#endif
#ifdef HAVE_WS2TCPIP_H
#include <ws2tcpip.h>
#endif
]
AHX_CONFIG_W32_FD_SET_T
)
AH_BOTTOM([
#ifdef __cplusplus
extern "C" {
#endif
#ifndef B64_PTON
int ldns_b64_ntop(uint8_t const *src, size_t srclength,
char *target, size_t targsize);
/**
* calculates the size needed to store the result of b64_ntop
*/
/*@unused@*/
static inline size_t ldns_b64_ntop_calculate_size(size_t srcsize)
{
return ((((srcsize + 2) / 3) * 4) + 1);
}
#endif /* !B64_PTON */
#ifndef B64_NTOP
int ldns_b64_pton(char const *src, uint8_t *target, size_t targsize);
/**
* calculates the size needed to store the result of ldns_b64_pton
*/
/*@unused@*/
static inline size_t ldns_b64_pton_calculate_size(size_t srcsize)
{
return (((((srcsize + 3) / 4) * 3)) + 1);
}
#endif /* !B64_NTOP */
#ifndef HAVE_SLEEP
/* use windows sleep, in millisecs, instead */
#define sleep(x) Sleep((x)*1000)
#endif
#ifndef HAVE_RANDOM
#define srandom(x) srand(x)
#define random(x) rand(x)
#endif
#ifndef HAVE_TIMEGM
#include <time.h>
time_t timegm (struct tm *tm);
#endif /* !TIMEGM */
#ifndef HAVE_GMTIME_R
struct tm *gmtime_r(const time_t *timep, struct tm *result);
#endif
#ifndef HAVE_LOCALTIME_R
struct tm *localtime_r(const time_t *timep, struct tm *result);
#endif
#ifndef HAVE_ISBLANK
int isblank(int c);
#endif /* !HAVE_ISBLANK */
#ifndef HAVE_ISASCII
int isascii(int c);
#endif /* !HAVE_ISASCII */
#ifndef HAVE_SNPRINTF
#include <stdarg.h>
int snprintf (char *str, size_t count, const char *fmt, ...);
int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
#endif /* HAVE_SNPRINTF */
#ifndef HAVE_INET_PTON
int inet_pton(int af, const char* src, void* dst);
#endif /* HAVE_INET_PTON */
#ifndef HAVE_INET_NTOP
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
#endif
#ifndef HAVE_INET_ATON
int inet_aton(const char *cp, struct in_addr *addr);
#endif
#ifndef HAVE_MEMMOVE
void *memmove(void *dest, const void *src, size_t n);
#endif
#ifndef HAVE_STRLCPY
size_t strlcpy(char *dst, const char *src, size_t siz);
#endif
#ifdef __cplusplus
}
#endif
#ifndef HAVE_GETADDRINFO
#include "compat/fake-rfc2553.h"
#endif
#ifndef HAVE_STRTOUL
#define strtoul (unsigned long)strtol
#endif
])
if test "x$HAVE_SSL" = "xyes"; then
AC_SUBST(ldns_build_config_have_ssl, 1)
else
AC_SUBST(ldns_build_config_have_ssl, 0)
fi
if test "x$ac_cv_c_format_attribute" = "xyes"; then
AC_SUBST(ldns_build_config_have_attr_format, 1)
else
AC_SUBST(ldns_build_config_have_attr_format, 0)
fi
if test "x$ac_cv_c_unused_attribute" = "xyes"; then
AC_SUBST(ldns_build_config_have_attr_unused, 1)
else
AC_SUBST(ldns_build_config_have_attr_unused, 0)
fi
AC_CONFIG_FILES([Makefile ldns/common.h ldns/net.h ldns/util.h packaging/libldns.pc packaging/ldns-config])
AC_CONFIG_HEADER([ldns/config.h])
AC_OUTPUT
COPY_HEADER_FILES(ldns/, ldns/)
dnl AC_CONFIG_SUBDIRS([drill])

565
contrib/ldns/dname.c Normal file
View file

@ -0,0 +1,565 @@
/*
* dname.c
*
* dname specific rdata implementations
* A dname is a rdf structure with type LDNS_RDF_TYPE_DNAME
* It is not a /real/ type! All function must therefor check
* for LDNS_RDF_TYPE_DNAME.
*
* a Net::DNS like library for C
*
* (c) NLnet Labs, 2004-2006
*
* See the file LICENSE for the license
*/
#include <ldns/config.h>
#include <ldns/ldns.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
ldns_rdf *
ldns_dname_cat_clone(const ldns_rdf *rd1, const ldns_rdf *rd2)
{
ldns_rdf *new;
uint16_t new_size;
uint8_t *buf;
uint16_t left_size;
if (ldns_rdf_get_type(rd1) != LDNS_RDF_TYPE_DNAME ||
ldns_rdf_get_type(rd2) != LDNS_RDF_TYPE_DNAME) {
return NULL;
}
/* remove root label if it is present at the end of the left
* rd, by reducing the size with 1
*/
left_size = ldns_rdf_size(rd1);
if (left_size > 0 &&ldns_rdf_data(rd1)[left_size - 1] == 0) {
left_size--;
}
/* we overwrite the nullbyte of rd1 */
new_size = left_size + ldns_rdf_size(rd2);
buf = LDNS_XMALLOC(uint8_t, new_size);
if (!buf) {
return NULL;
}
/* put the two dname's after each other */
memcpy(buf, ldns_rdf_data(rd1), left_size);
memcpy(buf + left_size, ldns_rdf_data(rd2), ldns_rdf_size(rd2));
new = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, new_size, buf);
LDNS_FREE(buf);
return new;
}
ldns_status
ldns_dname_cat(ldns_rdf *rd1, ldns_rdf *rd2)
{
uint16_t left_size;
uint16_t size;
uint8_t* newd;
if (ldns_rdf_get_type(rd1) != LDNS_RDF_TYPE_DNAME ||
ldns_rdf_get_type(rd2) != LDNS_RDF_TYPE_DNAME) {
return LDNS_STATUS_ERR;
}
/* remove root label if it is present at the end of the left
* rd, by reducing the size with 1
*/
left_size = ldns_rdf_size(rd1);
if (left_size > 0 &&ldns_rdf_data(rd1)[left_size - 1] == 0) {
left_size--;
}
size = left_size + ldns_rdf_size(rd2);
newd = LDNS_XREALLOC(ldns_rdf_data(rd1), uint8_t, size);
if(!newd) {
return LDNS_STATUS_MEM_ERR;
}
ldns_rdf_set_data(rd1, newd);
memcpy(ldns_rdf_data(rd1) + left_size, ldns_rdf_data(rd2),
ldns_rdf_size(rd2));
ldns_rdf_set_size(rd1, size);
return LDNS_STATUS_OK;
}
ldns_rdf *
ldns_dname_reverse(const ldns_rdf *d)
{
ldns_rdf *new;
ldns_rdf *tmp;
ldns_rdf *d_tmp;
ldns_status status;
d_tmp = ldns_rdf_clone(d);
new = ldns_dname_new_frm_str(".");
if(!new)
return NULL;
while(ldns_dname_label_count(d_tmp) > 0) {
tmp = ldns_dname_label(d_tmp, 0);
status = ldns_dname_cat(tmp, new);
if(status != LDNS_STATUS_OK) {
ldns_rdf_deep_free(new);
ldns_rdf_deep_free(d_tmp);
return NULL;
}
ldns_rdf_deep_free(new);
new = tmp;
tmp = ldns_dname_left_chop(d_tmp);
ldns_rdf_deep_free(d_tmp);
d_tmp = tmp;
}
ldns_rdf_deep_free(d_tmp);
return new;
}
ldns_rdf *
ldns_dname_clone_from(const ldns_rdf *d, uint16_t n)
{
uint8_t *data;
uint8_t label_size;
size_t data_size;
if (!d ||
ldns_rdf_get_type(d) != LDNS_RDF_TYPE_DNAME ||
ldns_dname_label_count(d) < n) {
return NULL;
}
data = ldns_rdf_data(d);
data_size = ldns_rdf_size(d);
while (n > 0) {
label_size = data[0] + 1;
data += label_size;
if (data_size < label_size) {
/* this label is very broken */
return NULL;
}
data_size -= label_size;
n--;
}
return ldns_dname_new_frm_data(data_size, data);
}
ldns_rdf *
ldns_dname_left_chop(const ldns_rdf *d)
{
uint8_t label_pos;
ldns_rdf *chop;
if (!d) {
return NULL;
}
if (ldns_rdf_get_type(d) != LDNS_RDF_TYPE_DNAME) {
return NULL;
}
if (ldns_dname_label_count(d) == 0) {
/* root label */
return NULL;
}
/* 05blaat02nl00 */
label_pos = ldns_rdf_data(d)[0];
chop = ldns_dname_new_frm_data(ldns_rdf_size(d) - label_pos - 1,
ldns_rdf_data(d) + label_pos + 1);
return chop;
}
uint8_t
ldns_dname_label_count(const ldns_rdf *r)
{
uint16_t src_pos;
uint16_t len;
uint8_t i;
size_t r_size;
if (!r) {
return 0;
}
i = 0;
src_pos = 0;
r_size = ldns_rdf_size(r);
if (ldns_rdf_get_type(r) != LDNS_RDF_TYPE_DNAME) {
return 0;
} else {
len = ldns_rdf_data(r)[src_pos]; /* start of the label */
/* single root label */
if (1 == r_size) {
return 0;
} else {
while ((len > 0) && src_pos < r_size) {
src_pos++;
src_pos += len;
len = ldns_rdf_data(r)[src_pos];
i++;
}
}
}
return i;
}
ldns_rdf *
ldns_dname_new(uint16_t s, void *d)
{
ldns_rdf *rd;
rd = LDNS_MALLOC(ldns_rdf);
if (!rd) {
return NULL;
}
ldns_rdf_set_size(rd, s);
ldns_rdf_set_type(rd, LDNS_RDF_TYPE_DNAME);
ldns_rdf_set_data(rd, d);
return rd;
}
ldns_rdf *
ldns_dname_new_frm_str(const char *str)
{
return ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, str);
}
ldns_rdf *
ldns_dname_new_frm_data(uint16_t size, const void *data)
{
return ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, size, data);
}
void
ldns_dname2canonical(const ldns_rdf *rd)
{
uint8_t *rdd;
uint16_t i;
if (ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_DNAME) {
return;
}
rdd = (uint8_t*)ldns_rdf_data(rd);
for (i = 0; i < ldns_rdf_size(rd); i++, rdd++) {
*rdd = (uint8_t)LDNS_DNAME_NORMALIZE((int)*rdd);
}
}
bool
ldns_dname_is_subdomain(const ldns_rdf *sub, const ldns_rdf *parent)
{
uint8_t sub_lab;
uint8_t par_lab;
int8_t i, j;
ldns_rdf *tmp_sub = NULL;
ldns_rdf *tmp_par = NULL;
ldns_rdf *sub_clone;
ldns_rdf *parent_clone;
bool result = true;
if (ldns_rdf_get_type(sub) != LDNS_RDF_TYPE_DNAME ||
ldns_rdf_get_type(parent) != LDNS_RDF_TYPE_DNAME ||
ldns_rdf_compare(sub, parent) == 0) {
return false;
}
/* would be nicer if we do not have to clone... */
sub_clone = ldns_dname_clone_from(sub, 0);
parent_clone = ldns_dname_clone_from(parent, 0);
ldns_dname2canonical(sub_clone);
ldns_dname2canonical(parent_clone);
sub_lab = ldns_dname_label_count(sub_clone);
par_lab = ldns_dname_label_count(parent_clone);
/* if sub sits above parent, it cannot be a child/sub domain */
if (sub_lab < par_lab) {
result = false;
} else {
/* check all labels the from the parent labels, from right to left.
* When they /all/ match we have found a subdomain
*/
j = sub_lab - 1; /* we count from zero, thank you */
for (i = par_lab -1; i >= 0; i--) {
tmp_sub = ldns_dname_label(sub_clone, j);
tmp_par = ldns_dname_label(parent_clone, i);
if (!tmp_sub || !tmp_par) {
/* deep free does null check */
ldns_rdf_deep_free(tmp_sub);
ldns_rdf_deep_free(tmp_par);
result = false;
break;
}
if (ldns_rdf_compare(tmp_sub, tmp_par) != 0) {
/* they are not equal */
ldns_rdf_deep_free(tmp_sub);
ldns_rdf_deep_free(tmp_par);
result = false;
break;
}
ldns_rdf_deep_free(tmp_sub);
ldns_rdf_deep_free(tmp_par);
j--;
}
}
ldns_rdf_deep_free(sub_clone);
ldns_rdf_deep_free(parent_clone);
return result;
}
int
ldns_dname_compare(const ldns_rdf *dname1, const ldns_rdf *dname2)
{
size_t lc1, lc2, lc1f, lc2f;
size_t i;
int result = 0;
uint8_t *lp1, *lp2;
/* see RFC4034 for this algorithm */
/* this algorithm assumes the names are normalized to case */
/* only when both are not NULL we can say anything about them */
if (!dname1 && !dname2) {
return 0;
}
if (!dname1 || !dname2) {
return -1;
}
/* asserts must happen later as we are looking in the
* dname, which could be NULL. But this case is handled
* above
*/
assert(ldns_rdf_get_type(dname1) == LDNS_RDF_TYPE_DNAME);
assert(ldns_rdf_get_type(dname2) == LDNS_RDF_TYPE_DNAME);
lc1 = ldns_dname_label_count(dname1);
lc2 = ldns_dname_label_count(dname2);
if (lc1 == 0 && lc2 == 0) {
return 0;
}
if (lc1 == 0) {
return -1;
}
if (lc2 == 0) {
return 1;
}
lc1--;
lc2--;
/* we start at the last label */
while (true) {
/* find the label first */
lc1f = lc1;
lp1 = ldns_rdf_data(dname1);
while (lc1f > 0) {
lp1 += *lp1 + 1;
lc1f--;
}
/* and find the other one */
lc2f = lc2;
lp2 = ldns_rdf_data(dname2);
while (lc2f > 0) {
lp2 += *lp2 + 1;
lc2f--;
}
/* now check the label character for character. */
for (i = 1; i < (size_t)(*lp1 + 1); i++) {
if (i > *lp2) {
/* apparently label 1 is larger */
result = 1;
goto done;
}
if (LDNS_DNAME_NORMALIZE((int) *(lp1 + i)) <
LDNS_DNAME_NORMALIZE((int) *(lp2 + i))) {
result = -1;
goto done;
} else if (LDNS_DNAME_NORMALIZE((int) *(lp1 + i)) >
LDNS_DNAME_NORMALIZE((int) *(lp2 + i))) {
result = 1;
goto done;
}
}
if (*lp1 < *lp2) {
/* apparently label 2 is larger */
result = -1;
goto done;
}
if (lc1 == 0 && lc2 > 0) {
result = -1;
goto done;
} else if (lc1 > 0 && lc2 == 0) {
result = 1;
goto done;
} else if (lc1 == 0 && lc2 == 0) {
result = 0;
goto done;
}
lc1--;
lc2--;
}
done:
return result;
}
int
ldns_dname_is_wildcard(const ldns_rdf* dname)
{
return ( ldns_dname_label_count(dname) > 0 &&
ldns_rdf_data(dname)[0] == 1 &&
ldns_rdf_data(dname)[1] == '*');
}
int
ldns_dname_match_wildcard(const ldns_rdf *dname, const ldns_rdf *wildcard)
{
ldns_rdf *wc_chopped;
int result;
/* check whether it really is a wildcard */
if (ldns_dname_is_wildcard(wildcard)) {
/* ok, so the dname needs to be a subdomain of the wildcard
* without the *
*/
wc_chopped = ldns_dname_left_chop(wildcard);
result = (int) ldns_dname_is_subdomain(dname, wc_chopped);
ldns_rdf_deep_free(wc_chopped);
} else {
result = (ldns_dname_compare(dname, wildcard) == 0);
}
return result;
}
/* nsec test: does prev <= middle < next
* -1 = yes
* 0 = error/can't tell
* 1 = no
*/
int
ldns_dname_interval(const ldns_rdf *prev, const ldns_rdf *middle,
const ldns_rdf *next)
{
int prev_check, next_check;
assert(ldns_rdf_get_type(prev) == LDNS_RDF_TYPE_DNAME);
assert(ldns_rdf_get_type(middle) == LDNS_RDF_TYPE_DNAME);
assert(ldns_rdf_get_type(next) == LDNS_RDF_TYPE_DNAME);
prev_check = ldns_dname_compare(prev, middle);
next_check = ldns_dname_compare(middle, next);
/* <= next. This cannot be the case for nsec, because then we would
* have gotten the nsec of next...
*/
if (next_check == 0) {
return 0;
}
/* <= */
if ((prev_check == -1 || prev_check == 0) &&
/* < */
next_check == -1) {
return -1;
} else {
return 1;
}
}
bool
ldns_dname_str_absolute(const char *dname_str)
{
const char* s;
if(dname_str && strcmp(dname_str, ".") == 0)
return 1;
if(!dname_str || strlen(dname_str) < 2)
return 0;
if(dname_str[strlen(dname_str) - 1] != '.')
return 0;
if(dname_str[strlen(dname_str) - 2] != '\\')
return 1; /* ends in . and no \ before it */
/* so we have the case of ends in . and there is \ before it */
for(s=dname_str; *s; s++) {
if(*s == '\\') {
if(s[1] && s[2] && s[3] /* check length */
&& isdigit(s[1]) && isdigit(s[2]) &&
isdigit(s[3]))
s += 3;
else if(!s[1] || isdigit(s[1])) /* escape of nul,0-9 */
return 0; /* parse error */
else s++; /* another character escaped */
}
else if(!*(s+1) && *s == '.')
return 1; /* trailing dot, unescaped */
}
return 0;
}
ldns_rdf *
ldns_dname_label(const ldns_rdf *rdf, uint8_t labelpos)
{
uint8_t labelcnt;
uint16_t src_pos;
uint16_t len;
ldns_rdf *tmpnew;
size_t s;
uint8_t *data;
if (ldns_rdf_get_type(rdf) != LDNS_RDF_TYPE_DNAME) {
return NULL;
}
labelcnt = 0;
src_pos = 0;
s = ldns_rdf_size(rdf);
len = ldns_rdf_data(rdf)[src_pos]; /* label start */
while ((len > 0) && src_pos < s) {
if (labelcnt == labelpos) {
/* found our label */
data = LDNS_XMALLOC(uint8_t, len + 2);
if (!data) {
return NULL;
}
memcpy(data, ldns_rdf_data(rdf) + src_pos, len + 1);
data[len + 2 - 1] = 0;
tmpnew = ldns_rdf_new( LDNS_RDF_TYPE_DNAME
, len + 2, data);
if (!tmpnew) {
LDNS_FREE(data);
return NULL;
}
return tmpnew;
}
src_pos++;
src_pos += len;
len = ldns_rdf_data(rdf)[src_pos];
labelcnt++;
}
return NULL;
}

1764
contrib/ldns/dnssec.c Normal file

File diff suppressed because it is too large Load diff

1420
contrib/ldns/dnssec_sign.c Normal file

File diff suppressed because it is too large Load diff

2699
contrib/ldns/dnssec_verify.c Normal file

File diff suppressed because it is too large Load diff

1093
contrib/ldns/dnssec_zone.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,105 @@
--------- Drill now is a subdirectory in ldns. To make life easier
--------- we are using ldns' version numbering for drill from now on.
--------- Sadly this means we GO BACKWARDS in the versions
--------- This ChangeLog will not be updated anymore - all changes are
--------- documented in ldns' ChangeLog
1.0-pre3: to be released: drill-team
* Secure tracing works
* Added section about DNSSEC in the manual page
* Allow the class information to be given to do_chase()
* Lint fixes for the code
* Bugzilla was setup for drill
* Bug #97 (drill); -S crash was fixed
* Add -Q (quiet) flag was added. This supresses output from drill.
1.0-pre2: 20 Jun 2005: drill-team
* Second prerelease
* Bugs where fix in the chasing functionality
1.0-pre1: 1 Jun 2005: drill-team
* First drill release based on ldns
* drill's core code is not much more simple, as
all the difficult stuff is moved to ldns.
* Much saner argument parsing
---------- Above Newer drill based on ldns --------------
---------- Below Older drill with it's own DNS handling --------------
0.9.2: Feb 3 2005: drill-team
* Added two more options (borrowed from dig)
--rd, don't set the RD bit in queries
--fail, don't query the next nameserver on SERVFAIL
* Fixed handling of obscure data types
* Handle classes other the 'IN' when making a query
* For people using FreeBSD: drill is now in the ports
(Thanks to Jaap Akkerhuis)
0.9.1: Jan 5 2005: drill-team
* Makefile tweaks
* drill ns . works
* re-check the root in when tracing
* added handling for some lesser known types (including WKS)
0.9: Dec 6 2004: drill-team
* big configure.ac and Makefile.in updates (made more general)
* escapes in names argument and txt and dname data
* gcc 2(.95) support
* packet wire data is now checked for dangerous elements (like
looping compression etc)
* (Multiple) Octal char representation
* Responses can be saved to file
* 'Answers' can be read from file instead of server
* Lots and lots of bugfixes and improvements
0.8.1: Oct 27 2004: Miek
* configure.ac updates
* secure resolving updates (still doesn't work)
* printing additions
- CERT RR supported
- LOC RR support
* All non supported RRs are handled as unknown
* If no namservers found in /etc/resolv.conf
default to 127.0.0.1
* Various bugs fixed
- Close sockets after using them
- Some memory leaks were plugged
0.8: Oct 26 2004: Miek
* Lots of features added. Drill is almost feature complete
* Unknown RR's are supported
* Numerous smaller updates in documentation
* Numerous code cleanups
* Dig is no longer needed to build drill
0.7: Oct 21 2004: Miek
* reworked interal code
* DNSSEC is working, except the secure resolving
* build updates
* more sane options parsing
* more sane argument handling
0.6-alpha: Oct 2004: Jelte
* No log
0.5-alpha: Sept 22 2004: Miek
* most of the DNS stuff is working
* moved to configure
* tested on Linux/FreeBSD
* fully IPV6 capable
* new DNSSEC types supported
* DNSSEC somewhat working
* gcc => 3 is needed for building
0.4-alpha: Sept 9 2004: Miek
* moved to autoconf for building
* lots of various updates
* really a workable program now
0.3-alpha: Sept 6 2004: Miek
* IPv6 support
* automatic secure resolving
* --trace updates
* --chase updates
* more checks

View file

@ -0,0 +1,119 @@
# Standard installation pathnames
# See the file LICENSE for the license
SHELL = @SHELL@
VERSION = @PACKAGE_VERSION@
basesrcdir = $(shell basename `pwd`)
srcdir = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
mandir = @mandir@
includedir = @includedir@
CC = @CC@
CFLAGS = -I. @CFLAGS@
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
INSTALL = $(srcdir)/install-sh -c
INSTALL_PROGRAM = $(INSTALL)
LDNSDIR = @LDNSDIR@
LIBS_STC = @LIBS_STC@
COMPILE = $(CC) $(CPPFLAGS) $(CFLAGS) -I. -I$(srcdir)
LINK = $(CC) $(CFLAGS) $(LDFLAGS)
LINT = splint
LINTFLAGS=+quiet -weak -warnposix -unrecog -Din_addr_t=uint32_t -Du_int=unsigned -Du_char=uint8_t -preproc -Drlimit=rlimit64 -D__gnuc_va_list=va_list
#-Dglob64=glob -Dglobfree64=globfree
# compat with openssl linux edition.
LINTFLAGS+="-DBN_ULONG=unsigned long" -Dkrb5_int32=int "-Dkrb5_ui_4=unsigned int" -DPQ_64BIT=uint64_t -DRC4_INT=unsigned -fixedformalarray -D"ENGINE=unsigned" -D"RSA=unsigned" -D"DSA=unsigned" -D"EVP_PKEY=unsigned" -D"EVP_MD=unsigned" -D"SSL=unsigned" -D"SSL_CTX=unsigned" -D"X509=unsigned" -D"RC4_KEY=unsigned" -D"EVP_MD_CTX=unsigned"
# compat with NetBSD
ifeq "$(shell uname)" "NetBSD"
LINTFLAGS+="-D__RENAME(x)=" -D_NETINET_IN_H_
endif
# compat with OpenBSD
LINTFLAGS+="-Dsigset_t=long"
# FreeBSD8
LINTFLAGS+="-D__uint16_t=uint16_t"
LINTFLAGS+=-D__signed__=signed "-D__packed=" "-D__aligned(x)="
# Ubuntu Linux 11.04
LINTFLAGS+="-D__u16=struct __u16" "-D__u32=struct __u32" "-D__u64=struct __u64"
OBJ=drill.o drill_util.o error.o root.o work.o chasetrace.o dnssec.o securetrace.o
SRC=$(OBJ:.o=.c)
HEADER=drill.h $(srcdir)/drill_util.h
.PHONY: all clean realclean docclean doc release tags install all-static
all: drill
all-static: drill-stc
tags:
ctags *.[ch]
drill: $(OBJ)
$(LINK) -o drill $(OBJ) $(LIBS)
drill-stc: $(OBJ)
$(LINK) -o drill $(OBJ) $(LIBS_STC)
## implicit rule
%.o: $(srcdir)/%.c
$(COMPILE) -c $<
clean:
rm -f ${OBJ}
rm -f drill
rm -f *core
rm -f config.h.in~
rm -f config.log
rm -f config.guess
rm -f config.status
docclean:
rm -rf doxydoc
distclean: clean docclean
rm -f config.h
rm -f drill.h
realclean: clean docclean
rm -f tags
rm -f config.log
rm -f config.sub
rm -f ltmain.sh
rm -f config.status
rm -rf autom4te.cache
rm -f config.h
rm -f config.h.in
rm -f drill.h
rm -f configure
rm -f Makefile
rm -f aclocal.m4
doc:
doxygen drill.doxygen
install: all
$(INSTALL) -d $(DESTDIR)$(bindir)
$(INSTALL) drill $(DESTDIR)$(bindir)/drill
$(INSTALL) -m 644 $(srcdir)/drill.1 $(DESTDIR)$(mandir)/man1/drill.1
uninstall:
@echo
rm -f -- $(DESTDIR)$(bindir)/drill
rm -f -- $(DESTDIR)$(mandir)/man1/drill.1
rmdir -p $(DESTDIR)$(bindir)
rmdir -p $(DESTDIR)$(mandir)/man1
@echo
lint:
@for i in $(SRC) ; do \
$(LINT) $(LINTFLAGS) $(CPPFLAGS) -I$(srcdir) $(srcdir)/$$i ; \
if [ $$? -ne 0 ] ; then exit 1 ; fi ; \
done
confclean: clean
rm -rf config.log config.status config.h Makefile

12
contrib/ldns/drill/README Normal file
View file

@ -0,0 +1,12 @@
QUICK INSTALL GUIDE
drill is a subdirectory in ldns.
To compile drill you need:
autoreconf && ./configure && make
If ldns is installed in a different location, use --with-ldns=directory
See also ./configure --help
In the first case you must run drill as:
LD_LIBRARY_PATH=../.libs ./drill <options>

View file

@ -0,0 +1,25 @@
REGRESSIONS
This version of drill is based on ldns and as such some things
are slightly changed. This file documents the changes.
o When tracing (-T option) we use the local resolver (as specified
in /etc/resolv.conf) to lookup names. This increases the speed
dramatically, but you obviously need to be able to reach a recursive
server/cache.
Previously drill would try to resolve the names by itself.
o Printing of DSs after DNSKEY records. Because we don't parse our
own packets anymore, we cannot print the DS directly after the DNSKEY
record. The DSs are now printed AFTER the packet.
o The long options are removed.
o The chase function has a different output, and will be subject to change
in the near future.
o The useless (for jokes only) -I option was dropped.
FIXED:
o the argument parsing is much smarter, the order doesn't matter (much)
anymore

View file

@ -0,0 +1,395 @@
/*
* chasetrace.c
* Where all the hard work concerning chasing
* and tracing is done
* (c) 2005, 2006 NLnet Labs
*
* See the file LICENSE for the license
*
*/
#include "drill.h"
#include <ldns/ldns.h>
/**
* trace down from the root to name
*/
/* same naive method as in drill0.9
* We resolver _ALL_ the names, which is ofcourse not needed
* We _do_ use the local resolver to do that, so it still is
* fast, but it can be made to run much faster
*/
ldns_pkt *
do_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
ldns_rr_class c)
{
ldns_resolver *res;
ldns_pkt *p;
ldns_rr_list *new_nss_a;
ldns_rr_list *new_nss_aaaa;
ldns_rr_list *final_answer;
ldns_rr_list *new_nss;
ldns_rr_list *ns_addr;
uint16_t loop_count;
ldns_rdf *pop;
ldns_status status;
size_t i;
loop_count = 0;
new_nss_a = NULL;
new_nss_aaaa = NULL;
new_nss = NULL;
ns_addr = NULL;
final_answer = NULL;
p = ldns_pkt_new();
res = ldns_resolver_new();
if (!p || !res) {
error("Memory allocation failed");
return NULL;
}
/* transfer some properties of local_res to res,
* because they were given on the commandline */
ldns_resolver_set_ip6(res,
ldns_resolver_ip6(local_res));
ldns_resolver_set_port(res,
ldns_resolver_port(local_res));
ldns_resolver_set_debug(res,
ldns_resolver_debug(local_res));
ldns_resolver_set_dnssec(res,
ldns_resolver_dnssec(local_res));
ldns_resolver_set_fail(res,
ldns_resolver_fail(local_res));
ldns_resolver_set_usevc(res,
ldns_resolver_usevc(local_res));
ldns_resolver_set_random(res,
ldns_resolver_random(local_res));
ldns_resolver_set_recursive(res, false);
/* setup the root nameserver in the new resolver */
status = ldns_resolver_push_nameserver_rr_list(res, global_dns_root);
if (status != LDNS_STATUS_OK) {
fprintf(stderr, "Error adding root servers to resolver: %s\n", ldns_get_errorstr_by_id(status));
ldns_rr_list_print(stdout, global_dns_root);
return NULL;
}
/* this must be a real query to local_res */
status = ldns_resolver_send(&p, res, ldns_dname_new_frm_str("."), LDNS_RR_TYPE_NS, c, 0);
/* p can still be NULL */
if (ldns_pkt_empty(p)) {
warning("No root server information received");
}
if (status == LDNS_STATUS_OK) {
if (!ldns_pkt_empty(p)) {
drill_pkt_print(stdout, local_res, p);
}
} else {
error("cannot use local resolver");
return NULL;
}
status = ldns_resolver_send(&p, res, name, t, c, 0);
while(status == LDNS_STATUS_OK &&
ldns_pkt_reply_type(p) == LDNS_PACKET_REFERRAL) {
if (!p) {
/* some error occurred, bail out */
return NULL;
}
new_nss_a = ldns_pkt_rr_list_by_type(p,
LDNS_RR_TYPE_A, LDNS_SECTION_ADDITIONAL);
new_nss_aaaa = ldns_pkt_rr_list_by_type(p,
LDNS_RR_TYPE_AAAA, LDNS_SECTION_ADDITIONAL);
new_nss = ldns_pkt_rr_list_by_type(p,
LDNS_RR_TYPE_NS, LDNS_SECTION_AUTHORITY);
if (verbosity != -1) {
ldns_rr_list_print(stdout, new_nss);
}
/* checks itself for verbosity */
drill_pkt_print_footer(stdout, local_res, p);
/* remove the old nameserver from the resolver */
while((pop = ldns_resolver_pop_nameserver(res))) { /* do it */ }
/* also check for new_nss emptyness */
if (!new_nss_aaaa && !new_nss_a) {
/*
* no nameserver found!!!
* try to resolve the names we do got
*/
for(i = 0; i < ldns_rr_list_rr_count(new_nss); i++) {
/* get the name of the nameserver */
pop = ldns_rr_rdf(ldns_rr_list_rr(new_nss, i), 0);
if (!pop) {
break;
}
ldns_rr_list_print(stdout, new_nss);
ldns_rdf_print(stdout, pop);
/* retrieve it's addresses */
ns_addr = ldns_rr_list_cat_clone(ns_addr,
ldns_get_rr_list_addr_by_name(local_res, pop, c, 0));
}
if (ns_addr) {
if (ldns_resolver_push_nameserver_rr_list(res, ns_addr) !=
LDNS_STATUS_OK) {
error("Error adding new nameservers");
ldns_pkt_free(p);
return NULL;
}
ldns_rr_list_free(ns_addr);
} else {
ldns_rr_list_print(stdout, ns_addr);
error("Could not find the nameserver ip addr; abort");
ldns_pkt_free(p);
return NULL;
}
}
/* add the new ones */
if (new_nss_aaaa) {
if (ldns_resolver_push_nameserver_rr_list(res, new_nss_aaaa) !=
LDNS_STATUS_OK) {
error("adding new nameservers");
ldns_pkt_free(p);
return NULL;
}
}
if (new_nss_a) {
if (ldns_resolver_push_nameserver_rr_list(res, new_nss_a) !=
LDNS_STATUS_OK) {
error("adding new nameservers");
ldns_pkt_free(p);
return NULL;
}
}
if (loop_count++ > 20) {
/* unlikely that we are doing something usefull */
error("Looks like we are looping");
ldns_pkt_free(p);
return NULL;
}
status = ldns_resolver_send(&p, res, name, t, c, 0);
new_nss_aaaa = NULL;
new_nss_a = NULL;
ns_addr = NULL;
}
status = ldns_resolver_send(&p, res, name, t, c, 0);
if (!p) {
return NULL;
}
new_nss = ldns_pkt_authority(p);
final_answer = ldns_pkt_answer(p);
if (verbosity != -1) {
ldns_rr_list_print(stdout, final_answer);
ldns_rr_list_print(stdout, new_nss);
}
drill_pkt_print_footer(stdout, local_res, p);
ldns_pkt_free(p);
return NULL;
}
/**
* Chase the given rr to a known and trusted key
*
* Based on drill 0.9
*
* the last argument prev_key_list, if not null, and type == DS, then the ds
* rr list we have must all be a ds for the keys in this list
*/
#ifdef HAVE_SSL
ldns_status
do_chase(ldns_resolver *res,
ldns_rdf *name,
ldns_rr_type type,
ldns_rr_class c,
ldns_rr_list *trusted_keys,
ldns_pkt *pkt_o,
uint16_t qflags,
ldns_rr_list * ATTR_UNUSED(prev_key_list),
int verbosity)
{
ldns_rr_list *rrset = NULL;
ldns_status result;
ldns_rr *orig_rr = NULL;
/*
ldns_rr_list *sigs;
ldns_rr *cur_sig;
uint16_t sig_i;
ldns_rr_list *keys;
*/
ldns_pkt *pkt;
ldns_status tree_result;
ldns_dnssec_data_chain *chain;
ldns_dnssec_trust_tree *tree;
const ldns_rr_descriptor *descriptor;
descriptor = ldns_rr_descript(type);
ldns_dname2canonical(name);
pkt = ldns_pkt_clone(pkt_o);
if (!name) {
mesg("No name to chase");
ldns_pkt_free(pkt);
return LDNS_STATUS_EMPTY_LABEL;
}
if (verbosity != -1) {
printf(";; Chasing: ");
ldns_rdf_print(stdout, name);
if (descriptor && descriptor->_name) {
printf(" %s\n", descriptor->_name);
} else {
printf(" type %d\n", type);
}
}
if (!trusted_keys || ldns_rr_list_rr_count(trusted_keys) < 1) {
warning("No trusted keys specified");
}
if (pkt) {
rrset = ldns_pkt_rr_list_by_name_and_type(pkt,
name,
type,
LDNS_SECTION_ANSWER
);
if (!rrset) {
/* nothing in answer, try authority */
rrset = ldns_pkt_rr_list_by_name_and_type(pkt,
name,
type,
LDNS_SECTION_AUTHORITY
);
}
/* answer might be a cname, chase that first, then chase
cname target? (TODO) */
if (!rrset) {
rrset = ldns_pkt_rr_list_by_name_and_type(pkt,
name,
LDNS_RR_TYPE_CNAME,
LDNS_SECTION_ANSWER
);
if (!rrset) {
/* nothing in answer, try authority */
rrset = ldns_pkt_rr_list_by_name_and_type(pkt,
name,
LDNS_RR_TYPE_CNAME,
LDNS_SECTION_AUTHORITY
);
}
}
} else {
/* no packet? */
if (verbosity >= 0) {
fprintf(stderr, "%s", ldns_get_errorstr_by_id(LDNS_STATUS_MEM_ERR));
fprintf(stderr, "\n");
}
return LDNS_STATUS_MEM_ERR;
}
if (!rrset) {
/* not found in original packet, try again */
ldns_pkt_free(pkt);
pkt = NULL;
pkt = ldns_resolver_query(res, name, type, c, qflags);
if (!pkt) {
if (verbosity >= 0) {
fprintf(stderr, "%s", ldns_get_errorstr_by_id(LDNS_STATUS_NETWORK_ERR));
fprintf(stderr, "\n");
}
return LDNS_STATUS_NETWORK_ERR;
}
if (verbosity >= 5) {
ldns_pkt_print(stdout, pkt);
}
rrset = ldns_pkt_rr_list_by_name_and_type(pkt,
name,
type,
LDNS_SECTION_ANSWER
);
}
orig_rr = ldns_rr_new();
/* if the answer had no answer section, we need to construct our own rr (for instance if
* the rr qe asked for doesn't exist. This rr will be destroyed when the chain is freed */
if (ldns_pkt_ancount(pkt) < 1) {
ldns_rr_set_type(orig_rr, type);
ldns_rr_set_owner(orig_rr, ldns_rdf_clone(name));
chain = ldns_dnssec_build_data_chain(res, qflags, rrset, pkt, ldns_rr_clone(orig_rr));
} else {
/* chase the first answer */
chain = ldns_dnssec_build_data_chain(res, qflags, rrset, pkt, NULL);
}
if (verbosity >= 4) {
printf("\n\nDNSSEC Data Chain:\n");
ldns_dnssec_data_chain_print(stdout, chain);
}
result = LDNS_STATUS_OK;
tree = ldns_dnssec_derive_trust_tree(chain, NULL);
if (verbosity >= 2) {
printf("\n\nDNSSEC Trust tree:\n");
ldns_dnssec_trust_tree_print(stdout, tree, 0, true);
}
if (ldns_rr_list_rr_count(trusted_keys) > 0) {
tree_result = ldns_dnssec_trust_tree_contains_keys(tree, trusted_keys);
if (tree_result == LDNS_STATUS_DNSSEC_EXISTENCE_DENIED) {
if (verbosity >= 1) {
printf("Existence denied or verifiably insecure\n");
}
result = LDNS_STATUS_OK;
} else if (tree_result != LDNS_STATUS_OK) {
if (verbosity >= 1) {
printf("No trusted keys found in tree: first error was: %s\n", ldns_get_errorstr_by_id(tree_result));
}
result = tree_result;
}
} else {
if (verbosity >= 0) {
printf("You have not provided any trusted keys.\n");
}
}
ldns_rr_free(orig_rr);
ldns_dnssec_trust_tree_free(tree);
ldns_dnssec_data_chain_deep_free(chain);
ldns_rr_list_deep_free(rrset);
ldns_pkt_free(pkt);
/* ldns_rr_free(orig_rr);*/
return result;
}
#endif /* HAVE_SSL */

View file

@ -0,0 +1,293 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H
/* Define to 1 if you have the <assert.h> header file. */
#undef HAVE_ASSERT_H
/* Define to 1 if you have the <ctype.h> header file. */
#undef HAVE_CTYPE_H
/* Whether getaddrinfo is available */
#undef HAVE_GETADDRINFO
/* Define to 1 if you have the <getopt.h> header file. */
#undef HAVE_GETOPT_H
/* If you have HMAC_CTX_init */
#undef HAVE_HMAC_CTX_INIT
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `isblank' function. */
#undef HAVE_ISBLANK
/* Define to 1 if you have the `ldns' library (-lldns). */
#undef HAVE_LIBLDNS
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <netinet/if_ether.h> header file. */
#undef HAVE_NETINET_IF_ETHER_H
/* Define to 1 if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
/* Define to 1 if you have the <netinet/in_systm.h> header file. */
#undef HAVE_NETINET_IN_SYSTM_H
/* Define to 1 if you have the <netinet/ip6.h> header file. */
#undef HAVE_NETINET_IP6_H
/* Define to 1 if you have the <netinet/ip.h> header file. */
#undef HAVE_NETINET_IP_H
/* Define to 1 if you have the <netinet/udp.h> header file. */
#undef HAVE_NETINET_UDP_H
/* Define to 1 if you have the <net/if.h> header file. */
#undef HAVE_NET_IF_H
/* Define to 1 if you have the <openssl/err.h> header file. */
#undef HAVE_OPENSSL_ERR_H
/* Define to 1 if you have the <openssl/rand.h> header file. */
#undef HAVE_OPENSSL_RAND_H
/* Define to 1 if you have the <openssl/ssl.h> header file. */
#undef HAVE_OPENSSL_SSL_H
/* Define if you have the SSL libraries installed. */
#undef HAVE_SSL
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdio.h> header file. */
#undef HAVE_STDIO_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/mount.h> header file. */
#undef HAVE_SYS_MOUNT_H
/* Define to 1 if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define to 1 if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
/* Define to 1 if you have the <sys/socket.h> header file. */
#undef HAVE_SYS_SOCKET_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <time.h> header file. */
#undef HAVE_TIME_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the <winsock2.h> header file. */
#undef HAVE_WINSOCK2_H
/* Define to 1 if you have the <ws2tcpip.h> header file. */
#undef HAVE_WS2TCPIP_H
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# undef _ALL_SOURCE
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# undef _GNU_SOURCE
#endif
/* Enable threading extensions on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# undef _POSIX_PTHREAD_SEMANTICS
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# undef _TANDEM_SOURCE
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# undef __EXTENSIONS__
#endif
/* Whether the windows socket API is used */
#undef USE_WINSOCK
/* the version of the windows API enabled */
#undef WINVER
/* Define to 1 if on MINIX. */
#undef _MINIX
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
#undef _POSIX_1_SOURCE
/* Define to 1 if you need to in order for `stat' and other things to work. */
#undef _POSIX_SOURCE
/* in_addr_t */
#undef in_addr_t
/* in_port_t */
#undef in_port_t
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#undef inline
#endif
/* Define to `short' if <sys/types.h> does not define. */
#undef int16_t
/* Define to `int' if <sys/types.h> does not define. */
#undef int32_t
/* Define to `long long' if <sys/types.h> does not define. */
#undef int64_t
/* Define to `char' if <sys/types.h> does not define. */
#undef int8_t
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t
/* Define to 'int' if not defined */
#undef socklen_t
/* Define to `int' if <sys/types.h> does not define. */
#undef ssize_t
/* Define to `unsigned short' if <sys/types.h> does not define. */
#undef uint16_t
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef uint32_t
/* Define to `unsigned long long' if <sys/types.h> does not define. */
#undef uint64_t
/* Define to `unsigned char' if <sys/types.h> does not define. */
#undef uint8_t
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#if STDC_HEADERS
#include <stdlib.h>
#include <stddef.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_NETINET_UDP_H
#include <netinet/udp.h>
#endif
#ifdef HAVE_TIME_H
#include <time.h>
#endif
#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
#endif
#ifdef HAVE_NETINET_IP_H
#include <netinet/ip.h>
#endif
#ifdef HAVE_NET_IF_H
#include <net/if.h>
#endif
#ifdef HAVE_NETINET_IF_ETHER_H
#include <netinet/if_ether.h>
#endif
#ifdef HAVE_WINSOCK2_H
#define USE_WINSOCK 1
#include <winsock2.h>
#endif
#ifdef HAVE_WS2TCPIP_H
#include <ws2tcpip.h>
#endif
extern char *optarg;
extern int optind, opterr;
#ifndef EXIT_FAILURE
#define EXIT_FAILURE 1
#endif
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#endif
#ifdef S_SPLINT_S
#define FD_ZERO(a) /* a */
#define FD_SET(a,b) /* a, b */
#endif

6678
contrib/ldns/drill/configure vendored Executable file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,259 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.56)
AC_INIT(ldns, 1.6.13, libdns@nlnetlabs.nl,libdns)
AC_CONFIG_SRCDIR([drill.c])
sinclude(../acx_nlnetlabs.m4)
OURCPPFLAGS=''
CPPFLAGS=${CPPFLAGS:-${OURCPPFLAGS}}
OURCFLAGS='-g'
CFLAGS=${CFLAGS:-${OURCFLAGS}}
AC_DEFINE(WINVER, 0x0502, [the version of the windows API enabled])
AC_AIX
# Checks for programs.
AC_PROG_CC
AC_PROG_MAKE_SET
AC_CHECK_PROGS(libtool, [glibtool libtool15 libtool], [../libtool])
# add option to disable the evil rpath
dnl Check whether to use rpath or not
AC_ARG_ENABLE(rpath,
[ --disable-rpath disable hardcoded rpath (default=enabled)],
enable_rpath=$enableval, enable_rpath=yes)
if test "x$enable_rpath" = xyes; then
RPATH_VAL="-Wl,-rpath=\${libdir}"
fi
ACX_CHECK_COMPILER_FLAG(std=c99, [C99FLAG="-std=c99"])
ACX_CHECK_COMPILER_FLAG(xc99, [C99FLAG="-xc99"])
AC_TYPE_SIZE_T
ACX_CHECK_COMPILER_FLAG(O2, [CFLAGS="$CFLAGS -O2"])
ACX_CHECK_COMPILER_FLAG_NEEDED($C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600,
[
#include "confdefs.h"
#include <stdlib.h>
#include <ctype.h>
#include <sys/time.h>
#ifdef HAVE_TIME_H
#include <time.h>
#endif
#include <unistd.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
int test() {
int a;
char **opts = NULL;
struct timeval tv;
char *t;
time_t time = 0;
char *buf = NULL;
t = ctime_r(&time, buf);
tv.tv_usec = 10;
srandom(32);
a = getopt(2, opts, "a");
a = isascii(32);
return a;
}
], [CFLAGS="$CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600"])
ACX_CHECK_COMPILER_FLAG_NEEDED($C99FLAG, [#include <stdbool.h>], [CFLAGS="$CFLAGS $C99FLAG"])
AC_C_INLINE
AC_CHECK_TYPE(int8_t, char)
AC_CHECK_TYPE(int16_t, short)
AC_CHECK_TYPE(int32_t, int)
AC_CHECK_TYPE(int64_t, long long)
AC_CHECK_TYPE(uint8_t, unsigned char)
AC_CHECK_TYPE(uint16_t, unsigned short)
AC_CHECK_TYPE(uint32_t, unsigned int)
AC_CHECK_TYPE(uint64_t, unsigned long long)
AC_CHECK_TYPE(ssize_t, int)
AC_CHECK_HEADERS([sys/types.h getopt.h stdlib.h stdio.h assert.h netinet/in.h ctype.h time.h arpa/inet.h sys/time.h sys/socket.h sys/select.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_HEADERS([netinet/in_systm.h net/if.h netinet/ip.h netinet/udp.h netinet/if_ether.h netinet/ip6.h],,, [
AC_INCLUDES_DEFAULT
#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NET_IF_H
#include <net/if.h>
#endif])
# MinGW32 tests
AC_CHECK_HEADERS([winsock2.h ws2tcpip.h],,, [AC_INCLUDES_DEFAULT])
ACX_TYPE_SOCKLEN_T
AC_CHECK_HEADERS([sys/param.h sys/mount.h],,,
[AC_INCLUDES_DEFAULT]
[
[
#if HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
]
])
AC_CHECK_TYPE(in_addr_t, [], [AC_DEFINE([in_addr_t], [uint32_t], [in_addr_t])], [
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#if HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif])
AC_CHECK_TYPE(in_port_t, [], [AC_DEFINE([in_port_t], [uint16_t], [in_port_t])], [
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#if HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif])
# check to see if libraries are needed for these functions.
AC_SEARCH_LIBS(socket, socket)
AC_SEARCH_LIBS([inet_pton], [nsl])
ACX_WITH_SSL_OPTIONAL
ACX_CHECK_GETADDRINFO_WITH_INCLUDES
LIBS_STC="$LIBS"
AC_SUBST(LIBS_STC)
# check for ldns
AC_ARG_WITH(ldns,
AC_HELP_STRING([--with-ldns=PATH specify prefix of path of ldns library to use])
,
[
specialldnsdir="$withval"
CPPFLAGS="$CPPFLAGS -I$withval/include"
LDFLAGS="-L$withval -L$withval/lib $LDFLAGS"
LDNSDIR="$withval"
LIBS="-lldns $LIBS"
LIBS_STC="$withval/lib/libldns.a $LIBS_STC"
]
)
#AC_CHECK_HEADER(ldns/ldns.h,, [
# AC_MSG_ERROR([Can't find ldns headers (make copy-headers in devel source.)])
# ], [AC_INCLUDES_DEFAULT]
#)
AC_CHECK_FUNCS(isblank)
# check for ldns development source tree
AC_MSG_CHECKING([for ldns devel source])
ldns_dev_dir=..
if test -f $ldns_dev_dir/ldns/util.h && \
grep LDNS_VERSION $ldns_dev_dir/ldns/util.h >/dev/null; then
ldns_version=`grep LDNS_VERSION $ldns_dev_dir/ldns/util.h | sed -e 's/^.*"\(.*\)".*$/\1/'`
AC_MSG_RESULT([using $ldns_dev_dir with $ldns_version])
CPPFLAGS="$CPPFLAGS -I$ldns_dev_dir/include"
LDFLAGS="-L$ldns_dev_dir -L$ldns_dev_dir/lib $LDFLAGS"
LIBS="-lldns $LIBS"
AC_DEFINE(HAVE_LIBLDNS, 1, [If the ldns library is available.])
LDNSDIR="$ldns_dev_dir"
LIBS_STC="$ldns_dev_dir/lib/libldns.a $LIBS_STC"
else
AC_MSG_RESULT([no])
AC_CHECK_LIB(ldns, ldns_rr_new, , [
AC_MSG_ERROR([Can't find ldns library])
]
)
fi
AC_SUBST(LDNSDIR)
AH_BOTTOM([
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#if STDC_HEADERS
#include <stdlib.h>
#include <stddef.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_NETINET_UDP_H
#include <netinet/udp.h>
#endif
#ifdef HAVE_TIME_H
#include <time.h>
#endif
#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
#endif
#ifdef HAVE_NETINET_IP_H
#include <netinet/ip.h>
#endif
#ifdef HAVE_NET_IF_H
#include <net/if.h>
#endif
#ifdef HAVE_NETINET_IF_ETHER_H
#include <netinet/if_ether.h>
#endif
#ifdef HAVE_WINSOCK2_H
#define USE_WINSOCK 1
#include <winsock2.h>
#endif
#ifdef HAVE_WS2TCPIP_H
#include <ws2tcpip.h>
#endif
extern char *optarg;
extern int optind, opterr;
#ifndef EXIT_FAILURE
#define EXIT_FAILURE 1
#endif
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#endif
#ifdef S_SPLINT_S
#define FD_ZERO(a) /* a */
#define FD_SET(a,b) /* a, b */
#endif
])
AC_CONFIG_FILES([Makefile])
AC_CONFIG_HEADER([config.h])
AC_OUTPUT

473
contrib/ldns/drill/dnssec.c Normal file
View file

@ -0,0 +1,473 @@
/*
* dnssec.c
* Some DNSSEC helper function are defined here
* and tracing is done
* (c) 2005 NLnet Labs
*
* See the file LICENSE for the license
*
*/
#include "drill.h"
#include <ldns/ldns.h>
/* get rr_type from a server from a server */
ldns_rr_list *
get_rr(ldns_resolver *res, ldns_rdf *zname, ldns_rr_type t, ldns_rr_class c)
{
/* query, retrieve, extract and return */
ldns_pkt *p;
ldns_rr_list *found;
p = ldns_pkt_new();
found = NULL;
if (ldns_resolver_send(&p, res, zname, t, c, 0) != LDNS_STATUS_OK) {
/* oops */
return NULL;
} else {
found = ldns_pkt_rr_list_by_type(p, t, LDNS_SECTION_ANY_NOQUESTION);
}
return found;
}
void
drill_pkt_print(FILE *fd, ldns_resolver *r, ldns_pkt *p)
{
ldns_rr_list *new_nss;
ldns_rr_list *hostnames;
if (verbosity < 5) {
return;
}
hostnames = ldns_get_rr_list_name_by_addr(r, ldns_pkt_answerfrom(p), 0, 0);
new_nss = ldns_pkt_rr_list_by_type(p,
LDNS_RR_TYPE_NS, LDNS_SECTION_ANSWER);
ldns_rr_list_print(fd, new_nss);
/* new_nss can be empty.... */
fprintf(fd, ";; Received %d bytes from %s#%d(",
(int) ldns_pkt_size(p),
ldns_rdf2str(ldns_pkt_answerfrom(p)),
(int) ldns_resolver_port(r));
/* if we can resolve this print it, other print the ip again */
if (hostnames) {
ldns_rdf_print(fd,
ldns_rr_rdf(ldns_rr_list_rr(hostnames, 0), 0));
ldns_rr_list_deep_free(hostnames);
} else {
fprintf(fd, "%s", ldns_rdf2str(ldns_pkt_answerfrom(p)));
}
fprintf(fd, ") in %u ms\n\n", (unsigned int)ldns_pkt_querytime(p));
}
void
drill_pkt_print_footer(FILE *fd, ldns_resolver *r, ldns_pkt *p)
{
ldns_rr_list *hostnames;
if (verbosity < 5) {
return;
}
hostnames = ldns_get_rr_list_name_by_addr(r, ldns_pkt_answerfrom(p), 0, 0);
fprintf(fd, ";; Received %d bytes from %s#%d(",
(int) ldns_pkt_size(p),
ldns_rdf2str(ldns_pkt_answerfrom(p)),
(int) ldns_resolver_port(r));
/* if we can resolve this print it, other print the ip again */
if (hostnames) {
ldns_rdf_print(fd,
ldns_rr_rdf(ldns_rr_list_rr(hostnames, 0), 0));
ldns_rr_list_deep_free(hostnames);
} else {
fprintf(fd, "%s", ldns_rdf2str(ldns_pkt_answerfrom(p)));
}
fprintf(fd, ") in %u ms\n\n", (unsigned int)ldns_pkt_querytime(p));
}
/*
* generic function to get some RRset from a nameserver
* and possible some signatures too (that would be the day...)
*/
ldns_pkt_type
get_dnssec_rr(ldns_pkt *p, ldns_rdf *name, ldns_rr_type t,
ldns_rr_list **rrlist, ldns_rr_list **sig)
{
ldns_pkt_type pt = LDNS_PACKET_UNKNOWN;
ldns_rr_list *rr = NULL;
ldns_rr_list *sigs = NULL;
size_t i;
if (!p) {
if (rrlist) {
*rrlist = NULL;
}
return LDNS_PACKET_UNKNOWN;
}
pt = ldns_pkt_reply_type(p);
if (name) {
rr = ldns_pkt_rr_list_by_name_and_type(p, name, t, LDNS_SECTION_ANSWER);
if (!rr) {
rr = ldns_pkt_rr_list_by_name_and_type(p, name, t, LDNS_SECTION_AUTHORITY);
}
sigs = ldns_pkt_rr_list_by_name_and_type(p, name, LDNS_RR_TYPE_RRSIG,
LDNS_SECTION_ANSWER);
if (!sigs) {
sigs = ldns_pkt_rr_list_by_name_and_type(p, name, LDNS_RR_TYPE_RRSIG,
LDNS_SECTION_AUTHORITY);
}
} else {
/* A DS-referral - get the DS records if they are there */
rr = ldns_pkt_rr_list_by_type(p, t, LDNS_SECTION_AUTHORITY);
sigs = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_RRSIG,
LDNS_SECTION_AUTHORITY);
}
if (sig) {
*sig = ldns_rr_list_new();
for (i = 0; i < ldns_rr_list_rr_count(sigs); i++) {
/* only add the sigs that cover this type */
if (ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(ldns_rr_list_rr(sigs, i))) ==
t) {
ldns_rr_list_push_rr(*sig, ldns_rr_clone(ldns_rr_list_rr(sigs, i)));
}
}
}
ldns_rr_list_deep_free(sigs);
if (rrlist) {
*rrlist = rr;
}
if (pt == LDNS_PACKET_NXDOMAIN || pt == LDNS_PACKET_NODATA) {
return pt;
} else {
return LDNS_PACKET_ANSWER;
}
}
ldns_status
ldns_verify_denial(ldns_pkt *pkt, ldns_rdf *name, ldns_rr_type type, ldns_rr_list **nsec_rrs, ldns_rr_list **nsec_rr_sigs)
{
uint16_t nsec_i;
ldns_rr_list *nsecs;
ldns_status result;
if (verbosity >= 5) {
printf("VERIFY DENIAL FROM:\n");
ldns_pkt_print(stdout, pkt);
}
result = LDNS_STATUS_CRYPTO_NO_RRSIG;
/* Try to see if there are NSECS in the packet */
nsecs = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_NSEC, LDNS_SECTION_ANY_NOQUESTION);
if (nsecs) {
for (nsec_i = 0; nsec_i < ldns_rr_list_rr_count(nsecs); nsec_i++) {
/* there are four options:
* - name equals ownername and is covered by the type bitmap
* - name equals ownername but is not covered by the type bitmap
* - name falls within nsec coverage but is not equal to the owner name
* - name falls outside of nsec coverage
*/
if (ldns_dname_compare(ldns_rr_owner(ldns_rr_list_rr(nsecs, nsec_i)), name) == 0) {
/*
printf("CHECKING NSEC:\n");
ldns_rr_print(stdout, ldns_rr_list_rr(nsecs, nsec_i));
printf("DAWASEM\n");
*/
if (ldns_nsec_bitmap_covers_type(
ldns_nsec_get_bitmap(ldns_rr_list_rr(nsecs,
nsec_i)),
type)) {
/* Error, according to the nsec this rrset is signed */
result = LDNS_STATUS_CRYPTO_NO_RRSIG;
} else {
/* ok nsec denies existence */
if (verbosity >= 3) {
printf(";; Existence of data set with this type denied by NSEC\n");
}
/*printf(";; Verifiably insecure.\n");*/
if (nsec_rrs && nsec_rr_sigs) {
(void) get_dnssec_rr(pkt, ldns_rr_owner(ldns_rr_list_rr(nsecs, nsec_i)), LDNS_RR_TYPE_NSEC, nsec_rrs, nsec_rr_sigs);
}
ldns_rr_list_deep_free(nsecs);
return LDNS_STATUS_OK;
}
} else if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, nsec_i), name)) {
if (verbosity >= 3) {
printf(";; Existence of data set with this name denied by NSEC\n");
}
if (nsec_rrs && nsec_rr_sigs) {
(void) get_dnssec_rr(pkt, ldns_rr_owner(ldns_rr_list_rr(nsecs, nsec_i)), LDNS_RR_TYPE_NSEC, nsec_rrs, nsec_rr_sigs);
}
ldns_rr_list_deep_free(nsecs);
return LDNS_STATUS_OK;
} else {
/* nsec has nothing to do with this data */
}
}
ldns_rr_list_deep_free(nsecs);
} else if( (nsecs = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_NSEC3, LDNS_SECTION_ANY_NOQUESTION)) ) {
ldns_rr_list* sigs = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_RRSIG, LDNS_SECTION_ANY_NOQUESTION);
ldns_rr* q = ldns_rr_new();
ldns_rr* match = NULL;
if(!sigs) return LDNS_STATUS_MEM_ERR;
if(!q) return LDNS_STATUS_MEM_ERR;
ldns_rr_set_question(q, 1);
ldns_rr_set_ttl(q, 0);
ldns_rr_set_owner(q, ldns_rdf_clone(name));
if(!ldns_rr_owner(q)) return LDNS_STATUS_MEM_ERR;
ldns_rr_set_type(q, type);
/* result = ldns_dnssec_verify_denial_nsec3(q, nsecs, sigs, ldns_pkt_get_rcode(pkt), type, ldns_pkt_ancount(pkt) == 0); */
result = ldns_dnssec_verify_denial_nsec3_match(q, nsecs, sigs, ldns_pkt_get_rcode(pkt), type, ldns_pkt_ancount(pkt) == 0, &match);
if (result == LDNS_STATUS_OK && match && nsec_rrs && nsec_rr_sigs) {
(void) get_dnssec_rr(pkt, ldns_rr_owner(match), LDNS_RR_TYPE_NSEC3, nsec_rrs, nsec_rr_sigs);
}
ldns_rr_free(q);
ldns_rr_list_deep_free(nsecs);
ldns_rr_list_deep_free(sigs);
}
return result;
}
/* NSEC3 draft -07 */
/*return hash name match*/
ldns_rr *
ldns_nsec3_exact_match(ldns_rdf *qname, ldns_rr_type qtype, ldns_rr_list *nsec3s) {
uint8_t algorithm;
uint32_t iterations;
uint8_t salt_length;
uint8_t *salt;
ldns_rdf *sname = NULL, *hashed_sname = NULL;
size_t nsec_i;
ldns_rr *nsec;
ldns_rr *result = NULL;
const ldns_rr_descriptor *descriptor;
ldns_rdf *zone_name = NULL;
if (verbosity >= 4) {
printf(";; finding exact match for ");
descriptor = ldns_rr_descript(qtype);
if (descriptor && descriptor->_name) {
printf("%s ", descriptor->_name);
} else {
printf("TYPE%d ", qtype);
}
ldns_rdf_print(stdout, qname);
printf("\n");
}
if (!qname || !nsec3s || ldns_rr_list_rr_count(nsec3s) < 1) {
if (verbosity >= 4) {
printf("no qname, nsec3s or list empty\n");
}
return NULL;
}
nsec = ldns_rr_list_rr(nsec3s, 0);
algorithm = ldns_nsec3_algorithm(nsec);
salt_length = ldns_nsec3_salt_length(nsec);
salt = ldns_nsec3_salt_data(nsec);
iterations = ldns_nsec3_iterations(nsec);
if (salt == NULL) {
goto done;
}
sname = ldns_rdf_clone(qname);
if (sname == NULL) {
goto done;
}
if (verbosity >= 4) {
printf(";; owner name hashes to: ");
}
hashed_sname = ldns_nsec3_hash_name(sname, algorithm, iterations, salt_length, salt);
if (hashed_sname == NULL) {
goto done;
}
zone_name = ldns_dname_left_chop(ldns_rr_owner(nsec));
if (zone_name == NULL) {
goto done;
}
if (ldns_dname_cat(hashed_sname, zone_name) != LDNS_STATUS_OK) {
goto done;
};
if (verbosity >= 4) {
ldns_rdf_print(stdout, hashed_sname);
printf("\n");
}
for (nsec_i = 0; nsec_i < ldns_rr_list_rr_count(nsec3s); nsec_i++) {
nsec = ldns_rr_list_rr(nsec3s, nsec_i);
/* check values of iterations etc! */
/* exact match? */
if (ldns_dname_compare(ldns_rr_owner(nsec), hashed_sname) == 0) {
result = nsec;
goto done;
}
}
done:
ldns_rdf_deep_free(zone_name);
ldns_rdf_deep_free(sname);
ldns_rdf_deep_free(hashed_sname);
LDNS_FREE(salt);
if (verbosity >= 4) {
if (result) {
printf(";; Found.\n");
} else {
printf(";; Not foud.\n");
}
}
return result;
}
/*return the owner name of the closest encloser for name from the list of rrs */
/* this is NOT the hash, but the original name! */
ldns_rdf *
ldns_nsec3_closest_encloser(ldns_rdf *qname, ldns_rr_type qtype, ldns_rr_list *nsec3s)
{
/* remember parameters, they must match */
uint8_t algorithm;
uint32_t iterations;
uint8_t salt_length;
uint8_t *salt;
ldns_rdf *sname = NULL, *hashed_sname = NULL, *tmp;
bool flag;
bool exact_match_found;
bool in_range_found;
ldns_rdf *zone_name = NULL;
size_t nsec_i;
ldns_rr *nsec;
ldns_rdf *result = NULL;
if (!qname || !nsec3s || ldns_rr_list_rr_count(nsec3s) < 1) {
return NULL;
}
if (verbosity >= 4) {
printf(";; finding closest encloser for type %d ", qtype);
ldns_rdf_print(stdout, qname);
printf("\n");
}
nsec = ldns_rr_list_rr(nsec3s, 0);
algorithm = ldns_nsec3_algorithm(nsec);
salt_length = ldns_nsec3_salt_length(nsec);
salt = ldns_nsec3_salt_data(nsec);
iterations = ldns_nsec3_iterations(nsec);
if (salt == NULL) {
goto done;
}
sname = ldns_rdf_clone(qname);
if (sname == NULL) {
goto done;
}
flag = false;
zone_name = ldns_dname_left_chop(ldns_rr_owner(nsec));
if (zone_name == NULL) {
goto done;
}
/* algorithm from nsec3-07 8.3 */
while (ldns_dname_label_count(sname) > 0) {
exact_match_found = false;
in_range_found = false;
if (verbosity >= 3) {
printf(";; ");
ldns_rdf_print(stdout, sname);
printf(" hashes to: ");
}
hashed_sname = ldns_nsec3_hash_name(sname, algorithm, iterations, salt_length, salt);
if (hashed_sname == NULL) {
goto done;
}
if (ldns_dname_cat(hashed_sname, zone_name) != LDNS_STATUS_OK){
goto done;
}
if (verbosity >= 3) {
ldns_rdf_print(stdout, hashed_sname);
printf("\n");
}
for (nsec_i = 0; nsec_i < ldns_rr_list_rr_count(nsec3s); nsec_i++) {
nsec = ldns_rr_list_rr(nsec3s, nsec_i);
/* check values of iterations etc! */
/* exact match? */
if (ldns_dname_compare(ldns_rr_owner(nsec), hashed_sname) == 0) {
if (verbosity >= 4) {
printf(";; exact match found\n");
}
exact_match_found = true;
} else if (ldns_nsec_covers_name(nsec, hashed_sname)) {
if (verbosity >= 4) {
printf(";; in range of an nsec\n");
}
in_range_found = true;
}
}
if (!exact_match_found && in_range_found) {
flag = true;
} else if (exact_match_found && flag) {
result = ldns_rdf_clone(sname);
} else if (exact_match_found && !flag) {
// error!
if (verbosity >= 4) {
printf(";; the closest encloser is the same name (ie. this is an exact match, ie there is no closest encloser)\n");
}
ldns_rdf_deep_free(hashed_sname);
goto done;
} else {
flag = false;
}
ldns_rdf_deep_free(hashed_sname);
tmp = sname;
sname = ldns_dname_left_chop(sname);
ldns_rdf_deep_free(tmp);
if (sname == NULL) {
goto done;
}
}
done:
LDNS_FREE(salt);
ldns_rdf_deep_free(zone_name);
ldns_rdf_deep_free(sname);
if (!result) {
if (verbosity >= 4) {
printf(";; no closest encloser found\n");
}
}
/* todo checks from end of 6.2. here or in caller? */
return result;
}

230
contrib/ldns/drill/drill.1 Normal file
View file

@ -0,0 +1,230 @@
.\" @(#)drill.1 1.7.0 14-Jul-2004 OF;
.TH drill 1 "28 May 2006"
.SH NAME
drill \- get (debug) information out of DNS(SEC)
.SH SYNOPSIS
.B drill
[
.IR OPTIONS
]
.IR name
[
.IR @server
]
[
.IR type
]
[
.IR class
]
.SH DESCRIPTION
\fBdrill\fR is a tool to designed to get all sorts of information out of the
DNS. It is specificly designed to be used with DNSSEC.
.PP
The name \fBdrill\fR is a pun on \fBdig\fR. With \fBdrill\fR you should be able
get even more information than with \fBdig\fR.
.PP
If no arguments are given class defaults to 'IN' and type to 'A'. The
server(s) specified in /etc/resolv.conf are used to query against.
.PP
\fIname\fR
Ask for this name.
.PP
\fI@server\fR
Send to query to this server. If not specified use the nameservers from
\fI/etc/resolv.conf\fR.
.PP
\fItype\fR
Ask for this RR type. If type is not given on the command line it defaults
to 'A'. Except when doing to reverse lookup when it defaults to 'PTR'.
.PP
\fIclass\fR
Use this class when querying.
.SH SAMPLE USAGE
\fBdrill mx miek.nl\fR
Show the MX records of the domain miek.nl
.TP
\fBdrill -S jelte.nlnetlabs.nl\fR
Chase any signatures in the jelte.nlnetlab.nl domain. This option is
only available when ldns has been compiled with openssl-support.
.TP
\fBdrill -TD www.example.com\fR
Do a DNSSEC (-D) trace (-T) from the rootservers down to www.example.com.
This option only works when ldns has been compiled with openssl support.
.TP
\fBdrill -s dnskey jelte.nlnetlabs.nl\fR
Show the DNSKEY record(s) for jelte.nlnetlabs.nl. For each found DNSKEY
record also print the DS record.
.SH OPTIONS
.TP
\fB\-D
Enable DNSSEC in the query. When querying for DNSSEC types (DNSKEY, RRSIG,
DS and NSEC) this is \fInot\fR automaticly enabled.
.TP
\fB\-T
Trace \fIname\fR from the root down. When using this option the @server and
the type arguments are not used.
.TP
\fB\-S
Chase the signature(s) of 'name' to a known key or as high up in
the tree as possible.
.TP
\fB\-V \fIlevel\fR
Be more verbose. Set level to 5 to see the actual query that is sent.
.TP
\fB\-Q
Quiet mode, this overrules -V.
.TP
\fB\-f \fIfile\fR
Read the query from a file. The query must be dumped with -w.
.TP
\fB\-i \fIfile\fR
read the answer from the file instead from the network. This aids
in debugging and can be used to check if a query on disk is valid.
If the file contains binary data it is assumed to be a query in
network order.
.TP
\fB\-w \fIfile\fR
Write an answer packet to file.
.TP
\fB\-q \fIfile\fR
Write the query packet to file.
.TP
\fB\-v
Show drill's version.
.TP
\fB\-h
Show a short help message.
.SS QUERY OPTIONS
.TP
\fB\-4
Stay on ip4. Only send queries to ip4 enabled nameservers.
.TP
\fB\-6
Stay on ip6. Only send queries to ip6 enabled nameservers.
.TP
\fB\-a
Use the resolver structure's fallback mechanism if the answer
is truncated (TC=1). If a truncated packet is received and this
option is set, drill will first send a new query with EDNS0
buffer size 4096.
If the EDNS0 buffer size was already set to 512+ bytes, or the
above retry also results in a truncated answer, the resolver
structure will fall back to TCP.
.TP
\fB\-b \fIsize\fR
Use size as the buffer size in the EDNS0 pseudo RR.
.TP
\fB\-c \fIfile\fR
Use file instead of /etc/resolv.conf for nameserver configuration.
.TP
\fB\-d \fIdomain\fR
When tracing (-T), start from this domain instead of the root.
.TP
\fB\-t
Use TCP/IP when querying a server
.TP
\fB\-k \fIkeyfile\fR
Use this file to read a (trusted) key from. When this options is
given \fBdrill\fR tries to validate the current answer with this
key. No chasing is done. When \fBdrill\fR is doing a secure trace, this
key will be used as trust anchor. Can contain a DNSKEY or a DS record.
.TP
\fB\-o \fImnemonic\fR
Use this option to set or unset specific header bits. A bit is
set by using the bit mnemonic in CAPITAL letters. A bit is unset when
the mnemonic is given in lowercase. The following mnemonics are
understood by \fBdrill\fR:
QR, qr: set, unset QueRy (default: on)
AA, aa: set, unset Authoritative Answer (default: off)
TC, tc: set, unset TrunCated (default: off)
RD, rd: set, unset Recursion Desired (default: on)
CD, cd: set, unset Checking Disabled (default: off)
RA, ra: set, unset Recursion Available (default: off)
AD, ad: set, unset Authenticated Data (default: off)
Thus: \fB-o CD\fR, will enable Checking Disabled, which instructs the
cache to not validate the answers it gives out.
.TP
\fB\-p \fIport\fR
Use this port instead of the default of 53.
.TP
\fB\-r \fIfile\fR
When tracing (-T), use file as a root servers hint file.
.TP
\fB\-s
When encountering a DNSKEY print the equivalent DS also.
.TP
\fB\-u
Use UDP when querying a server. This is the default.
.TP
\fB\-w \fIfile\fR
write the answer to a file. The file will contain a hexadecimal dump
of the query. This can be used in conjunction with -f.
.TP
\fB\-x
Do a reverse loopup. The type argument is not used, it is preset to PTR.
.TP
\fB\-y \fI<name:key[:algo]>\fR
specify named base64 tsig key, and optional an algorithm (defaults to hmac-md5.sig-alg.reg.int)
.TP
\fB\-z \fR
don't randomize the nameserver list before sending queries.
.SH AUTHOR
Jelte Jansen and Miek Gieben. Both of NLnet Labs.
.SH REPORTING BUGS
Report bugs to <ldns-team@nlnetlabs.nl>.
.SH BUGS
.SH COPYRIGHT
Copyright (c) 2004-2008 NLnet Labs.
Licensed under the revised BSD license. There is NO warranty; not even for MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
.SH SEE ALSO
\fBdig\fR(1), \fIRFC403{3,4,5}\fR.

934
contrib/ldns/drill/drill.c Normal file
View file

@ -0,0 +1,934 @@
/*
* drill.c
* the main file of drill
* (c) 2005-2008 NLnet Labs
*
* See the file LICENSE for the license
*
*/
#include "drill.h"
#include <ldns/ldns.h>
#ifdef HAVE_SSL
#include <openssl/err.h>
#endif
#define IP6_ARPA_MAX_LEN 65
/* query debug, 2 hex dumps */
int verbosity;
static void
usage(FILE *stream, const char *progname)
{
fprintf(stream, " Usage: %s name [@server] [type] [class]\n", progname);
fprintf(stream, "\t<name> can be a domain name or an IP address (-x lookups)\n");
fprintf(stream, "\t<type> defaults to A\n");
fprintf(stream, "\t<class> defaults to IN\n");
fprintf(stream, "\n\targuments may be placed in random order\n");
fprintf(stream, "\n Options:\n");
fprintf(stream, "\t-D\t\tenable DNSSEC (DO bit)\n");
#ifdef HAVE_SSL
fprintf(stream, "\t-T\t\ttrace from the root down to <name>\n");
fprintf(stream, "\t-S\t\tchase signature(s) from <name> to a know key [*]\n");
#endif /*HAVE_SSL*/
fprintf(stream, "\t-V <number>\tverbosity (0-5)\n");
fprintf(stream, "\t-Q\t\tquiet mode (overrules -V)\n");
fprintf(stream, "\n");
fprintf(stream, "\t-f file\t\tread packet from file and send it\n");
fprintf(stream, "\t-i file\t\tread packet from file and print it\n");
fprintf(stream, "\t-w file\t\twrite answer packet to file\n");
fprintf(stream, "\t-q file\t\twrite query packet to file\n");
fprintf(stream, "\t-h\t\tshow this help\n");
fprintf(stream, "\t-v\t\tshow version\n");
fprintf(stream, "\n Query options:\n");
fprintf(stream, "\t-4\t\tstay on ip4\n");
fprintf(stream, "\t-6\t\tstay on ip6\n");
fprintf(stream, "\t-a\t\tfallback to EDNS0 and TCP if the answer is truncated\n");
fprintf(stream, "\t-b <bufsize>\tuse <bufsize> as the buffer size (defaults to 512 b)\n");
fprintf(stream, "\t-c <file>\t\tuse file for rescursive nameserver configuration (/etc/resolv.conf)\n");
fprintf(stream, "\t-k <file>\tspecify a file that contains a trusted DNSSEC key (DNSKEY|DS) [**]\n");
fprintf(stream, "\t\t\tused to verify any signatures in the current answer\n");
fprintf(stream, "\t-o <mnemonic>\tset flags to: [QR|qr][AA|aa][TC|tc][RD|rd][CD|cd][RA|ra][AD|ad]\n");
fprintf(stream, "\t\t\tlowercase: unset bit, uppercase: set bit\n");
fprintf(stream, "\t-p <port>\tuse <port> as remote port number\n");
fprintf(stream, "\t-s\t\tshow the DS RR for each key in a packet\n");
fprintf(stream, "\t-u\t\tsend the query with udp (the default)\n");
fprintf(stream, "\t-x\t\tdo a reverse lookup\n");
fprintf(stream, "\twhen doing a secure trace:\n");
fprintf(stream, "\t-r <file>\t\tuse file as root servers hint file\n");
fprintf(stream, "\t-t\t\tsend the query with tcp (connected)\n");
fprintf(stream, "\t-d <domain>\t\tuse domain as the start point for the trace\n");
fprintf(stream, "\t-y <name:key[:algo]>\tspecify named base64 tsig key, and optional an\n\t\t\talgorithm (defaults to hmac-md5.sig-alg.reg.int)\n");
fprintf(stream, "\t-z\t\tdon't randomize the nameservers before use\n");
fprintf(stream, "\n [*] = enables/implies DNSSEC\n");
fprintf(stream, " [**] = can be given more than once\n");
fprintf(stream, "\n ldns-team@nlnetlabs.nl | http://www.nlnetlabs.nl/ldns/\n");
}
/**
* Prints the drill version to stderr
*/
static void
version(FILE *stream, const char *progname)
{
fprintf(stream, "%s version %s (ldns version %s)\n", progname, DRILL_VERSION, ldns_version());
fprintf(stream, "Written by NLnet Labs.\n");
fprintf(stream, "\nCopyright (c) 2004-2008 NLnet Labs.\n");
fprintf(stream, "Licensed under the revised BSD license.\n");
fprintf(stream, "There is NO warranty; not even for MERCHANTABILITY or FITNESS\n");
fprintf(stream, "FOR A PARTICULAR PURPOSE.\n");
}
/**
* Main function of drill
* parse the arguments and prepare a query
*/
int
main(int argc, char *argv[])
{
ldns_resolver *res = NULL;
ldns_resolver *cmdline_res = NULL; /* only used to resolv @name names */
ldns_rr_list *cmdline_rr_list = NULL;
ldns_rdf *cmdline_dname = NULL;
ldns_rdf *qname, *qname_tmp;
ldns_pkt *pkt;
ldns_pkt *qpkt;
char *serv;
const char *name;
char *name2;
char *progname;
char *query_file = NULL;
char *answer_file = NULL;
ldns_buffer *query_buffer = NULL;
ldns_rdf *serv_rdf;
ldns_rr_type type;
ldns_rr_class clas;
#if 0
ldns_pkt_opcode opcode = LDNS_PACKET_QUERY;
#endif
int i, c;
int int_type;
int int_clas;
int PURPOSE;
char *tsig_name = NULL;
char *tsig_data = NULL;
char *tsig_algorithm = NULL;
size_t tsig_separator;
size_t tsig_separator2;
ldns_rr *axfr_rr;
ldns_status status;
char *type_str;
/* list of keys used in dnssec operations */
ldns_rr_list *key_list = ldns_rr_list_new();
/* what key verify the current answer */
ldns_rr_list *key_verified;
/* resolver options */
uint16_t qflags;
uint16_t qbuf;
uint16_t qport;
uint8_t qfamily;
bool qdnssec;
bool qfallback;
bool qds;
bool qusevc;
bool qrandom;
char *resolv_conf_file = NULL;
ldns_rdf *trace_start_name = NULL;
int result = 0;
#ifdef USE_WINSOCK
int r;
WSADATA wsa_data;
#endif
int_type = -1; serv = NULL; type = 0;
int_clas = -1; name = NULL; clas = 0;
qname = NULL;
progname = strdup(argv[0]);
#ifdef USE_WINSOCK
r = WSAStartup(MAKEWORD(2,2), &wsa_data);
if(r != 0) {
printf("Failed WSAStartup: %d\n", r);
result = EXIT_FAILURE;
goto exit;
}
#endif /* USE_WINSOCK */
PURPOSE = DRILL_QUERY;
qflags = LDNS_RD;
qport = LDNS_PORT;
verbosity = 2;
qdnssec = false;
qfamily = LDNS_RESOLV_INETANY;
qfallback = false;
qds = false;
qbuf = 0;
qusevc = false;
qrandom = true;
key_verified = NULL;
ldns_init_random(NULL, 0);
if (argc == 0) {
usage(stdout, progname);
result = EXIT_FAILURE;
goto exit;
}
/* string from orig drill: "i:w:I46Sk:TNp:b:DsvhVcuaq:f:xr" */
/* global first, query opt next, option with parm's last
* and sorted */ /* "46DITSVQf:i:w:q:achuvxzy:so:p:b:k:" */
while ((c = getopt(argc, argv, "46ab:c:d:Df:hi:Ik:o:p:q:Qr:sStTuvV:w:xy:z")) != -1) {
switch(c) {
/* global options */
case '4':
qfamily = LDNS_RESOLV_INET;
break;
case '6':
qfamily = LDNS_RESOLV_INET6;
break;
case 'D':
qdnssec = true;
break;
case 'I':
/* reserved for backward compatibility */
break;
case 'T':
if (PURPOSE == DRILL_CHASE) {
fprintf(stderr, "-T and -S cannot be used at the same time.\n");
exit(EXIT_FAILURE);
}
PURPOSE = DRILL_TRACE;
break;
#ifdef HAVE_SSL
case 'S':
if (PURPOSE == DRILL_TRACE) {
fprintf(stderr, "-T and -S cannot be used at the same time.\n");
exit(EXIT_FAILURE);
}
PURPOSE = DRILL_CHASE;
break;
#endif /* HAVE_SSL */
case 'V':
if (strtok(optarg, "0123456789") != NULL) {
fprintf(stderr, "-V expects an number as an argument.\n");
exit(EXIT_FAILURE);
}
verbosity = atoi(optarg);
break;
case 'Q':
verbosity = -1;
break;
case 'f':
query_file = optarg;
break;
case 'i':
answer_file = optarg;
PURPOSE = DRILL_AFROMFILE;
break;
case 'w':
answer_file = optarg;
break;
case 'q':
query_file = optarg;
PURPOSE = DRILL_QTOFILE;
break;
case 'r':
if (global_dns_root) {
fprintf(stderr, "There was already a series of root servers set\n");
exit(EXIT_FAILURE);
}
global_dns_root = read_root_hints(optarg);
if (!global_dns_root) {
fprintf(stderr, "Unable to read root hints file %s, aborting\n", optarg);
exit(EXIT_FAILURE);
}
break;
/* query options */
case 'a':
qfallback = true;
break;
case 'b':
qbuf = (uint16_t)atoi(optarg);
if (qbuf == 0) {
error("%s", "<bufsize> could not be converted");
}
break;
case 'c':
resolv_conf_file = optarg;
break;
case 't':
qusevc = true;
break;
case 'k':
status = read_key_file(optarg, key_list);
if (status != LDNS_STATUS_OK) {
error("Could not parse the key file %s: %s", optarg, ldns_get_errorstr_by_id(status));
}
qdnssec = true; /* enable that too */
break;
case 'o':
/* only looks at the first hit: capital=ON, lowercase=OFF*/
if (strstr(optarg, "QR")) {
DRILL_ON(qflags, LDNS_QR);
}
if (strstr(optarg, "qr")) {
DRILL_OFF(qflags, LDNS_QR);
}
if (strstr(optarg, "AA")) {
DRILL_ON(qflags, LDNS_AA);
}
if (strstr(optarg, "aa")) {
DRILL_OFF(qflags, LDNS_AA);
}
if (strstr(optarg, "TC")) {
DRILL_ON(qflags, LDNS_TC);
}
if (strstr(optarg, "tc")) {
DRILL_OFF(qflags, LDNS_TC);
}
if (strstr(optarg, "RD")) {
DRILL_ON(qflags, LDNS_RD);
}
if (strstr(optarg, "rd")) {
DRILL_OFF(qflags, LDNS_RD);
}
if (strstr(optarg, "CD")) {
DRILL_ON(qflags, LDNS_CD);
}
if (strstr(optarg, "cd")) {
DRILL_OFF(qflags, LDNS_CD);
}
if (strstr(optarg, "RA")) {
DRILL_ON(qflags, LDNS_RA);
}
if (strstr(optarg, "ra")) {
DRILL_OFF(qflags, LDNS_RA);
}
if (strstr(optarg, "AD")) {
DRILL_ON(qflags, LDNS_AD);
}
if (strstr(optarg, "ad")) {
DRILL_OFF(qflags, LDNS_AD);
}
break;
case 'p':
qport = (uint16_t)atoi(optarg);
if (qport == 0) {
error("%s", "<port> could not be converted");
}
break;
case 's':
qds = true;
break;
case 'u':
qusevc = false;
break;
case 'v':
version(stdout, progname);
result = EXIT_SUCCESS;
goto exit;
case 'x':
PURPOSE = DRILL_REVERSE;
break;
case 'y':
#ifdef HAVE_SSL
if (strchr(optarg, ':')) {
tsig_separator = (size_t) (strchr(optarg, ':') - optarg);
if (strchr(optarg + tsig_separator + 1, ':')) {
tsig_separator2 = (size_t) (strchr(optarg + tsig_separator + 1, ':') - optarg);
tsig_algorithm = xmalloc(strlen(optarg) - tsig_separator2);
strncpy(tsig_algorithm, optarg + tsig_separator2 + 1, strlen(optarg) - tsig_separator2);
tsig_algorithm[strlen(optarg) - tsig_separator2 - 1] = '\0';
} else {
tsig_separator2 = strlen(optarg);
tsig_algorithm = xmalloc(26);
strncpy(tsig_algorithm, "hmac-md5.sig-alg.reg.int.", 25);
tsig_algorithm[25] = '\0';
}
tsig_name = xmalloc(tsig_separator + 1);
tsig_data = xmalloc(tsig_separator2 - tsig_separator);
strncpy(tsig_name, optarg, tsig_separator);
strncpy(tsig_data, optarg + tsig_separator + 1, tsig_separator2 - tsig_separator - 1);
/* strncpy does not append \0 if source is longer than n */
tsig_name[tsig_separator] = '\0';
tsig_data[ tsig_separator2 - tsig_separator - 1] = '\0';
}
#else
fprintf(stderr, "TSIG requested, but SSL is not supported\n");
result = EXIT_FAILURE;
goto exit;
#endif /* HAVE_SSL */
break;
case 'z':
qrandom = false;
break;
case 'd':
trace_start_name = ldns_dname_new_frm_str(optarg);
if (!trace_start_name) {
fprintf(stderr, "Unable to parse argument for -%c\n", c);
result = EXIT_FAILURE;
goto exit;
}
break;
case 'h':
version(stdout, progname);
usage(stdout, progname);
result = EXIT_SUCCESS;
goto exit;
break;
default:
fprintf(stderr, "Unknown argument: -%c, use -h to see usage\n", c);
result = EXIT_FAILURE;
goto exit;
}
}
argc -= optind;
argv += optind;
/* do a secure trace when requested */
if (PURPOSE == DRILL_TRACE && qdnssec) {
#ifdef HAVE_SSL
if (ldns_rr_list_rr_count(key_list) == 0) {
warning("%s", "No trusted keys were given. Will not be able to verify authenticity!");
}
PURPOSE = DRILL_SECTRACE;
#else
fprintf(stderr, "ldns has not been compiled with OpenSSL support. Secure trace not available\n");
exit(1);
#endif /* HAVE_SSL */
}
/* parse the arguments, with multiple arguments, the last argument
* found is used */
for(i = 0; i < argc; i++) {
/* if ^@ then it's a server */
if (argv[i][0] == '@') {
if (strlen(argv[i]) == 1) {
warning("%s", "No nameserver given");
exit(EXIT_FAILURE);
}
serv = argv[i] + 1;
continue;
}
/* if has a dot, it's a name */
if (strchr(argv[i], '.')) {
name = argv[i];
continue;
}
/* if it matches a type, it's a type */
if (int_type == -1) {
type = ldns_get_rr_type_by_name(argv[i]);
if (type != 0) {
int_type = 0;
continue;
}
}
/* if it matches a class, it's a class */
if (int_clas == -1) {
clas = ldns_get_rr_class_by_name(argv[i]);
if (clas != 0) {
int_clas = 0;
continue;
}
}
/* it all fails assume it's a name */
name = argv[i];
}
/* act like dig and use for . NS */
if (!name) {
name = ".";
int_type = 0;
type = LDNS_RR_TYPE_NS;
}
/* defaults if not given */
if (int_clas == -1) {
clas = LDNS_RR_CLASS_IN;
}
if (int_type == -1) {
if (PURPOSE != DRILL_REVERSE) {
type = LDNS_RR_TYPE_A;
} else {
type = LDNS_RR_TYPE_PTR;
}
}
/* set the nameserver to use */
if (!serv) {
/* no server given make a resolver from /etc/resolv.conf */
status = ldns_resolver_new_frm_file(&res, resolv_conf_file);
if (status != LDNS_STATUS_OK) {
warning("Could not create a resolver structure: %s (%s)\n"
"Try drill @localhost if you have a resolver running on your machine.",
ldns_get_errorstr_by_id(status), resolv_conf_file);
result = EXIT_FAILURE;
goto exit;
}
} else {
res = ldns_resolver_new();
if (!res || strlen(serv) <= 0) {
warning("Could not create a resolver structure");
result = EXIT_FAILURE;
goto exit;
}
/* add the nameserver */
serv_rdf = ldns_rdf_new_addr_frm_str(serv);
if (!serv_rdf) {
/* try to resolv the name if possible */
status = ldns_resolver_new_frm_file(&cmdline_res, resolv_conf_file);
if (status != LDNS_STATUS_OK) {
error("%s", "@server ip could not be converted");
}
ldns_resolver_set_dnssec(cmdline_res, qdnssec);
ldns_resolver_set_ip6(cmdline_res, qfamily);
ldns_resolver_set_fallback(cmdline_res, qfallback);
ldns_resolver_set_usevc(cmdline_res, qusevc);
cmdline_dname = ldns_dname_new_frm_str(serv);
cmdline_rr_list = ldns_get_rr_list_addr_by_name(
cmdline_res,
cmdline_dname,
LDNS_RR_CLASS_IN,
qflags);
ldns_rdf_deep_free(cmdline_dname);
if (!cmdline_rr_list) {
/* This error msg is not always accurate */
error("%s `%s\'", "could not find any address for the name:", serv);
} else {
if (ldns_resolver_push_nameserver_rr_list(
res,
cmdline_rr_list
) != LDNS_STATUS_OK) {
error("%s", "pushing nameserver");
}
}
} else {
if (ldns_resolver_push_nameserver(res, serv_rdf) != LDNS_STATUS_OK) {
error("%s", "pushing nameserver");
} else {
ldns_rdf_deep_free(serv_rdf);
}
}
}
/* set the resolver options */
ldns_resolver_set_port(res, qport);
if (verbosity >= 5) {
ldns_resolver_set_debug(res, true);
} else {
ldns_resolver_set_debug(res, false);
}
ldns_resolver_set_dnssec(res, qdnssec);
/* ldns_resolver_set_dnssec_cd(res, qdnssec);*/
ldns_resolver_set_ip6(res, qfamily);
ldns_resolver_set_fallback(res, qfallback);
ldns_resolver_set_usevc(res, qusevc);
ldns_resolver_set_random(res, qrandom);
if (qbuf != 0) {
ldns_resolver_set_edns_udp_size(res, qbuf);
}
if (!name &&
PURPOSE != DRILL_AFROMFILE &&
!query_file
) {
usage(stdout, progname);
result = EXIT_FAILURE;
goto exit;
}
if (tsig_name && tsig_data) {
ldns_resolver_set_tsig_keyname(res, tsig_name);
ldns_resolver_set_tsig_keydata(res, tsig_data);
ldns_resolver_set_tsig_algorithm(res, tsig_algorithm);
}
/* main switching part of drill */
switch(PURPOSE) {
case DRILL_TRACE:
/* do a trace from the root down */
if (!global_dns_root) {
init_root();
}
qname = ldns_dname_new_frm_str(name);
if (!qname) {
error("%s", "parsing query name");
}
/* don't care about return packet */
(void)do_trace(res, qname, type, clas);
clear_root();
break;
case DRILL_SECTRACE:
/* do a secure trace from the root down */
if (!global_dns_root) {
init_root();
}
qname = ldns_dname_new_frm_str(name);
if (!qname) {
error("%s", "making qname");
}
/* don't care about return packet */
#ifdef HAVE_SSL
result = do_secure_trace(res, qname, type, clas, key_list, trace_start_name);
#endif /* HAVE_SSL */
clear_root();
break;
case DRILL_CHASE:
qname = ldns_dname_new_frm_str(name);
if (!qname) {
error("%s", "making qname");
}
ldns_resolver_set_dnssec(res, true);
ldns_resolver_set_dnssec_cd(res, true);
/* set dnssec implies udp_size of 4096 */
ldns_resolver_set_edns_udp_size(res, 4096);
pkt = ldns_resolver_query(res, qname, type, clas, qflags);
if (!pkt) {
error("%s", "error pkt sending");
result = EXIT_FAILURE;
} else {
if (verbosity >= 3) {
ldns_pkt_print(stdout, pkt);
}
if (!ldns_pkt_answer(pkt)) {
mesg("No answer in packet");
} else {
#ifdef HAVE_SSL
ldns_resolver_set_dnssec_anchors(res, ldns_rr_list_clone(key_list));
result = do_chase(res, qname, type,
clas, key_list,
pkt, qflags, NULL,
verbosity);
if (result == LDNS_STATUS_OK) {
if (verbosity != -1) {
mesg("Chase successful");
}
result = 0;
} else {
if (verbosity != -1) {
mesg("Chase failed.");
}
}
#endif /* HAVE_SSL */
}
ldns_pkt_free(pkt);
}
break;
case DRILL_AFROMFILE:
pkt = read_hex_pkt(answer_file);
if (pkt) {
if (verbosity != -1) {
ldns_pkt_print(stdout, pkt);
}
ldns_pkt_free(pkt);
}
break;
case DRILL_QTOFILE:
qname = ldns_dname_new_frm_str(name);
if (!qname) {
error("%s", "making qname");
}
status = ldns_resolver_prepare_query_pkt(&qpkt, res, qname, type, clas, qflags);
if(status != LDNS_STATUS_OK) {
error("%s", "making query: %s",
ldns_get_errorstr_by_id(status));
}
dump_hex(qpkt, query_file);
ldns_pkt_free(qpkt);
break;
case DRILL_NSEC:
break;
case DRILL_REVERSE:
/* ipv4 or ipv6 addr? */
if (strchr(name, ':')) {
if (strchr(name, '.')) {
error("Syntax error: both '.' and ':' seen in address\n");
}
name2 = malloc(IP6_ARPA_MAX_LEN + 20);
c = 0;
for (i=0; i<(int)strlen(name); i++) {
if (i >= IP6_ARPA_MAX_LEN) {
error("%s", "reverse argument to long");
}
if (name[i] == ':') {
if (i < (int) strlen(name) && name[i + 1] == ':') {
error("%s", ":: not supported (yet)");
} else {
if (i + 2 == (int) strlen(name) || name[i + 2] == ':') {
name2[c++] = '0';
name2[c++] = '.';
name2[c++] = '0';
name2[c++] = '.';
name2[c++] = '0';
name2[c++] = '.';
} else if (i + 3 == (int) strlen(name) || name[i + 3] == ':') {
name2[c++] = '0';
name2[c++] = '.';
name2[c++] = '0';
name2[c++] = '.';
} else if (i + 4 == (int) strlen(name) || name[i + 4] == ':') {
name2[c++] = '0';
name2[c++] = '.';
}
}
} else {
name2[c++] = name[i];
name2[c++] = '.';
}
}
name2[c++] = '\0';
qname = ldns_dname_new_frm_str(name2);
qname_tmp = ldns_dname_reverse(qname);
ldns_rdf_deep_free(qname);
qname = qname_tmp;
qname_tmp = ldns_dname_new_frm_str("ip6.arpa.");
status = ldns_dname_cat(qname, qname_tmp);
if (status != LDNS_STATUS_OK) {
error("%s", "could not create reverse address for ip6: %s\n", ldns_get_errorstr_by_id(status));
}
ldns_rdf_deep_free(qname_tmp);
free(name2);
} else {
qname = ldns_dname_new_frm_str(name);
qname_tmp = ldns_dname_reverse(qname);
ldns_rdf_deep_free(qname);
qname = qname_tmp;
qname_tmp = ldns_dname_new_frm_str("in-addr.arpa.");
status = ldns_dname_cat(qname, qname_tmp);
if (status != LDNS_STATUS_OK) {
error("%s", "could not create reverse address for ip4: %s\n", ldns_get_errorstr_by_id(status));
}
ldns_rdf_deep_free(qname_tmp);
}
if (!qname) {
error("%s", "-x implies an ip address");
}
/* create a packet and set the RD flag on it */
pkt = ldns_resolver_query(res, qname, type, clas, qflags);
if (!pkt) {
error("%s", "pkt sending");
result = EXIT_FAILURE;
} else {
if (verbosity != -1) {
ldns_pkt_print(stdout, pkt);
}
ldns_pkt_free(pkt);
}
break;
case DRILL_QUERY:
default:
if (query_file) {
/* this old way, the query packet needed
to be parseable, but we want to be able
to send mangled packets, so we need
to do it directly */
#if 0
qpkt = read_hex_pkt(query_file);
if (qpkt) {
status = ldns_resolver_send_pkt(&pkt, res, qpkt);
if (status != LDNS_STATUS_OK) {
printf("Error: %s\n", ldns_get_errorstr_by_id(status));
exit(1);
}
} else {
/* qpkt was bogus, reset pkt */
pkt = NULL;
}
#endif
query_buffer = read_hex_buffer(query_file);
if (query_buffer) {
status = ldns_send_buffer(&pkt, res, query_buffer, NULL);
ldns_buffer_free(query_buffer);
if (status != LDNS_STATUS_OK) {
printf("Error: %s\n", ldns_get_errorstr_by_id(status));
exit(1);
}
} else {
printf("NO BUFFER\n");
pkt = NULL;
}
} else {
qname = ldns_dname_new_frm_str(name);
if (!qname) {
error("%s", "error in making qname");
}
if (type == LDNS_RR_TYPE_AXFR) {
status = ldns_axfr_start(res, qname, clas);
if(status != LDNS_STATUS_OK) {
error("Error starting axfr: %s",
ldns_get_errorstr_by_id(status));
}
axfr_rr = ldns_axfr_next(res);
if(!axfr_rr) {
fprintf(stderr, "AXFR failed.\n");
ldns_pkt_print(stdout,
ldns_axfr_last_pkt(res));
goto exit;
}
while (axfr_rr) {
if (verbosity != -1) {
ldns_rr_print(stdout, axfr_rr);
}
ldns_rr_free(axfr_rr);
axfr_rr = ldns_axfr_next(res);
}
goto exit;
} else {
/* create a packet and set the RD flag on it */
pkt = ldns_resolver_query(res, qname, type, clas, qflags);
}
}
if (!pkt) {
mesg("No packet received");
result = EXIT_FAILURE;
} else {
if (verbosity != -1) {
ldns_pkt_print(stdout, pkt);
if (ldns_pkt_tc(pkt)) {
fprintf(stdout,
"\n;; WARNING: The answer packet was truncated; you might want to\n");
fprintf(stdout,
";; query again with TCP (-t argument), or EDNS0 (-b for buffer size)\n");
}
}
if (qds) {
if (verbosity != -1) {
print_ds_of_keys(pkt);
printf("\n");
}
}
if (ldns_rr_list_rr_count(key_list) > 0) {
/* -k's were given on the cmd line */
ldns_rr_list *rrset_verified;
uint16_t key_count;
rrset_verified = ldns_pkt_rr_list_by_name_and_type(
pkt, qname, type,
LDNS_SECTION_ANY_NOQUESTION);
if (type == LDNS_RR_TYPE_ANY) {
/* don't verify this */
break;
}
if (verbosity != -1) {
printf("; ");
ldns_rr_list_print(stdout, rrset_verified);
}
/* verify */
#ifdef HAVE_SSL
key_verified = ldns_rr_list_new();
result = ldns_pkt_verify(pkt, type, qname, key_list, NULL, key_verified);
if (result == LDNS_STATUS_ERR) {
/* is the existence denied then? */
result = ldns_verify_denial(pkt, qname, type, NULL, NULL);
if (result == LDNS_STATUS_OK) {
if (verbosity != -1) {
printf("Existence denied for ");
ldns_rdf_print(stdout, qname);
type_str = ldns_rr_type2str(type);
printf("\t%s\n", type_str);
LDNS_FREE(type_str);
}
} else {
if (verbosity != -1) {
printf("Bad data; RR for name and "
"type not found or failed to "
"verify, and denial of "
"existence failed.\n");
}
}
} else if (result == LDNS_STATUS_OK) {
for(key_count = 0; key_count < ldns_rr_list_rr_count(key_verified);
key_count++) {
if (verbosity != -1) {
printf("; VALIDATED by id = %u, owner = ",
(unsigned int)ldns_calc_keytag(
ldns_rr_list_rr(key_verified, key_count)));
ldns_rdf_print(stdout, ldns_rr_owner(
ldns_rr_list_rr(key_list, key_count)));
printf("\n");
}
}
} else {
for(key_count = 0; key_count < ldns_rr_list_rr_count(key_list);
key_count++) {
if (verbosity != -1) {
printf("; %s for id = %u, owner = ",
ldns_get_errorstr_by_id(result),
(unsigned int)ldns_calc_keytag(
ldns_rr_list_rr(key_list, key_count)));
ldns_rdf_print(stdout, ldns_rr_owner(
ldns_rr_list_rr(key_list,
key_count)));
printf("\n");
}
}
}
ldns_rr_list_free(key_verified);
#else
(void) key_count;
#endif /* HAVE_SSL */
}
if (answer_file) {
dump_hex(pkt, answer_file);
}
ldns_pkt_free(pkt);
}
break;
}
exit:
ldns_rdf_deep_free(qname);
ldns_resolver_deep_free(res);
ldns_resolver_deep_free(cmdline_res);
ldns_rr_list_deep_free(key_list);
ldns_rr_list_deep_free(cmdline_rr_list);
ldns_rdf_deep_free(trace_start_name);
xfree(progname);
xfree(tsig_name);
xfree(tsig_data);
xfree(tsig_algorithm);
#ifdef HAVE_SSL
ERR_remove_state(0);
CRYPTO_cleanup_all_ex_data();
ERR_free_strings();
EVP_cleanup();
#endif
#ifdef USE_WINSOCK
WSACleanup();
#endif
return result;
}

104
contrib/ldns/drill/drill.h Normal file
View file

@ -0,0 +1,104 @@
/*
* drill.h
* the main header file of drill
* (c) 2005, 2006 NLnet Labs
*
* See the file LICENSE for the license
*
*/
#ifndef _DRILL_H_
#define _DRILL_H_
#include "config.h"
#include "drill_util.h"
#define DRILL_VERSION PACKAGE_VERSION
/* what kind of stuff do we allow */
#define DRILL_QUERY 0
#define DRILL_TRACE 1
#define DRILL_CHASE 2
#define DRILL_AFROMFILE 3
#define DRILL_QTOFILE 4
#define DRILL_NSEC 5
#define DRILL_REVERSE 6
#define DRILL_SECTRACE 7
#define DRILL_ON(VAR, BIT) \
(VAR) = (VAR) | (BIT)
#define DRILL_OFF(VAR, BIT) \
(VAR) = (VAR) & ~(BIT)
extern ldns_rr_list *global_dns_root;
extern bool qds;
extern int verbosity;
ldns_pkt *do_trace(ldns_resolver *res,
ldns_rdf *name,
ldns_rr_type type,
ldns_rr_class c);
ldns_status do_chase(ldns_resolver *res,
ldns_rdf *name,
ldns_rr_type type,
ldns_rr_class c,
ldns_rr_list *trusted_keys,
ldns_pkt *pkt_o,
uint16_t qflags,
ldns_rr_list *prev_key_list,
int verbosity);
int do_secure_trace(ldns_resolver *res,
ldns_rdf *name,
ldns_rr_type type,
ldns_rr_class c,
ldns_rr_list *trusted_keys,
ldns_rdf *start_name);
ldns_rr_list * get_rr(ldns_resolver *res,
ldns_rdf *zname,
ldns_rr_type t,
ldns_rr_class c);
void drill_pkt_print(FILE *fd, ldns_resolver *r, ldns_pkt *p);
void drill_pkt_print_footer(FILE *fd, ldns_resolver *r, ldns_pkt *p);
ldns_pkt_type get_dnssec_rr(ldns_pkt *p,
ldns_rdf *name,
ldns_rr_type t,
ldns_rr_list **rrlist,
ldns_rr_list **sig);
ldns_rr *ldns_nsec3_exact_match(ldns_rdf *qname,
ldns_rr_type qtype,
ldns_rr_list *nsec3s);
ldns_rdf *ldns_nsec3_closest_encloser(ldns_rdf *qname,
ldns_rr_type qtype,
ldns_rr_list *nsec3s);
/* verifies denial of existence of *name in *pkt (must contain NSEC or NSEC3 records
* if *nsec_rrs and *nsec_rr_sigs are given, pointers to the relevant nsecs and their signatures are
* placed there
*/
ldns_status ldns_verify_denial(ldns_pkt *pkt,
ldns_rdf *name,
ldns_rr_type type,
ldns_rr_list **nsec_rrs,
ldns_rr_list **nsec_rr_sigs);
ldns_status read_key_file(const char *filename, ldns_rr_list *key_list);
ldns_pkt *read_hex_pkt(char *filename);
ldns_buffer *read_hex_buffer(char *filename);
void init_root(void);
ldns_rr_list *read_root_hints(const char *filename);
void clear_root(void);
void dump_hex(const ldns_pkt *pkt, const char *file);
void warning(const char *fmt, ...);
void error(const char *fmt, ...);
void mesg(const char *fmt, ...);
/* screen.c */
void resolver_print_nameservers(ldns_resolver *r);
void print_dnskey(ldns_rr_list *key_list);
void print_ds(ldns_rr_list *ds_list);
#endif /* _DRILL_H_ */

View file

@ -0,0 +1,305 @@
/*
* util.c
* some handy function needed in drill and not implemented
* in ldns
* (c) 2005 NLnet Labs
*
* See the file LICENSE for the license
*
*/
#include "drill.h"
#include <ldns/ldns.h>
#include <errno.h>
static size_t
read_line(FILE *input, char *line, size_t len)
{
size_t i;
char c;
for (i = 0; i < len-1; i++) {
c = getc(input);
if (c == EOF) {
return -1;
} else if (c != '\n') {
line[i] = c;
} else {
break;
}
}
line[i] = '\0';
return i;
}
/* key_list must be initialized with ldns_rr_list_new() */
ldns_status
read_key_file(const char *filename, ldns_rr_list *key_list)
{
int line_len = 0;
int line_nr = 0;
int key_count = 0;
char line[LDNS_MAX_PACKETLEN];
ldns_status status;
FILE *input_file;
ldns_rr *rr;
input_file = fopen(filename, "r");
if (!input_file) {
fprintf(stderr, "Error opening %s: %s\n",
filename, strerror(errno));
return LDNS_STATUS_ERR;
}
while (line_len >= 0) {
line_len = (int) read_line(input_file, line, sizeof(line));
line_nr++;
if (line_len > 0 && line[0] != ';') {
status = ldns_rr_new_frm_str(&rr, line, 0, NULL, NULL);
if (status != LDNS_STATUS_OK) {
fprintf(stderr,
"Error parsing DNSKEY RR in line %d: %s\n",
line_nr,
ldns_get_errorstr_by_id(status));
} else if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_DNSKEY ||
ldns_rr_get_type(rr) == LDNS_RR_TYPE_DS) {
ldns_rr_list_push_rr(key_list, rr);
key_count++;
} else {
ldns_rr_free(rr);
}
}
}
printf(";; Number of trusted keys: %d\n", key_count);
if (key_count > 0) {
return LDNS_STATUS_OK;
} else {
/*fprintf(stderr, "No keys read\n");*/
return LDNS_STATUS_ERR;
}
}
ldns_rdf *
ldns_rdf_new_addr_frm_str(char *str)
{
ldns_rdf *a;
a = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, str);
if (!a) {
/* maybe ip6 */
a = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, str);
if (!a) {
return NULL;
}
}
return a;
}
static inline void
local_print_ds(FILE* out, const char* pre, ldns_rr* ds)
{
if (out && ds) {
fprintf(out, "%s", pre);
ldns_rr_print(out, ds);
ldns_rr_free(ds);
}
}
/*
* For all keys in a packet print the DS
*/
void
print_ds_of_keys(ldns_pkt *p)
{
ldns_rr_list *keys;
uint16_t i;
ldns_rr *ds;
/* TODO fix the section stuff, here or in ldns */
keys = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_DNSKEY,
LDNS_SECTION_ANSWER);
/* this also returns the question section rr, which does not
* have any data.... and this inturn crashes everything */
if (keys) {
for (i = 0; i < ldns_rr_list_rr_count(keys); i++) {
fprintf(stdout, ";\n; equivalent DS records for key %u:\n",
(unsigned int)ldns_calc_keytag(ldns_rr_list_rr(keys, i)));
ds = ldns_key_rr2ds(ldns_rr_list_rr(keys, i), LDNS_SHA1);
local_print_ds(stdout, "; sha1: ", ds);
ds = ldns_key_rr2ds(ldns_rr_list_rr(keys, i), LDNS_SHA256);
local_print_ds(stdout, "; sha256: ", ds);
}
}
}
static void
print_class_type(FILE *fp, ldns_rr *r)
{
ldns_lookup_table *lt;
lt = ldns_lookup_by_id(ldns_rr_classes, ldns_rr_get_class(r));
if (lt) {
fprintf(fp, " %s", lt->name);
} else {
fprintf(fp, " CLASS%d", ldns_rr_get_class(r));
}
/* okay not THE way - but the quickest */
switch (ldns_rr_get_type(r)) {
case LDNS_RR_TYPE_RRSIG:
fprintf(fp, " RRSIG ");
break;
case LDNS_RR_TYPE_DNSKEY:
fprintf(fp, " DNSKEY ");
break;
case LDNS_RR_TYPE_DS:
fprintf(fp, " DS ");
break;
default:
break;
}
}
void
print_ds_abbr(FILE *fp, ldns_rr *ds)
{
if (!ds || (ldns_rr_get_type(ds) != LDNS_RR_TYPE_DS)) {
return;
}
ldns_rdf_print(fp, ldns_rr_owner(ds));
fprintf(fp, " %d", (int)ldns_rr_ttl(ds));
print_class_type(fp, ds);
ldns_rdf_print(fp, ldns_rr_rdf(ds, 0)); fprintf(fp, " ");
ldns_rdf_print(fp, ldns_rr_rdf(ds, 1)); fprintf(fp, " ");
ldns_rdf_print(fp, ldns_rr_rdf(ds, 2)); fprintf(fp, " ");
ldns_rdf_print(fp, ldns_rr_rdf(ds, 3)); fprintf(fp, " ");
}
/* print some of the elements of a signature */
void
print_rrsig_abbr(FILE *fp, ldns_rr *sig) {
if (!sig || (ldns_rr_get_type(sig) != LDNS_RR_TYPE_RRSIG)) {
return;
}
ldns_rdf_print(fp, ldns_rr_owner(sig));
fprintf(fp, " %d", (int)ldns_rr_ttl(sig));
print_class_type(fp, sig);
/* print a number of rdf's */
/* typecovered */
ldns_rdf_print(fp, ldns_rr_rdf(sig, 0)); fprintf(fp, " ");
/* algo */
ldns_rdf_print(fp, ldns_rr_rdf(sig, 1)); fprintf(fp, " ");
/* labels */
ldns_rdf_print(fp, ldns_rr_rdf(sig, 2)); fprintf(fp, " (\n\t\t\t");
/* expir */
ldns_rdf_print(fp, ldns_rr_rdf(sig, 4)); fprintf(fp, " ");
/* incep */
ldns_rdf_print(fp, ldns_rr_rdf(sig, 5)); fprintf(fp, " ");
/* key-id */
ldns_rdf_print(fp, ldns_rr_rdf(sig, 6)); fprintf(fp, " ");
/* key owner */
ldns_rdf_print(fp, ldns_rr_rdf(sig, 7)); fprintf(fp, ")");
}
void
print_dnskey_abbr(FILE *fp, ldns_rr *key)
{
if (!key || (ldns_rr_get_type(key) != LDNS_RR_TYPE_DNSKEY)) {
return;
}
ldns_rdf_print(fp, ldns_rr_owner(key));
fprintf(fp, " %d", (int)ldns_rr_ttl(key));
print_class_type(fp, key);
/* print a number of rdf's */
/* flags */
ldns_rdf_print(fp, ldns_rr_rdf(key, 0)); fprintf(fp, " ");
/* proto */
ldns_rdf_print(fp, ldns_rr_rdf(key, 1)); fprintf(fp, " ");
/* algo */
ldns_rdf_print(fp, ldns_rr_rdf(key, 2));
if (ldns_rdf2native_int16(ldns_rr_rdf(key, 0)) == 256) {
fprintf(fp, " ;{id = %u (zsk), size = %db}", (unsigned int)ldns_calc_keytag(key),
(int)ldns_rr_dnskey_key_size(key));
return;
}
if (ldns_rdf2native_int16(ldns_rr_rdf(key, 0)) == 257) {
fprintf(fp, " ;{id = %u (ksk), size = %db}", (unsigned int)ldns_calc_keytag(key),
(int)ldns_rr_dnskey_key_size(key));
return;
}
fprintf(fp, " ;{id = %u, size = %db}", (unsigned int)ldns_calc_keytag(key),
(int)ldns_rr_dnskey_key_size(key));
}
void
print_rr_list_abbr(FILE *fp, ldns_rr_list *rrlist, const char *usr)
{
size_t i;
ldns_rr_type tp;
for(i = 0; i < ldns_rr_list_rr_count(rrlist); i++) {
tp = ldns_rr_get_type(ldns_rr_list_rr(rrlist, i));
if (i == 0 && tp != LDNS_RR_TYPE_RRSIG) {
if (usr) {
fprintf(fp, "%s ", usr);
}
}
switch(tp) {
case LDNS_RR_TYPE_DNSKEY:
print_dnskey_abbr(fp, ldns_rr_list_rr(rrlist, i));
break;
case LDNS_RR_TYPE_RRSIG:
print_rrsig_abbr(fp, ldns_rr_list_rr(rrlist, i));
break;
case LDNS_RR_TYPE_DS:
print_ds_abbr(fp, ldns_rr_list_rr(rrlist, i));
break;
default:
/* not handled */
break;
}
fputs("\n", fp);
}
}
void *
xmalloc(size_t s)
{
void *p;
p = malloc(s);
if (!p) {
printf("Mem failure\n");
exit(EXIT_FAILURE);
}
return p;
}
void *
xrealloc(void *p, size_t size)
{
void *q;
q = realloc(p, size);
if (!q) {
printf("Mem failure\n");
exit(EXIT_FAILURE);
}
return q;
}
void
xfree(void *p)
{
if (p) {
free(p);
}
}

View file

@ -0,0 +1,58 @@
/*
* util.h
* util.c header file
* in ldns
* (c) 2005 NLnet Labs
*
* See the file LICENSE for the license
*
*/
#ifndef _DRILL_UTIL_H_
#define _DRILL_UTIL_H_
#include <ldns/ldns.h>
/**
* return a address rdf, either A or AAAA
* NULL if anything goes wrong
*/
ldns_rdf * ldns_rdf_new_addr_frm_str(char *);
/**
* print all the ds of the keys in the packet
*/
void print_ds_of_keys(ldns_pkt *p);
/**
* print some rdfs of a signature
*/
void print_rrsig_abbr(FILE *fp, ldns_rr *sig);
/**
* print some rdfs of a dnskey
*/
void print_dnskey_abbr(FILE *fp, ldns_rr *key);
/**
* print some rdfs of a ds
*/
void print_ds_abbr(FILE *fp, ldns_rr *ds);
/**
* print some rdfs of a rr in a rr_list
*/
void print_rr_list_abbr(FILE *fp, ldns_rr_list *sig, const char *usr);
/**
* Alloc some memory, with error checking
*/
void *xmalloc(size_t s);
/**
* Realloc some memory, with error checking
*/
void *xrealloc(void *p, size_t s);
/**
* Free the data
*/
void xfree(void *q);
#endif /* _DRILL_UTIL_H_ */

115
contrib/ldns/drill/error.c Normal file
View file

@ -0,0 +1,115 @@
/**
* error.c
*
* error reporting routines
* basicly wrappers around printf
*
* (c) 2005 NLnet Labs
*
* See the file LICENSE for the license
*
*/
#include "drill.h"
#include <ldns/ldns.h>
static void
warning_va_list(const char *fmt, va_list args)
{
fprintf(stderr, "Warning: ");
vfprintf(stderr, fmt, args);
fprintf(stderr, "\n");
}
void
warning(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
warning_va_list(fmt, args);
va_end(args);
}
static void
error_va_list(const char *fmt, va_list args)
{
fprintf(stderr, "Error: ");
vfprintf(stderr, fmt, args);
fprintf(stderr, "\n");
}
void
error(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
error_va_list(fmt, args);
va_end(args);
exit(EXIT_FAILURE);
}
static void
verbose_va_list(const char *fmt, va_list args)
{
vfprintf(stdout, fmt, args);
fprintf(stdout, "\n");
}
/* print stuff */
void
mesg(const char *fmt, ...)
{
va_list args;
if (verbosity == -1) {
return;
}
fprintf(stdout, ";; ");
va_start(args, fmt);
verbose_va_list(fmt, args);
va_end(args);
}
/* print stuff when in verbose mode (1) */
void
verbose(const char *fmt, ...)
{
va_list args;
if (verbosity < 1) {
return;
}
va_start(args, fmt);
verbose_va_list(fmt, args);
va_end(args);
}
/* print stuff when in vverbose mode (2) */
void
vverbose(const char *fmt, ...)
{
va_list args;
if (verbosity < 2) {
return;
}
va_start(args, fmt);
verbose_va_list(fmt, args);
va_end(args);
}
static void
debug_va_list(const char *fmt, va_list args)
{
vfprintf(stderr, fmt, args);
fprintf(stderr, "\n");
}
void
debug(const char *fmt, ...)
{
va_list args;
fprintf(stderr, "[DEBUG] ");
va_start(args, fmt);
debug_va_list(fmt, args);
va_end(args);
}

520
contrib/ldns/drill/install-sh Executable file
View file

@ -0,0 +1,520 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2009-04-28.21; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
nl='
'
IFS=" "" $nl"
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
if test -z "$doit"; then
doit_exec=exec
else
doit_exec=$doit
fi
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_glob='?'
initialize_posix_glob='
test "$posix_glob" != "?" || {
if (set -f) 2>/dev/null; then
posix_glob=
else
posix_glob=:
fi
}
'
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
no_target_directory=
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *' '* | *'
'* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-t) dst_arg=$2
shift;;
-T) no_target_directory=true;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call `install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
trap '(exit $?); exit' 1 2 13 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names starting with `-'.
case $src in
-*) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# Protect names starting with `-'.
case $dst in
-*) dst=./$dst;;
esac
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
# Prefer dirname, but fall back on a substitute if dirname fails.
dstdir=`
(dirname "$dst") 2>/dev/null ||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$dst" : 'X\(//\)[^/]' \| \
X"$dst" : 'X\(//\)$' \| \
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
echo X"$dst" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'
`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writeable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
-*) prefix='./';;
*) prefix='';;
esac
eval "$initialize_posix_glob"
oIFS=$IFS
IFS=/
$posix_glob set -f
set fnord $dstdir
shift
$posix_glob set +f
IFS=$oIFS
prefixes=
for d
do
test -z "$d" && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
eval "$initialize_posix_glob" &&
$posix_glob set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
$posix_glob set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

122
contrib/ldns/drill/root.c Normal file
View file

@ -0,0 +1,122 @@
/*
* root.c
* Function to handle to the rootservers
* and to update and prime them
* (c) 2005 NLnet Labs
*
* See the file LICENSE for the license
*
*/
#include "drill.h"
#include <ldns/ldns.h>
#include <errno.h>
/* a global list of the root-servers */
ldns_rr_list *global_dns_root = NULL;
/* put a hardcoded list in the root and
* init the root rrlist structure */
void
init_root(void)
{
ldns_rr *r;
global_dns_root = ldns_rr_list_new();
(void)ldns_rr_new_frm_str(&r, "A.ROOT-SERVERS.NET. 3600000 A 198.41.0.4", 0, NULL, NULL);
ldns_rr_list_push_rr(global_dns_root, r);
(void)ldns_rr_new_frm_str(&r, "A.ROOT-SERVERS.NET. 3600000 AAAA 2001:503:BA3E::2:30", 0, NULL, NULL);
ldns_rr_list_push_rr(global_dns_root, r);
(void)ldns_rr_new_frm_str(&r, "B.ROOT-SERVERS.NET. 3600000 A 192.228.79.201", 0, NULL, NULL);
ldns_rr_list_push_rr(global_dns_root, r);
(void)ldns_rr_new_frm_str(&r, "C.ROOT-SERVERS.NET. 3600000 A 192.33.4.12", 0, NULL, NULL);
ldns_rr_list_push_rr(global_dns_root, r);
(void)ldns_rr_new_frm_str(&r, "D.ROOT-SERVERS.NET. 3600000 A 128.8.10.90", 0, NULL, NULL);
ldns_rr_list_push_rr(global_dns_root, r);
(void)ldns_rr_new_frm_str(&r, "E.ROOT-SERVERS.NET. 3600000 A 192.203.230.10", 0, NULL, NULL);
ldns_rr_list_push_rr(global_dns_root, r);
(void)ldns_rr_new_frm_str(&r, "F.ROOT-SERVERS.NET. 3600000 A 192.5.5.241", 0, NULL, NULL);
ldns_rr_list_push_rr(global_dns_root, r);
(void)ldns_rr_new_frm_str(&r, "F.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2F::F", 0, NULL, NULL);
ldns_rr_list_push_rr(global_dns_root, r);
(void)ldns_rr_new_frm_str(&r, "G.ROOT-SERVERS.NET. 3600000 A 192.112.36.4", 0, NULL, NULL);
ldns_rr_list_push_rr(global_dns_root, r);
(void)ldns_rr_new_frm_str(&r, "H.ROOT-SERVERS.NET. 3600000 A 128.63.2.53", 0, NULL, NULL);
ldns_rr_list_push_rr(global_dns_root, r);
(void)ldns_rr_new_frm_str(&r, "H.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:1::803F:235", 0, NULL, NULL);
ldns_rr_list_push_rr(global_dns_root, r);
(void)ldns_rr_new_frm_str(&r, "I.ROOT-SERVERS.NET. 3600000 A 192.36.148.17", 0, NULL, NULL);
ldns_rr_list_push_rr(global_dns_root, r);
(void)ldns_rr_new_frm_str(&r, "J.ROOT-SERVERS.NET. 3600000 A 192.58.128.30", 0, NULL, NULL);
ldns_rr_list_push_rr(global_dns_root, r);
(void)ldns_rr_new_frm_str(&r, "J.ROOT-SERVERS.NET. 3600000 AAAA 2001:503:C27::2:30", 0, NULL, NULL);
ldns_rr_list_push_rr(global_dns_root, r);
(void)ldns_rr_new_frm_str(&r, "K.ROOT-SERVERS.NET. 3600000 A 193.0.14.129 ", 0, NULL, NULL);
ldns_rr_list_push_rr(global_dns_root, r);
(void)ldns_rr_new_frm_str(&r, "K.ROOT-SERVERS.NET. 3600000 AAAA 2001:7FD::1", 0, NULL, NULL);
ldns_rr_list_push_rr(global_dns_root, r);
(void)ldns_rr_new_frm_str(&r, "L.ROOT-SERVERS.NET. 3600000 A 199.7.83.42", 0, NULL, NULL);
ldns_rr_list_push_rr(global_dns_root, r);
(void)ldns_rr_new_frm_str(&r, "L.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:3::42 ", 0, NULL, NULL);
ldns_rr_list_push_rr(global_dns_root, r);
(void)ldns_rr_new_frm_str(&r, "M.ROOT-SERVERS.NET. 3600000 A 202.12.27.33", 0, NULL, NULL);
ldns_rr_list_push_rr(global_dns_root, r);
(void)ldns_rr_new_frm_str(&r, "M.ROOT-SERVERS.NET. 3600000 AAAA 2001:DC3::35", 0, NULL, NULL);
ldns_rr_list_push_rr(global_dns_root, r);
}
/*
* Read a hints file as root
*
* The file with the given path should contain a list of NS RRs
* for the root zone and A records for those NS RRs.
* Read them, check them, and append the a records to the rr list given.
*/
ldns_rr_list *
read_root_hints(const char *filename)
{
FILE *fp = NULL;
int line_nr = 0;
ldns_zone *z;
ldns_status status;
ldns_rr_list *addresses = NULL;
ldns_rr *rr;
size_t i;
fp = fopen(filename, "r");
if (!fp) {
fprintf(stderr, "Unable to open %s for reading: %s\n", filename, strerror(errno));
return NULL;
}
status = ldns_zone_new_frm_fp_l(&z, fp, NULL, 0, 0, &line_nr);
fclose(fp);
if (status != LDNS_STATUS_OK) {
fprintf(stderr, "Error reading root hints file: %s\n", ldns_get_errorstr_by_id(status));
return NULL;
} else {
addresses = ldns_rr_list_new();
for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(z)); i++) {
rr = ldns_rr_list_rr(ldns_zone_rrs(z), i);
/*if ((address_family == 0 || address_family == 1) &&
*/
if ( ldns_rr_get_type(rr) == LDNS_RR_TYPE_A ) {
ldns_rr_list_push_rr(addresses, ldns_rr_clone(rr));
}
/*if ((address_family == 0 || address_family == 2) &&*/
if ( ldns_rr_get_type(rr) == LDNS_RR_TYPE_AAAA) {
ldns_rr_list_push_rr(addresses, ldns_rr_clone(rr));
}
}
ldns_zone_deep_free(z);
return addresses;
}
}
void
clear_root(void)
{
ldns_rr_list_deep_free(global_dns_root);
}

View file

@ -0,0 +1,746 @@
/*
* securechasetrace.c
* Where all the hard work concerning secure tracing is done
*
* (c) 2005, 2006 NLnet Labs
*
* See the file LICENSE for the license
*
*/
#include "drill.h"
#include <ldns/ldns.h>
#define SELF "[S]" /* self sig ok */
#define TRUST "[T]" /* chain from parent */
#define BOGUS "[B]" /* bogus */
#define UNSIGNED "[U]" /* no relevant dnssec data found */
#if 0
/* See if there is a key/ds in trusted that matches
* a ds in *ds.
*/
static ldns_rr_list *
ds_key_match(ldns_rr_list *ds, ldns_rr_list *trusted)
{
size_t i, j;
bool match;
ldns_rr *rr_i, *rr_j;
ldns_rr_list *keys;
if (!trusted || !ds) {
return NULL;
}
match = false;
keys = ldns_rr_list_new();
if (!keys) {
return NULL;
}
if (!ds || !trusted) {
return NULL;
}
for (i = 0; i < ldns_rr_list_rr_count(trusted); i++) {
rr_i = ldns_rr_list_rr(trusted, i);
for (j = 0; j < ldns_rr_list_rr_count(ds); j++) {
rr_j = ldns_rr_list_rr(ds, j);
if (ldns_rr_compare_ds(rr_i, rr_j)) {
match = true;
/* only allow unique RRs to match */
ldns_rr_set_push_rr(keys, rr_i);
}
}
}
if (match) {
return keys;
} else {
return NULL;
}
}
#endif
ldns_pkt *
get_dnssec_pkt(ldns_resolver *r, ldns_rdf *name, ldns_rr_type t)
{
ldns_pkt *p = NULL;
p = ldns_resolver_query(r, name, t, LDNS_RR_CLASS_IN, 0);
if (!p) {
return NULL;
} else {
if (verbosity >= 5) {
ldns_pkt_print(stdout, p);
}
return p;
}
}
#ifdef HAVE_SSL
/*
* retrieve keys for this zone
*/
static ldns_pkt_type
get_key(ldns_pkt *p, ldns_rdf *apexname, ldns_rr_list **rrlist, ldns_rr_list **opt_sig)
{
return get_dnssec_rr(p, apexname, LDNS_RR_TYPE_DNSKEY, rrlist, opt_sig);
}
/*
* check to see if we can find a DS rrset here which we can then follow
*/
static ldns_pkt_type
get_ds(ldns_pkt *p, ldns_rdf *ownername, ldns_rr_list **rrlist, ldns_rr_list **opt_sig)
{
return get_dnssec_rr(p, ownername, LDNS_RR_TYPE_DS, rrlist, opt_sig);
}
#endif /* HAVE_SSL */
void
remove_resolver_nameservers(ldns_resolver *res)
{
ldns_rdf *pop;
/* remove the old nameserver from the resolver */
while((pop = ldns_resolver_pop_nameserver(res))) {
ldns_rdf_deep_free(pop);
}
}
void
show_current_nameservers(FILE *out, ldns_resolver *res)
{
size_t i;
fprintf(out, "Current nameservers for resolver object:\n");
for (i = 0; i < ldns_resolver_nameserver_count(res); i++) {
ldns_rdf_print(out, ldns_resolver_nameservers(res)[i]);
fprintf(out, "\n");
}
}
/*ldns_pkt **/
#ifdef HAVE_SSL
int
do_secure_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
ldns_rr_class c, ldns_rr_list *trusted_keys, ldns_rdf *start_name
)
{
ldns_resolver *res;
ldns_pkt *p, *local_p;
ldns_rr_list *new_nss;
ldns_rr_list *ns_addr;
ldns_rdf *pop;
ldns_rdf **labels = NULL;
ldns_status status, st;
ssize_t i;
size_t j;
size_t k;
size_t l;
uint8_t labels_count;
/* dnssec */
ldns_rr_list *key_list;
ldns_rr_list *key_sig_list;
ldns_rr_list *ds_list;
ldns_rr_list *ds_sig_list;
ldns_rr_list *correct_key_list;
ldns_rr_list *trusted_ds_rrs;
bool new_keys_trusted = false;
ldns_rr_list *current_correct_keys;
ldns_rr_list *dataset;
ldns_rr_list *nsec_rrs = NULL;
ldns_rr_list *nsec_rr_sigs = NULL;
/* empty non-terminal check */
bool ent;
/* glue handling */
ldns_rr_list *new_ns_addr;
ldns_rr_list *old_ns_addr;
ldns_rr *ns_rr;
int result = 0;
/* printing niceness */
const ldns_rr_descriptor *descriptor;
descriptor = ldns_rr_descript(t);
new_nss = NULL;
ns_addr = NULL;
key_list = NULL;
ds_list = NULL;
p = NULL;
local_p = NULL;
res = ldns_resolver_new();
key_sig_list = NULL;
ds_sig_list = NULL;
if (!res) {
error("Memory allocation failed");
result = -1;
return result;
}
correct_key_list = ldns_rr_list_new();
if (!correct_key_list) {
error("Memory allocation failed");
result = -1;
return result;
}
trusted_ds_rrs = ldns_rr_list_new();
if (!trusted_ds_rrs) {
error("Memory allocation failed");
result = -1;
return result;
}
/* Add all preset trusted DS signatures to the list of trusted DS RRs. */
for (j = 0; j < ldns_rr_list_rr_count(trusted_keys); j++) {
ldns_rr* one_rr = ldns_rr_list_rr(trusted_keys, j);
if (ldns_rr_get_type(one_rr) == LDNS_RR_TYPE_DS) {
ldns_rr_list_push_rr(trusted_ds_rrs, ldns_rr_clone(one_rr));
}
}
/* transfer some properties of local_res to res */
ldns_resolver_set_ip6(res,
ldns_resolver_ip6(local_res));
ldns_resolver_set_port(res,
ldns_resolver_port(local_res));
ldns_resolver_set_debug(res,
ldns_resolver_debug(local_res));
ldns_resolver_set_fail(res,
ldns_resolver_fail(local_res));
ldns_resolver_set_usevc(res,
ldns_resolver_usevc(local_res));
ldns_resolver_set_random(res,
ldns_resolver_random(local_res));
ldns_resolver_set_recursive(local_res, true);
ldns_resolver_set_recursive(res, false);
ldns_resolver_set_dnssec_cd(res, false);
ldns_resolver_set_dnssec(res, true);
/* setup the root nameserver in the new resolver */
status = ldns_resolver_push_nameserver_rr_list(res, global_dns_root);
if (status != LDNS_STATUS_OK) {
printf("ERRRRR: %s\n", ldns_get_errorstr_by_id(status));
ldns_rr_list_print(stdout, global_dns_root);
return status;
}
labels_count = ldns_dname_label_count(name);
if (start_name) {
if (ldns_dname_is_subdomain(name, start_name)) {
labels_count -= ldns_dname_label_count(start_name);
} else {
fprintf(stderr, "Error; ");
ldns_rdf_print(stderr, name);
fprintf(stderr, " is not a subdomain of ");
ldns_rdf_print(stderr, start_name);
fprintf(stderr, "\n");
goto done;
}
}
labels = LDNS_XMALLOC(ldns_rdf*, labels_count + 2);
if (!labels) {
goto done;
}
labels[0] = ldns_dname_new_frm_str(LDNS_ROOT_LABEL_STR);
labels[1] = ldns_rdf_clone(name);
for(i = 2 ; i < (ssize_t)labels_count + 2; i++) {
labels[i] = ldns_dname_left_chop(labels[i - 1]);
}
/* get the nameserver for the label
* ask: dnskey and ds for the label
*/
for(i = (ssize_t)labels_count + 1; i > 0; i--) {
status = ldns_resolver_send(&local_p, res, labels[i], LDNS_RR_TYPE_NS, c, 0);
if (verbosity >= 5) {
ldns_pkt_print(stdout, local_p);
}
new_nss = ldns_pkt_rr_list_by_type(local_p,
LDNS_RR_TYPE_NS, LDNS_SECTION_ANSWER);
if (!new_nss) {
/* if it's a delegation, servers put them in the auth section */
new_nss = ldns_pkt_rr_list_by_type(local_p,
LDNS_RR_TYPE_NS, LDNS_SECTION_AUTHORITY);
}
/* if this is the final step there might not be nameserver records
of course if the data is in the apex, there are, so cover both
cases */
if (new_nss || i > 1) {
for(j = 0; j < ldns_rr_list_rr_count(new_nss); j++) {
ns_rr = ldns_rr_list_rr(new_nss, j);
pop = ldns_rr_rdf(ns_rr, 0);
if (!pop) {
printf("nopo\n");
break;
}
/* retrieve it's addresses */
/* trust glue? */
new_ns_addr = NULL;
if (ldns_dname_is_subdomain(pop, labels[i])) {
new_ns_addr = ldns_pkt_rr_list_by_name_and_type(local_p, pop, LDNS_RR_TYPE_A, LDNS_SECTION_ADDITIONAL);
}
if (!new_ns_addr || ldns_rr_list_rr_count(new_ns_addr) == 0) {
new_ns_addr = ldns_get_rr_list_addr_by_name(res, pop, c, 0);
}
if (!new_ns_addr || ldns_rr_list_rr_count(new_ns_addr) == 0) {
new_ns_addr = ldns_get_rr_list_addr_by_name(local_res, pop, c, 0);
}
if (new_ns_addr) {
old_ns_addr = ns_addr;
ns_addr = ldns_rr_list_cat_clone(ns_addr, new_ns_addr);
ldns_rr_list_deep_free(old_ns_addr);
}
ldns_rr_list_deep_free(new_ns_addr);
}
ldns_rr_list_deep_free(new_nss);
if (ns_addr) {
remove_resolver_nameservers(res);
if (ldns_resolver_push_nameserver_rr_list(res, ns_addr) !=
LDNS_STATUS_OK) {
error("Error adding new nameservers");
ldns_pkt_free(local_p);
goto done;
}
ldns_rr_list_deep_free(ns_addr);
} else {
status = ldns_verify_denial(local_p, labels[i], LDNS_RR_TYPE_NS, &nsec_rrs, &nsec_rr_sigs);
/* verify the nsec3 themselves*/
if (verbosity >= 4) {
printf("NSEC(3) Records to verify:\n");
ldns_rr_list_print(stdout, nsec_rrs);
printf("With signatures:\n");
ldns_rr_list_print(stdout, nsec_rr_sigs);
printf("correct keys:\n");
ldns_rr_list_print(stdout, correct_key_list);
}
if (status == LDNS_STATUS_OK) {
if ((st = ldns_verify(nsec_rrs, nsec_rr_sigs, trusted_keys, NULL)) == LDNS_STATUS_OK) {
fprintf(stdout, "%s ", TRUST);
fprintf(stdout, "Existence denied: ");
ldns_rdf_print(stdout, labels[i]);
/*
if (descriptor && descriptor->_name) {
printf(" %s", descriptor->_name);
} else {
printf(" TYPE%u", t);
}
*/ fprintf(stdout, " NS\n");
} else if ((st = ldns_verify(nsec_rrs, nsec_rr_sigs, correct_key_list, NULL)) == LDNS_STATUS_OK) {
fprintf(stdout, "%s ", SELF);
fprintf(stdout, "Existence denied: ");
ldns_rdf_print(stdout, labels[i]);
/*
if (descriptor && descriptor->_name) {
printf(" %s", descriptor->_name);
} else {
printf(" TYPE%u", t);
}
*/
fprintf(stdout, " NS\n");
} else {
fprintf(stdout, "%s ", BOGUS);
result = 1;
printf(";; Error verifying denial of existence for name ");
ldns_rdf_print(stdout, labels[i]);
/*
printf(" type ");
if (descriptor && descriptor->_name) {
printf("%s", descriptor->_name);
} else {
printf("TYPE%u", t);
}
*/ printf("NS: %s\n", ldns_get_errorstr_by_id(st));
}
} else {
fprintf(stdout, "%s ", BOGUS);
result = 1;
printf(";; Error verifying denial of existence for name ");
ldns_rdf_print(stdout, labels[i]);
printf("NS: %s\n", ldns_get_errorstr_by_id(status));
}
/* there might be an empty non-terminal, in which case we need to continue */
ent = false;
for (j = 0; j < ldns_rr_list_rr_count(nsec_rrs); j++) {
if (ldns_dname_is_subdomain(ldns_rr_rdf(ldns_rr_list_rr(nsec_rrs, j), 0), labels[i])) {
ent = true;
}
}
if (!ent) {
ldns_rr_list_deep_free(nsec_rrs);
ldns_rr_list_deep_free(nsec_rr_sigs);
ldns_pkt_free(local_p);
goto done;
} else {
printf(";; There is an empty non-terminal here, continue\n");
continue;
}
goto done;
}
if (ldns_resolver_nameserver_count(res) == 0) {
error("No nameservers found for this node");
goto done;
}
}
ldns_pkt_free(local_p);
fprintf(stdout, ";; Domain: ");
ldns_rdf_print(stdout, labels[i]);
fprintf(stdout, "\n");
/* retrieve keys for current domain, and verify them
if they match an already trusted DS, or if one of the
keys used to sign these is trusted, add the keys to
the trusted list */
p = get_dnssec_pkt(res, labels[i], LDNS_RR_TYPE_DNSKEY);
(void) get_key(p, labels[i], &key_list, &key_sig_list);
if (key_sig_list) {
if (key_list) {
current_correct_keys = ldns_rr_list_new();
if ((st = ldns_verify(key_list, key_sig_list, key_list, current_correct_keys)) ==
LDNS_STATUS_OK) {
/* add all signed keys (don't just add current_correct, you'd miss
* the zsk's then */
for (j = 0; j < ldns_rr_list_rr_count(key_list); j++) {
ldns_rr_list_push_rr(correct_key_list, ldns_rr_clone(ldns_rr_list_rr(key_list, j)));
}
/* check whether these keys were signed
* by a trusted keys. if so, these
* keys are also trusted */
new_keys_trusted = false;
for (k = 0; k < ldns_rr_list_rr_count(current_correct_keys); k++) {
for (j = 0; j < ldns_rr_list_rr_count(trusted_ds_rrs); j++) {
if (ldns_rr_compare_ds(ldns_rr_list_rr(current_correct_keys, k),
ldns_rr_list_rr(trusted_ds_rrs, j))) {
new_keys_trusted = true;
}
}
}
/* also all keys are trusted if one of the current correct keys is trusted */
for (k = 0; k < ldns_rr_list_rr_count(current_correct_keys); k++) {
for (j = 0; j < ldns_rr_list_rr_count(trusted_keys); j++) {
if (ldns_rr_compare(ldns_rr_list_rr(current_correct_keys, k),
ldns_rr_list_rr(trusted_keys, j)) == 0) {
new_keys_trusted = true;
}
}
}
if (new_keys_trusted) {
ldns_rr_list_push_rr_list(trusted_keys, key_list);
print_rr_list_abbr(stdout, key_list, TRUST);
ldns_rr_list_free(key_list);
key_list = NULL;
} else {
if (verbosity >= 2) {
printf(";; Signature ok but no chain to a trusted key or ds record\n");
}
print_rr_list_abbr(stdout, key_list, SELF);
ldns_rr_list_deep_free(key_list);
key_list = NULL;
}
} else {
print_rr_list_abbr(stdout, key_list, BOGUS);
result = 2;
ldns_rr_list_deep_free(key_list);
key_list = NULL;
}
ldns_rr_list_free(current_correct_keys);
current_correct_keys = NULL;
} else {
printf(";; No DNSKEY record found for ");
ldns_rdf_print(stdout, labels[i]);
printf("\n");
}
}
ldns_pkt_free(p);
ldns_rr_list_deep_free(key_sig_list);
key_sig_list = NULL;
/* check the DS records for the next child domain */
if (i > 1) {
p = get_dnssec_pkt(res, labels[i-1], LDNS_RR_TYPE_DS);
(void) get_ds(p, labels[i-1], &ds_list, &ds_sig_list);
if (!ds_list) {
ldns_pkt_free(p);
if (ds_sig_list) {
ldns_rr_list_deep_free(ds_sig_list);
}
p = get_dnssec_pkt(res, name, LDNS_RR_TYPE_DNSKEY);
(void) get_ds(p, NULL, &ds_list, &ds_sig_list);
}
if (ds_sig_list) {
if (ds_list) {
if (verbosity >= 4) {
printf("VERIFYING:\n");
printf("DS LIST:\n");
ldns_rr_list_print(stdout, ds_list);
printf("SIGS:\n");
ldns_rr_list_print(stdout, ds_sig_list);
printf("KEYS:\n");
ldns_rr_list_print(stdout, correct_key_list);
}
current_correct_keys = ldns_rr_list_new();
if ((st = ldns_verify(ds_list, ds_sig_list, correct_key_list, current_correct_keys)) ==
LDNS_STATUS_OK) {
/* if the ds is signed by a trusted key and a key from correct keys
matches that ds, add that key to the trusted keys */
new_keys_trusted = false;
if (verbosity >= 2) {
printf("Checking if signing key is trusted:\n");
}
for (j = 0; j < ldns_rr_list_rr_count(current_correct_keys); j++) {
if (verbosity >= 2) {
printf("New key: ");
ldns_rr_print(stdout, ldns_rr_list_rr(current_correct_keys, j));
}
for (k = 0; k < ldns_rr_list_rr_count(trusted_keys); k++) {
if (verbosity >= 2) {
printf("\tTrusted key: ");
ldns_rr_print(stdout, ldns_rr_list_rr(trusted_keys, k));
}
if (ldns_rr_compare(ldns_rr_list_rr(current_correct_keys, j),
ldns_rr_list_rr(trusted_keys, k)) == 0) {
if (verbosity >= 2) {
printf("Key is now trusted!\n");
}
for (l = 0; l < ldns_rr_list_rr_count(ds_list); l++) {
ldns_rr_list_push_rr(trusted_ds_rrs, ldns_rr_clone(ldns_rr_list_rr(ds_list, l)));
new_keys_trusted = true;
}
}
}
}
if (new_keys_trusted) {
print_rr_list_abbr(stdout, ds_list, TRUST);
} else {
print_rr_list_abbr(stdout, ds_list, SELF);
}
} else {
result = 3;
print_rr_list_abbr(stdout, ds_list, BOGUS);
}
ldns_rr_list_free(current_correct_keys);
current_correct_keys = NULL;
} else {
/* wait apparently there were no keys either, go back to the ds packet */
ldns_pkt_free(p);
ldns_rr_list_deep_free(ds_sig_list);
p = get_dnssec_pkt(res, labels[i-1], LDNS_RR_TYPE_DS);
(void) get_ds(p, labels[i-1], &ds_list, &ds_sig_list);
status = ldns_verify_denial(p, labels[i-1], LDNS_RR_TYPE_DS, &nsec_rrs, &nsec_rr_sigs);
if (verbosity >= 4) {
printf("NSEC(3) Records to verify:\n");
ldns_rr_list_print(stdout, nsec_rrs);
printf("With signatures:\n");
ldns_rr_list_print(stdout, nsec_rr_sigs);
printf("correct keys:\n");
ldns_rr_list_print(stdout, correct_key_list);
}
if (status == LDNS_STATUS_OK) {
if ((st = ldns_verify(nsec_rrs, nsec_rr_sigs, trusted_keys, NULL)) == LDNS_STATUS_OK) {
fprintf(stdout, "%s ", TRUST);
fprintf(stdout, "Existence denied: ");
ldns_rdf_print(stdout, labels[i-1]);
printf(" DS");
fprintf(stdout, "\n");
} else if ((st = ldns_verify(nsec_rrs, nsec_rr_sigs, correct_key_list, NULL)) == LDNS_STATUS_OK) {
fprintf(stdout, "%s ", SELF);
fprintf(stdout, "Existence denied: ");
ldns_rdf_print(stdout, labels[i-1]);
printf(" DS");
fprintf(stdout, "\n");
} else {
result = 4;
fprintf(stdout, "%s ", BOGUS);
printf("Error verifying denial of existence for ");
ldns_rdf_print(stdout, labels[i-1]);
printf(" DS");
printf(": %s\n", ldns_get_errorstr_by_id(st));
}
} else {
if (status == LDNS_STATUS_CRYPTO_NO_RRSIG) {
printf(";; No DS for ");
ldns_rdf_print(stdout, labels[i - 1]);
} else {
printf("[B] Unable to verify denial of existence for ");
ldns_rdf_print(stdout, labels[i - 1]);
printf(" DS: %s\n", ldns_get_errorstr_by_id(status));
}
}
if (verbosity >= 2) {
printf(";; No ds record for delegation\n");
}
}
}
ldns_rr_list_deep_free(ds_list);
ldns_pkt_free(p);
} else {
/* if this is the last label, just verify the data and stop */
p = get_dnssec_pkt(res, labels[i], t);
(void) get_dnssec_rr(p, labels[i], t, &dataset, &key_sig_list);
if (dataset && ldns_rr_list_rr_count(dataset) > 0) {
if (key_sig_list && ldns_rr_list_rr_count(key_sig_list) > 0) {
/* If this is a wildcard, you must be able to deny exact match */
if ((st = ldns_verify(dataset, key_sig_list, trusted_keys, NULL)) == LDNS_STATUS_OK) {
fprintf(stdout, "%s ", TRUST);
ldns_rr_list_print(stdout, dataset);
} else if ((st = ldns_verify(dataset, key_sig_list, correct_key_list, NULL)) == LDNS_STATUS_OK) {
fprintf(stdout, "%s ", SELF);
ldns_rr_list_print(stdout, dataset);
} else {
result = 5;
fprintf(stdout, "%s ", BOGUS);
ldns_rr_list_print(stdout, dataset);
printf(";; Error: %s\n", ldns_get_errorstr_by_id(st));
}
} else {
fprintf(stdout, "%s ", UNSIGNED);
ldns_rr_list_print(stdout, dataset);
}
ldns_rr_list_deep_free(dataset);
} else {
status = ldns_verify_denial(p, name, t, &nsec_rrs, &nsec_rr_sigs);
if (status == LDNS_STATUS_OK) {
/* verify the nsec3 themselves*/
if (verbosity >= 5) {
printf("NSEC(3) Records to verify:\n");
ldns_rr_list_print(stdout, nsec_rrs);
printf("With signatures:\n");
ldns_rr_list_print(stdout, nsec_rr_sigs);
printf("correct keys:\n");
ldns_rr_list_print(stdout, correct_key_list);
/*
printf("trusted keys at %p:\n", trusted_keys);
ldns_rr_list_print(stdout, trusted_keys);
*/ }
if ((st = ldns_verify(nsec_rrs, nsec_rr_sigs, trusted_keys, NULL)) == LDNS_STATUS_OK) {
fprintf(stdout, "%s ", TRUST);
fprintf(stdout, "Existence denied: ");
ldns_rdf_print(stdout, name);
if (descriptor && descriptor->_name) {
printf(" %s", descriptor->_name);
} else {
printf(" TYPE%u", t);
}
fprintf(stdout, "\n");
} else if ((st = ldns_verify(nsec_rrs, nsec_rr_sigs, correct_key_list, NULL)) == LDNS_STATUS_OK) {
fprintf(stdout, "%s ", SELF);
fprintf(stdout, "Existence denied: ");
ldns_rdf_print(stdout, name);
if (descriptor && descriptor->_name) {
printf(" %s", descriptor->_name);
} else {
printf(" TYPE%u", t);
}
fprintf(stdout, "\n");
} else {
result = 6;
fprintf(stdout, "%s ", BOGUS);
printf("Error verifying denial of existence for ");
ldns_rdf_print(stdout, name);
printf(" type ");
if (descriptor && descriptor->_name) {
printf("%s", descriptor->_name);
} else {
printf("TYPE%u", t);
}
printf(": %s\n", ldns_get_errorstr_by_id(st));
}
ldns_rr_list_deep_free(nsec_rrs);
ldns_rr_list_deep_free(nsec_rr_sigs);
} else {
/*
*/
if (status == LDNS_STATUS_CRYPTO_NO_RRSIG) {
printf("%s ", UNSIGNED);
printf("No data found for: ");
ldns_rdf_print(stdout, name);
printf(" type ");
if (descriptor && descriptor->_name) {
printf("%s", descriptor->_name);
} else {
printf("TYPE%u", t);
}
printf("\n");
} else {
printf("[B] Unable to verify denial of existence for ");
ldns_rdf_print(stdout, name);
printf(" type ");
if (descriptor && descriptor->_name) {
printf("%s", descriptor->_name);
} else {
printf("TYPE%u", t);
}
printf("\n");
}
}
}
ldns_pkt_free(p);
}
new_nss = NULL;
ns_addr = NULL;
ldns_rr_list_deep_free(key_list);
key_list = NULL;
ldns_rr_list_deep_free(key_sig_list);
key_sig_list = NULL;
ds_list = NULL;
ldns_rr_list_deep_free(ds_sig_list);
ds_sig_list = NULL;
}
printf(";;" SELF " self sig OK; " BOGUS " bogus; " TRUST " trusted\n");
/* verbose mode?
printf("Trusted keys:\n");
ldns_rr_list_print(stdout, trusted_keys);
printf("trusted dss:\n");
ldns_rr_list_print(stdout, trusted_ds_rrs);
*/
done:
ldns_rr_list_deep_free(trusted_ds_rrs);
ldns_rr_list_deep_free(correct_key_list);
ldns_resolver_deep_free(res);
if (labels) {
for(i = 0 ; i < (ssize_t)labels_count + 2; i++) {
ldns_rdf_deep_free(labels[i]);
}
LDNS_FREE(labels);
}
return result;
}
#endif /* HAVE_SSL */

276
contrib/ldns/drill/work.c Normal file
View file

@ -0,0 +1,276 @@
/*
* work.c
* Where all the hard work is done
* (c) 2005 NLnet Labs
*
* See the file LICENSE for the license
*
*/
#include "drill.h"
#include <ldns/ldns.h>
/**
* Converts a hex string to binary data
* len is the length of the string
* buf is the buffer to store the result in
* offset is the starting position in the result buffer
*
* This function returns the length of the result
*/
size_t
hexstr2bin(char *hexstr, int len, uint8_t *buf, size_t offset, size_t buf_len)
{
char c;
int i;
uint8_t int8 = 0;
int sec = 0;
size_t bufpos = 0;
if (len % 2 != 0) {
return 0;
}
for (i=0; i<len; i++) {
c = hexstr[i];
/* case insensitive, skip spaces */
if (c != ' ') {
if (c >= '0' && c <= '9') {
int8 += c & 0x0f;
} else if (c >= 'a' && c <= 'z') {
int8 += (c & 0x0f) + 9;
} else if (c >= 'A' && c <= 'Z') {
int8 += (c & 0x0f) + 9;
} else {
return 0;
}
if (sec == 0) {
int8 = int8 << 4;
sec = 1;
} else {
if (bufpos + offset + 1 <= buf_len) {
buf[bufpos+offset] = int8;
int8 = 0;
sec = 0;
bufpos++;
} else {
error("Buffer too small in hexstr2bin");
}
}
}
}
return bufpos;
}
size_t
packetbuffromfile(char *filename, uint8_t *wire)
{
FILE *fp = NULL;
int c;
/* stat hack
* 0 = normal
* 1 = comment (skip to end of line)
* 2 = unprintable character found, read binary data directly
*/
int state = 0;
uint8_t *hexbuf = xmalloc(LDNS_MAX_PACKETLEN);
int hexbufpos = 0;
size_t wirelen;
if (strncmp(filename, "-", 2) == 0) {
fp = stdin;
} else {
fp = fopen(filename, "r");
}
if (fp == NULL) {
perror("Unable to open file for reading");
xfree(hexbuf);
return 0;
}
/*verbose("Opened %s\n", filename);*/
c = fgetc(fp);
while (c != EOF && hexbufpos < LDNS_MAX_PACKETLEN) {
if (state < 2 && !isascii(c)) {
/*verbose("non ascii character found in file: (%d) switching to raw mode\n", c);*/
state = 2;
}
switch (state) {
case 0:
if ( (c >= '0' && c <= '9') ||
(c >= 'a' && c <= 'f') ||
(c >= 'A' && c <= 'F') )
{
hexbuf[hexbufpos] = (uint8_t) c;
hexbufpos++;
} else if (c == ';') {
state = 1;
} else if (c == ' ' || c == '\t' || c == '\n') {
/* skip whitespace */
}
break;
case 1:
if (c == '\n' || c == EOF) {
state = 0;
}
break;
case 2:
hexbuf[hexbufpos] = (uint8_t) c;
hexbufpos++;
break;
default:
warning("unknown state while reading %s", filename);
xfree(hexbuf);
return 0;
break;
}
c = fgetc(fp);
}
if (c == EOF) {
/*
if (have_drill_opt && drill_opt->verbose) {
verbose("END OF FILE REACHED\n");
if (state < 2) {
verbose("read:\n");
verbose("%s\n", hexbuf);
} else {
verbose("Not printing wire because it contains non ascii data\n");
}
}
*/
}
if (hexbufpos >= LDNS_MAX_PACKETLEN) {
/*verbose("packet size reached\n");*/
}
/* lenient mode: length must be multiple of 2 */
if (hexbufpos % 2 != 0) {
hexbuf[hexbufpos] = (uint8_t) '0';
hexbufpos++;
}
if (state < 2) {
wirelen = hexstr2bin((char *) hexbuf,
hexbufpos,
wire,
0,
LDNS_MAX_PACKETLEN);
} else {
memcpy(wire, hexbuf, (size_t) hexbufpos);
wirelen = (size_t) hexbufpos;
}
if (fp != stdin) {
fclose(fp);
}
xfree(hexbuf);
return wirelen;
}
ldns_buffer *
read_hex_buffer(char *filename)
{
uint8_t *wire;
size_t wiresize;
ldns_buffer *result_buffer = NULL;
FILE *fp = NULL;
if (strncmp(filename, "-", 2) != 0) {
fp = fopen(filename, "r");
} else {
fp = stdin;
}
if (fp == NULL) {
perror("");
warning("Unable to open %s", filename);
return NULL;
}
wire = xmalloc(LDNS_MAX_PACKETLEN);
wiresize = packetbuffromfile(filename, wire);
result_buffer = LDNS_MALLOC(ldns_buffer);
ldns_buffer_new_frm_data(result_buffer, wire, wiresize);
ldns_buffer_set_position(result_buffer, ldns_buffer_capacity(result_buffer));
xfree(wire);
return result_buffer;
}
ldns_pkt *
read_hex_pkt(char *filename)
{
uint8_t *wire;
size_t wiresize;
ldns_pkt *pkt = NULL;
ldns_status status = LDNS_STATUS_ERR;
wire = xmalloc(LDNS_MAX_PACKETLEN);
wiresize = packetbuffromfile(filename, wire);
if (wiresize > 0) {
status = ldns_wire2pkt(&pkt, wire, wiresize);
}
xfree(wire);
if (status == LDNS_STATUS_OK) {
return pkt;
} else {
fprintf(stderr, "Error parsing hex file: %s\n",
ldns_get_errorstr_by_id(status));
return NULL;
}
}
void
dump_hex(const ldns_pkt *pkt, const char *filename)
{
uint8_t *wire;
size_t size, i;
FILE *fp;
ldns_status status;
fp = fopen(filename, "w");
if (fp == NULL) {
error("Unable to open %s for writing", filename);
return;
}
status = ldns_pkt2wire(&wire, pkt, &size);
if (status != LDNS_STATUS_OK) {
error("Unable to convert packet: error code %u", status);
return;
}
fprintf(fp, "; 0");
for (i = 1; i < 20; i++) {
fprintf(fp, " %2u", (unsigned int) i);
}
fprintf(fp, "\n");
fprintf(fp, ";--");
for (i = 1; i < 20; i++) {
fprintf(fp, " --");
}
fprintf(fp, "\n");
for (i = 0; i < size; i++) {
if (i % 20 == 0 && i > 0) {
fprintf(fp, "\t;\t%4u-%4u\n", (unsigned int) i-19, (unsigned int) i);
}
fprintf(fp, " %02x", (unsigned int)wire[i]);
}
fprintf(fp, "\n");
fclose(fp);
}

354
contrib/ldns/duration.c Normal file
View file

@ -0,0 +1,354 @@
/*
* $Id: duration.c 4518 2011-02-24 15:39:09Z matthijs $
*
* Copyright (c) 2009 NLNet Labs. 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*
*/
/**
*
* This file is copied from the OpenDNSSEC source repository
* and only slightly adapted to make it fit.
*/
/**
*
* Durations.
*/
#include <ldns/config.h>
#include <ldns/duration.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
/**
* Create a new 'instant' duration.
*
*/
ldns_duration_type*
ldns_duration_create(void)
{
ldns_duration_type* duration;
duration = malloc(sizeof(ldns_duration_type));
if (!duration) {
return NULL;
}
duration->years = 0;
duration->months = 0;
duration->weeks = 0;
duration->days = 0;
duration->hours = 0;
duration->minutes = 0;
duration->seconds = 0;
return duration;
}
/**
* Compare durations.
*
*/
int
ldns_duration_compare(ldns_duration_type* d1, ldns_duration_type* d2)
{
if (!d1 && !d2) {
return 0;
}
if (!d1 || !d2) {
return d1?-1:1;
}
if (d1->years != d2->years) {
return (int) (d1->years - d2->years);
}
if (d1->months != d2->months) {
return (int) (d1->months - d2->months);
}
if (d1->weeks != d2->weeks) {
return (int) (d1->weeks - d2->weeks);
}
if (d1->days != d2->days) {
return (int) (d1->days - d2->days);
}
if (d1->hours != d2->hours) {
return (int) (d1->hours - d2->hours);
}
if (d1->minutes != d2->minutes) {
return (int) (d1->minutes - d2->minutes);
}
if (d1->seconds != d2->seconds) {
return (int) (d1->seconds - d2->seconds);
}
return 0;
}
/**
* Create a duration from string.
*
*/
ldns_duration_type*
ldns_duration_create_from_string(const char* str)
{
ldns_duration_type* duration = ldns_duration_create();
char* P, *X, *T, *W;
int not_weeks = 0;
if (!duration) {
return NULL;
}
if (!str) {
return duration;
}
P = strchr(str, 'P');
if (!P) {
ldns_duration_cleanup(duration);
return NULL;
}
T = strchr(str, 'T');
X = strchr(str, 'Y');
if (X) {
duration->years = (time_t) atoi(str+1);
str = X;
not_weeks = 1;
}
X = strchr(str, 'M');
if (X && (!T || (size_t) (X-P) < (size_t) (T-P))) {
duration->months = (time_t) atoi(str+1);
str = X;
not_weeks = 1;
}
X = strchr(str, 'D');
if (X) {
duration->days = (time_t) atoi(str+1);
str = X;
not_weeks = 1;
}
if (T) {
str = T;
not_weeks = 1;
}
X = strchr(str, 'H');
if (X && T) {
duration->hours = (time_t) atoi(str+1);
str = X;
not_weeks = 1;
}
X = strrchr(str, 'M');
if (X && T && (size_t) (X-P) > (size_t) (T-P)) {
duration->minutes = (time_t) atoi(str+1);
str = X;
not_weeks = 1;
}
X = strchr(str, 'S');
if (X && T) {
duration->seconds = (time_t) atoi(str+1);
str = X;
not_weeks = 1;
}
W = strchr(str, 'W');
if (W) {
if (not_weeks) {
ldns_duration_cleanup(duration);
return NULL;
} else {
duration->weeks = (time_t) atoi(str+1);
str = W;
}
}
return duration;
}
/**
* Get the number of digits in a number.
*
*/
static size_t
digits_in_number(time_t duration)
{
uint32_t period = (uint32_t) duration;
size_t count = 0;
while (period > 0) {
count++;
period /= 10;
}
return count;
}
/**
* Convert a duration to a string.
*
*/
char*
ldns_duration2string(ldns_duration_type* duration)
{
char* str = NULL, *num = NULL;
size_t count = 2;
int T = 0;
if (!duration) {
return NULL;
}
if (duration->years > 0) {
count = count + 1 + digits_in_number(duration->years);
}
if (duration->months > 0) {
count = count + 1 + digits_in_number(duration->months);
}
if (duration->weeks > 0) {
count = count + 1 + digits_in_number(duration->weeks);
}
if (duration->days > 0) {
count = count + 1 + digits_in_number(duration->days);
}
if (duration->hours > 0) {
count = count + 1 + digits_in_number(duration->hours);
T = 1;
}
if (duration->minutes > 0) {
count = count + 1 + digits_in_number(duration->minutes);
T = 1;
}
if (duration->seconds > 0) {
count = count + 1 + digits_in_number(duration->seconds);
T = 1;
}
if (T) {
count++;
}
str = (char*) calloc(count, sizeof(char));
str[0] = 'P';
str[1] = '\0';
if (duration->years > 0) {
count = digits_in_number(duration->years);
num = (char*) calloc(count+2, sizeof(char));
snprintf(num, count+2, "%uY", (unsigned int) duration->years);
str = strncat(str, num, count+2);
free((void*) num);
}
if (duration->months > 0) {
count = digits_in_number(duration->months);
num = (char*) calloc(count+2, sizeof(char));
snprintf(num, count+2, "%uM", (unsigned int) duration->months);
str = strncat(str, num, count+2);
free((void*) num);
}
if (duration->weeks > 0) {
count = digits_in_number(duration->weeks);
num = (char*) calloc(count+2, sizeof(char));
snprintf(num, count+2, "%uW", (unsigned int) duration->weeks);
str = strncat(str, num, count+2);
free((void*) num);
}
if (duration->days > 0) {
count = digits_in_number(duration->days);
num = (char*) calloc(count+2, sizeof(char));
snprintf(num, count+2, "%uD", (unsigned int) duration->days);
str = strncat(str, num, count+2);
free((void*) num);
}
if (T) {
str = strncat(str, "T", 1);
}
if (duration->hours > 0) {
count = digits_in_number(duration->hours);
num = (char*) calloc(count+2, sizeof(char));
snprintf(num, count+2, "%uH", (unsigned int) duration->hours);
str = strncat(str, num, count+2);
free((void*) num);
}
if (duration->minutes > 0) {
count = digits_in_number(duration->minutes);
num = (char*) calloc(count+2, sizeof(char));
snprintf(num, count+2, "%uM", (unsigned int) duration->minutes);
str = strncat(str, num, count+2);
free((void*) num);
}
if (duration->seconds > 0) {
count = digits_in_number(duration->seconds);
num = (char*) calloc(count+2, sizeof(char));
snprintf(num, count+2, "%uS", (unsigned int) duration->seconds);
str = strncat(str, num, count+2);
free((void*) num);
}
return str;
}
/**
* Convert a duration to a time.
*
*/
time_t
ldns_duration2time(ldns_duration_type* duration)
{
time_t period = 0;
if (duration) {
period += (duration->seconds);
period += (duration->minutes)*60;
period += (duration->hours)*3600;
period += (duration->days)*86400;
period += (duration->weeks)*86400*7;
period += (duration->months)*86400*31;
period += (duration->years)*86400*365;
/* [TODO] calculate correct number of days in this month/year */
/*
if (duration->months || duration->years) {
}
*/
}
return period;
}
/**
* Clean up duration.
*
*/
void
ldns_duration_cleanup(ldns_duration_type* duration)
{
if (!duration) {
return;
}
free(duration);
return;
}

112
contrib/ldns/error.c Normal file
View file

@ -0,0 +1,112 @@
/*
* a error2str function to make sense of all the
* error codes we have laying ardoun
*
* a Net::DNS like library for C
* LibDNS Team @ NLnet Labs
* (c) NLnet Labs, 2005-2006
* See the file LICENSE for the license
*/
#include <ldns/config.h>
#include <ldns/ldns.h>
ldns_lookup_table ldns_error_str[] = {
{ LDNS_STATUS_OK, "All OK" },
{ LDNS_STATUS_EMPTY_LABEL, "Empty label" },
{ LDNS_STATUS_LABEL_OVERFLOW, "Label length overflow" },
{ LDNS_STATUS_DOMAINNAME_OVERFLOW, "Domainname length overflow" },
{ LDNS_STATUS_DOMAINNAME_UNDERFLOW, "Domainname length underflow (zero length)" },
{ LDNS_STATUS_DDD_OVERFLOW, "\\DDD sequence overflow (>255)" },
{ LDNS_STATUS_PACKET_OVERFLOW, "Packet size overflow" },
{ LDNS_STATUS_INVALID_POINTER, "Invalid compression pointer" },
{ LDNS_STATUS_MEM_ERR, "General memory error" },
{ LDNS_STATUS_INTERNAL_ERR, "Internal error, this should not happen" },
{ LDNS_STATUS_SSL_ERR, "Error in SSL library" },
{ LDNS_STATUS_ERR, "General LDNS error" },
{ LDNS_STATUS_INVALID_INT, "Conversion error, integer expected" },
{ LDNS_STATUS_INVALID_IP4, "Conversion error, ip4 addr expected" },
{ LDNS_STATUS_INVALID_IP6, "Conversion error, ip6 addr expected" },
{ LDNS_STATUS_INVALID_STR, "Conversion error, string expected" },
{ LDNS_STATUS_INVALID_B32_EXT, "Conversion error, b32 ext encoding expected" },
{ LDNS_STATUS_INVALID_B64, "Conversion error, b64 encoding expected" },
{ LDNS_STATUS_INVALID_HEX, "Conversion error, hex encoding expected" },
{ LDNS_STATUS_INVALID_TIME, "Conversion error, time encoding expected" },
{ LDNS_STATUS_NETWORK_ERR, "Could not send or receive, because of network error" },
{ LDNS_STATUS_ADDRESS_ERR, "Could not start AXFR, because of address error" },
{ LDNS_STATUS_FILE_ERR, "Could not open the files" },
{ LDNS_STATUS_UNKNOWN_INET, "Uknown address family" },
{ LDNS_STATUS_NOT_IMPL, "This function is not implemented (yet), please notify the developers - or not..." },
{ LDNS_STATUS_NULL, "Supplied value pointer null" },
{ LDNS_STATUS_CRYPTO_UNKNOWN_ALGO, "Unknown cryptographic algorithm" },
{ LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL, "Cryptographic algorithm not implemented" },
{ LDNS_STATUS_CRYPTO_NO_RRSIG, "No DNSSEC signature(s)" },
{ LDNS_STATUS_CRYPTO_NO_DNSKEY, "No DNSSEC public key(s)" },
{ LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR, "The signature does not cover this RRset" },
{ LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY, "No signatures found for trusted DNSSEC public key(s)" },
{ LDNS_STATUS_CRYPTO_NO_DS, "No DS record(s)" },
{ LDNS_STATUS_CRYPTO_NO_TRUSTED_DS, "Could not validate DS record(s)" },
{ LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY, "No keys with the keytag and algorithm from the RRSIG found" },
{ LDNS_STATUS_CRYPTO_VALIDATED, "Valid DNSSEC signature" },
{ LDNS_STATUS_CRYPTO_BOGUS, "Bogus DNSSEC signature" },
{ LDNS_STATUS_CRYPTO_SIG_EXPIRED, "DNSSEC signature has expired" },
{ LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED, "DNSSEC signature not incepted yet" },
{ LDNS_STATUS_CRYPTO_TSIG_BOGUS, "Bogus TSIG signature" },
{ LDNS_STATUS_CRYPTO_TSIG_ERR, "Could not create TSIG signature" },
{ LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION, "DNSSEC signature has expiration date earlier than inception date" },
{ LDNS_STATUS_ENGINE_KEY_NOT_LOADED, "Unable to load private key from engine" },
{ LDNS_STATUS_NSEC3_ERR, "Error in NSEC3 denial of existence proof" },
{ LDNS_STATUS_RES_NO_NS, "No (valid) nameservers defined in the resolver" },
{ LDNS_STATUS_RES_QUERY, "No correct query given to resolver" },
{ LDNS_STATUS_WIRE_INCOMPLETE_HEADER, "header section incomplete" },
{ LDNS_STATUS_WIRE_INCOMPLETE_QUESTION, "question section incomplete" },
{ LDNS_STATUS_WIRE_INCOMPLETE_ANSWER, "answer section incomplete" },
{ LDNS_STATUS_WIRE_INCOMPLETE_AUTHORITY, "authority section incomplete" },
{ LDNS_STATUS_WIRE_INCOMPLETE_ADDITIONAL, "additional section incomplete" },
{ LDNS_STATUS_NO_DATA, "No data" },
{ LDNS_STATUS_CERT_BAD_ALGORITHM, "Bad algorithm type for CERT record" },
{ LDNS_STATUS_SYNTAX_TYPE_ERR, "Syntax error, could not parse the RR's type" },
{ LDNS_STATUS_SYNTAX_CLASS_ERR, "Syntax error, could not parse the RR's class" },
{ LDNS_STATUS_SYNTAX_TTL_ERR, "Syntax error, could not parse the RR's TTL" },
{ LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL, "Syntax error, $INCLUDE not implemented" },
{ LDNS_STATUS_SYNTAX_RDATA_ERR, "Syntax error, could not parse the RR's rdata" },
{ LDNS_STATUS_SYNTAX_DNAME_ERR, "Syntax error, could not parse the RR's dname(s)" },
{ LDNS_STATUS_SYNTAX_VERSION_ERR, "Syntax error, version mismatch" },
{ LDNS_STATUS_SYNTAX_ALG_ERR, "Syntax error, algorithm unknown or non parseable" },
{ LDNS_STATUS_SYNTAX_KEYWORD_ERR, "Syntax error, unknown keyword in input" },
{ LDNS_STATUS_SYNTAX_ERR, "Syntax error, could not parse the RR" },
{ LDNS_STATUS_SYNTAX_EMPTY, "Empty line was returned" },
{ LDNS_STATUS_SYNTAX_TTL, "$TTL directive was seen in the zone" },
{ LDNS_STATUS_SYNTAX_ORIGIN, "$ORIGIN directive was seen in the zone" },
{ LDNS_STATUS_SYNTAX_INCLUDE, "$INCLUDE directive was seen in the zone" },
{ LDNS_STATUS_SYNTAX_ITERATIONS_OVERFLOW, "Iterations count for NSEC3 record higher than maximum" },
{ LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR, "Syntax error, value expected" },
{ LDNS_STATUS_SYNTAX_INTEGER_OVERFLOW, "Syntax error, integer value too large" },
{ LDNS_STATUS_SYNTAX_BAD_ESCAPE, "Syntax error, bad escape sequence" },
{ LDNS_STATUS_SOCKET_ERROR, "Error creating socket" },
{ LDNS_STATUS_DNSSEC_EXISTENCE_DENIED, "Existence denied by NSEC" },
{ LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED, "RR not covered by the given NSEC RRs" },
{ LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED, "wildcard not covered by the given NSEC RRs" },
{ LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND, "original of NSEC3 hashed name could not be found" },
{ LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG, "The RRSIG has to few rdata fields" },
{ LDNS_STATUS_MISSING_RDATA_FIELDS_KEY, "The DNSKEY has to few rdata fields" },
{ LDNS_STATUS_CRYPTO_SIG_EXPIRED_WITHIN_MARGIN,
"DNSSEC signature will expire too soon" },
{ LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED_WITHIN_MARGIN,
"DNSSEC signature not incepted long enough" },
{ 0, NULL }
};
const char *
ldns_get_errorstr_by_id(ldns_status err)
{
ldns_lookup_table *lt;
lt = ldns_lookup_by_id(ldns_error_str, err);
if (lt) {
return lt->name;
}
return NULL;
}

359
contrib/ldns/higher.c Normal file
View file

@ -0,0 +1,359 @@
/*
* higher.c
*
* Specify some higher level functions that would
* be usefull to would be developers
*
* a Net::DNS like library for C
*
* (c) NLnet Labs, 2004-2006
*
* See the file LICENSE for the license
*/
#include <ldns/config.h>
#include <ldns/ldns.h>
#ifdef HAVE_SSL
#include <openssl/ssl.h>
#include <openssl/sha.h>
#endif /* HAVE_SSL */
ldns_rr_list *
ldns_get_rr_list_addr_by_name(ldns_resolver *res, ldns_rdf *name, ldns_rr_class c,
uint16_t flags)
{
ldns_pkt *pkt;
ldns_rr_list *aaaa;
ldns_rr_list *a;
ldns_rr_list *result = NULL;
ldns_rr_list *hostsfilenames;
size_t i;
uint8_t ip6;
a = NULL;
aaaa = NULL;
result = NULL;
if (!res) {
return NULL;
}
if (ldns_rdf_get_type(name) != LDNS_RDF_TYPE_DNAME) {
return NULL;
}
ip6 = ldns_resolver_ip6(res); /* we use INET_ANY here, save
what was there */
ldns_resolver_set_ip6(res, LDNS_RESOLV_INETANY);
hostsfilenames = ldns_get_rr_list_hosts_frm_file(NULL);
for (i = 0; i < ldns_rr_list_rr_count(hostsfilenames); i++) {
if (ldns_rdf_compare(name,
ldns_rr_owner(ldns_rr_list_rr(hostsfilenames,
i))) == 0) {
if (!result) {
result = ldns_rr_list_new();
}
ldns_rr_list_push_rr(result,
ldns_rr_clone(ldns_rr_list_rr(hostsfilenames, i)));
}
}
ldns_rr_list_deep_free(hostsfilenames);
if (result) {
return result;
}
/* add the RD flags, because we want an answer */
pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_AAAA, c, flags | LDNS_RD);
if (pkt) {
/* extract the data we need */
aaaa = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_AAAA,
LDNS_SECTION_ANSWER);
ldns_pkt_free(pkt);
}
pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_A, c, flags | LDNS_RD);
if (pkt) {
/* extract the data we need */
a = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_A, LDNS_SECTION_ANSWER);
ldns_pkt_free(pkt);
}
ldns_resolver_set_ip6(res, ip6);
if (aaaa && a) {
result = ldns_rr_list_cat_clone(aaaa, a);
ldns_rr_list_deep_free(aaaa);
ldns_rr_list_deep_free(a);
return result;
}
if (aaaa) {
result = ldns_rr_list_clone(aaaa);
}
if (a) {
result = ldns_rr_list_clone(a);
}
ldns_rr_list_deep_free(aaaa);
ldns_rr_list_deep_free(a);
return result;
}
ldns_rr_list *
ldns_get_rr_list_name_by_addr(ldns_resolver *res, ldns_rdf *addr, ldns_rr_class c,
uint16_t flags)
{
ldns_pkt *pkt;
ldns_rr_list *names;
ldns_rdf *name;
names = NULL;
if (!res || !addr) {
return NULL;
}
if (ldns_rdf_get_type(addr) != LDNS_RDF_TYPE_A &&
ldns_rdf_get_type(addr) != LDNS_RDF_TYPE_AAAA) {
return NULL;
}
name = ldns_rdf_address_reverse(addr);
/* add the RD flags, because we want an answer */
pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_PTR, c, flags | LDNS_RD);
if (pkt) {
/* extract the data we need */
names = ldns_pkt_rr_list_by_type(pkt,
LDNS_RR_TYPE_PTR, LDNS_SECTION_ANSWER);
}
return names;
}
/* read a line, put it in a buffer, parse the buffer */
ldns_rr_list *
ldns_get_rr_list_hosts_frm_fp(FILE *fp)
{
return ldns_get_rr_list_hosts_frm_fp_l(fp, NULL);
}
ldns_rr_list *
ldns_get_rr_list_hosts_frm_fp_l(FILE *fp, int *line_nr)
{
ssize_t i, j;
size_t cnt;
char *line;
char *word;
char *addr;
char *rr_str;
ldns_buffer *linebuf;
ldns_rr *rr;
ldns_rr_list *list;
ldns_rdf *tmp;
bool ip6;
ldns_status parse_result;
line = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
word = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
addr = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
rr_str = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
ip6 = false;
list = ldns_rr_list_new();
rr = NULL;
if(!line || !word || !addr || !rr_str || !list) {
LDNS_FREE(line);
LDNS_FREE(word);
LDNS_FREE(addr);
LDNS_FREE(rr_str);
ldns_rr_list_free(list);
return NULL;
}
for(i = ldns_fget_token_l(fp, line, "\n", LDNS_MAX_LINELEN, line_nr);
i > 0; i = ldns_fget_token_l(fp, line, "\n", LDNS_MAX_LINELEN, line_nr)) {
/* # is comment */
if (line[0] == '#') {
continue;
}
/* put it in a buffer for further processing */
linebuf = LDNS_MALLOC(ldns_buffer);
if(!linebuf) {
LDNS_FREE(line);
LDNS_FREE(word);
LDNS_FREE(addr);
LDNS_FREE(rr_str);
ldns_rr_list_deep_free(list);
return NULL;
}
ldns_buffer_new_frm_data(linebuf, line, (size_t) i);
for(cnt = 0, j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, LDNS_MAX_LINELEN);
j > 0;
j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, LDNS_MAX_LINELEN), cnt++) {
if (cnt == 0) {
/* the address */
if ((tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA,
word))) {
/* ip6 */
ldns_rdf_deep_free(tmp);
ip6 = true;
} else {
if ((tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A,
word))) {
/* ip4 */
ldns_rdf_deep_free(tmp);
ip6 = false;
} else {
/* kaput */
break;
}
}
(void)strlcpy(addr, word, LDNS_MAX_LINELEN+1);
} else {
/* la al la la */
if (ip6) {
snprintf(rr_str, LDNS_MAX_LINELEN,
"%s IN AAAA %s", word, addr);
} else {
snprintf(rr_str, LDNS_MAX_LINELEN,
"%s IN A %s", word, addr);
}
parse_result = ldns_rr_new_frm_str(&rr, rr_str, 0, NULL, NULL);
if (parse_result == LDNS_STATUS_OK && ldns_rr_owner(rr) && ldns_rr_rd_count(rr) > 0) {
ldns_rr_list_push_rr(list, ldns_rr_clone(rr));
}
ldns_rr_free(rr);
}
}
ldns_buffer_free(linebuf);
}
LDNS_FREE(line);
LDNS_FREE(word);
LDNS_FREE(addr);
LDNS_FREE(rr_str);
return list;
}
ldns_rr_list *
ldns_get_rr_list_hosts_frm_file(char *filename)
{
ldns_rr_list *names;
FILE *fp;
if (!filename) {
fp = fopen(LDNS_RESOLV_HOSTS, "r");
} else {
fp = fopen(filename, "r");
}
if (!fp) {
return NULL;
}
names = ldns_get_rr_list_hosts_frm_fp(fp);
fclose(fp);
return names;
}
uint16_t
ldns_getaddrinfo(ldns_resolver *res, ldns_rdf *node, ldns_rr_class c,
ldns_rr_list **ret)
{
ldns_rdf_type t;
uint16_t names_found;
ldns_resolver *r;
ldns_status s;
t = ldns_rdf_get_type(node);
names_found = 0;
r = res;
if (res == NULL) {
/* prepare a new resolver, using /etc/resolv.conf as a guide */
s = ldns_resolver_new_frm_file(&r, NULL);
if (s != LDNS_STATUS_OK) {
return 0;
}
}
if (t == LDNS_RDF_TYPE_DNAME) {
/* we're asked to query for a name */
*ret = ldns_get_rr_list_addr_by_name(r, node, c, 0);
names_found = ldns_rr_list_rr_count(*ret);
}
if (t == LDNS_RDF_TYPE_A || t == LDNS_RDF_TYPE_AAAA) {
/* an address */
*ret = ldns_get_rr_list_name_by_addr(r, node, c, 0);
names_found = ldns_rr_list_rr_count(*ret);
}
if (res == NULL) {
ldns_resolver_deep_free(r);
}
return names_found;
}
bool
ldns_nsec_type_check(ldns_rr *nsec, ldns_rr_type t)
{
/* does the nsec cover the t given? */
/* copied from host2str.c line 465: ldns_rdf2buffer_str_nsec */
uint8_t window_block_nr;
uint8_t bitmap_length;
uint16_t type;
uint16_t pos = 0;
uint16_t bit_pos;
ldns_rdf *nsec_type_list = ldns_rr_rdf(nsec, 1);
uint8_t *data;
if (nsec_type_list == NULL) {
return false;
}
data = ldns_rdf_data(nsec_type_list);
while(pos < ldns_rdf_size(nsec_type_list)) {
window_block_nr = data[pos];
bitmap_length = data[pos + 1];
pos += 2;
for (bit_pos = 0; bit_pos < (bitmap_length) * 8; bit_pos++) {
if (ldns_get_bit(&data[pos], bit_pos)) {
type = 256 * (uint16_t) window_block_nr + bit_pos;
if ((ldns_rr_type)type == t) {
/* we have a winner */
return true;
}
}
}
pos += (uint16_t) bitmap_length;
}
return false;
}
void
ldns_print_rr_rdf(FILE *fp, ldns_rr *r, int rdfnum, ...)
{
int16_t rdf;
ldns_rdf *rd;
va_list va_rdf;
va_start(va_rdf, rdfnum);
for (rdf = (int16_t)rdfnum; rdf != -1; rdf = (int16_t)va_arg(va_rdf, int))
{
rd = ldns_rr_rdf(r, rdf);
if (!rd) {
continue;
} else {
ldns_rdf_print(fp, rd);
fprintf(fp, " "); /* not sure if we want to do this */
}
}
va_end(va_rdf);
}

2314
contrib/ldns/host2str.c Normal file

File diff suppressed because it is too large Load diff

434
contrib/ldns/host2wire.c Normal file
View file

@ -0,0 +1,434 @@
/*
* host2wire.c
*
* conversion routines from the host to the wire format.
* This will usually just a re-ordering of the
* data (as we store it in network format)
*
* a Net::DNS like library for C
*
* (c) NLnet Labs, 2004-2006
*
* See the file LICENSE for the license
*/
#include <ldns/config.h>
#include <ldns/ldns.h>
/* TODO Jelte
add a pointer to a 'possiblecompression' structure
to all the needed functions?
something like an array of name, pointer values?
every dname part could be added to it
*/
ldns_status
ldns_dname2buffer_wire(ldns_buffer *buffer, const ldns_rdf *name)
{
if (ldns_buffer_reserve(buffer, ldns_rdf_size(name))) {
ldns_buffer_write(buffer, ldns_rdf_data(name), ldns_rdf_size(name));
}
return ldns_buffer_status(buffer);
}
ldns_status
ldns_rdf2buffer_wire(ldns_buffer *buffer, const ldns_rdf *rdf)
{
if (ldns_buffer_reserve(buffer, ldns_rdf_size(rdf))) {
ldns_buffer_write(buffer, ldns_rdf_data(rdf), ldns_rdf_size(rdf));
}
return ldns_buffer_status(buffer);
}
ldns_status
ldns_rdf2buffer_wire_canonical(ldns_buffer *buffer, const ldns_rdf *rdf)
{
size_t i;
uint8_t *rdf_data;
if (ldns_rdf_get_type(rdf) == LDNS_RDF_TYPE_DNAME) {
if (ldns_buffer_reserve(buffer, ldns_rdf_size(rdf))) {
rdf_data = ldns_rdf_data(rdf);
for (i = 0; i < ldns_rdf_size(rdf); i++) {
ldns_buffer_write_u8(buffer,
(uint8_t) LDNS_DNAME_NORMALIZE((int)rdf_data[i]));
}
}
} else {
/* direct copy for all other types */
if (ldns_buffer_reserve(buffer, ldns_rdf_size(rdf))) {
ldns_buffer_write(buffer,
ldns_rdf_data(rdf),
ldns_rdf_size(rdf));
}
}
return ldns_buffer_status(buffer);
}
/* convert a rr list to wireformat */
ldns_status
ldns_rr_list2buffer_wire(ldns_buffer *buffer,const ldns_rr_list *rr_list)
{
uint16_t rr_count;
uint16_t i;
rr_count = ldns_rr_list_rr_count(rr_list);
for(i = 0; i < rr_count; i++) {
(void)ldns_rr2buffer_wire(buffer, ldns_rr_list_rr(rr_list, i),
LDNS_SECTION_ANY);
}
return ldns_buffer_status(buffer);
}
ldns_status
ldns_rr2buffer_wire_canonical(ldns_buffer *buffer,
const ldns_rr *rr,
int section)
{
uint16_t i;
uint16_t rdl_pos = 0;
bool pre_rfc3597 = false;
switch (ldns_rr_get_type(rr)) {
case LDNS_RR_TYPE_NS:
case LDNS_RR_TYPE_MD:
case LDNS_RR_TYPE_MF:
case LDNS_RR_TYPE_CNAME:
case LDNS_RR_TYPE_SOA:
case LDNS_RR_TYPE_MB:
case LDNS_RR_TYPE_MG:
case LDNS_RR_TYPE_MR:
case LDNS_RR_TYPE_PTR:
case LDNS_RR_TYPE_HINFO:
case LDNS_RR_TYPE_MINFO:
case LDNS_RR_TYPE_MX:
case LDNS_RR_TYPE_RP:
case LDNS_RR_TYPE_AFSDB:
case LDNS_RR_TYPE_RT:
case LDNS_RR_TYPE_SIG:
case LDNS_RR_TYPE_PX:
case LDNS_RR_TYPE_NXT:
case LDNS_RR_TYPE_NAPTR:
case LDNS_RR_TYPE_KX:
case LDNS_RR_TYPE_SRV:
case LDNS_RR_TYPE_DNAME:
case LDNS_RR_TYPE_A6:
case LDNS_RR_TYPE_RRSIG:
pre_rfc3597 = true;
break;
default:
break;
}
if (ldns_rr_owner(rr)) {
(void) ldns_rdf2buffer_wire_canonical(buffer, ldns_rr_owner(rr));
}
if (ldns_buffer_reserve(buffer, 4)) {
(void) ldns_buffer_write_u16(buffer, ldns_rr_get_type(rr));
(void) ldns_buffer_write_u16(buffer, ldns_rr_get_class(rr));
}
if (section != LDNS_SECTION_QUESTION) {
if (ldns_buffer_reserve(buffer, 6)) {
ldns_buffer_write_u32(buffer, ldns_rr_ttl(rr));
/* remember pos for later */
rdl_pos = ldns_buffer_position(buffer);
ldns_buffer_write_u16(buffer, 0);
}
for (i = 0; i < ldns_rr_rd_count(rr); i++) {
if (pre_rfc3597) {
(void) ldns_rdf2buffer_wire_canonical(
buffer, ldns_rr_rdf(rr, i));
} else {
(void) ldns_rdf2buffer_wire(
buffer, ldns_rr_rdf(rr, i));
}
}
if (rdl_pos != 0) {
ldns_buffer_write_u16_at(buffer, rdl_pos,
ldns_buffer_position(buffer)
- rdl_pos - 2);
}
}
return ldns_buffer_status(buffer);
}
ldns_status
ldns_rr2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr, int section)
{
uint16_t i;
uint16_t rdl_pos = 0;
if (ldns_rr_owner(rr)) {
(void) ldns_dname2buffer_wire(buffer, ldns_rr_owner(rr));
}
if (ldns_buffer_reserve(buffer, 4)) {
(void) ldns_buffer_write_u16(buffer, ldns_rr_get_type(rr));
(void) ldns_buffer_write_u16(buffer, ldns_rr_get_class(rr));
}
if (section != LDNS_SECTION_QUESTION) {
if (ldns_buffer_reserve(buffer, 6)) {
ldns_buffer_write_u32(buffer, ldns_rr_ttl(rr));
/* remember pos for later */
rdl_pos = ldns_buffer_position(buffer);
ldns_buffer_write_u16(buffer, 0);
}
for (i = 0; i < ldns_rr_rd_count(rr); i++) {
(void) ldns_rdf2buffer_wire(
buffer, ldns_rr_rdf(rr, i));
}
if (rdl_pos != 0) {
ldns_buffer_write_u16_at(buffer, rdl_pos,
ldns_buffer_position(buffer)
- rdl_pos - 2);
}
}
return ldns_buffer_status(buffer);
}
ldns_status
ldns_rrsig2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr)
{
uint16_t i;
/* it must be a sig RR */
if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG) {
return LDNS_STATUS_ERR;
}
/* Convert all the rdfs, except the actual signature data
* rdf number 8 - the last, hence: -1 */
for (i = 0; i < ldns_rr_rd_count(rr) - 1; i++) {
(void) ldns_rdf2buffer_wire_canonical(buffer, ldns_rr_rdf(rr, i));
}
return ldns_buffer_status(buffer);
}
ldns_status
ldns_rr_rdata2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr)
{
uint16_t i;
/* convert all the rdf's */
for (i = 0; i < ldns_rr_rd_count(rr); i++) {
(void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr, i));
}
return ldns_buffer_status(buffer);
}
/*
* Copies the packet header data to the buffer in wire format
*/
static ldns_status
ldns_hdr2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet)
{
uint8_t flags;
uint16_t arcount;
if (ldns_buffer_reserve(buffer, 12)) {
ldns_buffer_write_u16(buffer, ldns_pkt_id(packet));
flags = ldns_pkt_qr(packet) << 7
| ldns_pkt_get_opcode(packet) << 3
| ldns_pkt_aa(packet) << 2
| ldns_pkt_tc(packet) << 1 | ldns_pkt_rd(packet);
ldns_buffer_write_u8(buffer, flags);
flags = ldns_pkt_ra(packet) << 7
/*| ldns_pkt_z(packet) << 6*/
| ldns_pkt_ad(packet) << 5
| ldns_pkt_cd(packet) << 4 | ldns_pkt_get_rcode(packet);
ldns_buffer_write_u8(buffer, flags);
ldns_buffer_write_u16(buffer, ldns_pkt_qdcount(packet));
ldns_buffer_write_u16(buffer, ldns_pkt_ancount(packet));
ldns_buffer_write_u16(buffer, ldns_pkt_nscount(packet));
/* add EDNS0 and TSIG to additional if they are there */
arcount = ldns_pkt_arcount(packet);
if (ldns_pkt_tsig(packet)) {
arcount++;
}
if (ldns_pkt_edns(packet)) {
arcount++;
}
ldns_buffer_write_u16(buffer, arcount);
}
return ldns_buffer_status(buffer);
}
ldns_status
ldns_pkt2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet)
{
ldns_rr_list *rr_list;
uint16_t i;
/* edns tmp vars */
ldns_rr *edns_rr;
uint8_t edata[4];
(void) ldns_hdr2buffer_wire(buffer, packet);
rr_list = ldns_pkt_question(packet);
if (rr_list) {
for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
(void) ldns_rr2buffer_wire(buffer,
ldns_rr_list_rr(rr_list, i), LDNS_SECTION_QUESTION);
}
}
rr_list = ldns_pkt_answer(packet);
if (rr_list) {
for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
(void) ldns_rr2buffer_wire(buffer,
ldns_rr_list_rr(rr_list, i), LDNS_SECTION_ANSWER);
}
}
rr_list = ldns_pkt_authority(packet);
if (rr_list) {
for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
(void) ldns_rr2buffer_wire(buffer,
ldns_rr_list_rr(rr_list, i), LDNS_SECTION_AUTHORITY);
}
}
rr_list = ldns_pkt_additional(packet);
if (rr_list) {
for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
(void) ldns_rr2buffer_wire(buffer,
ldns_rr_list_rr(rr_list, i), LDNS_SECTION_ADDITIONAL);
}
}
/* add EDNS to additional if it is needed */
if (ldns_pkt_edns(packet)) {
edns_rr = ldns_rr_new();
if(!edns_rr) return LDNS_STATUS_MEM_ERR;
ldns_rr_set_owner(edns_rr,
ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, "."));
ldns_rr_set_type(edns_rr, LDNS_RR_TYPE_OPT);
ldns_rr_set_class(edns_rr, ldns_pkt_edns_udp_size(packet));
edata[0] = ldns_pkt_edns_extended_rcode(packet);
edata[1] = ldns_pkt_edns_version(packet);
ldns_write_uint16(&edata[2], ldns_pkt_edns_z(packet));
ldns_rr_set_ttl(edns_rr, ldns_read_uint32(edata));
/* don't forget to add the edns rdata (if any) */
if (packet->_edns_data)
ldns_rr_push_rdf (edns_rr, packet->_edns_data);
(void)ldns_rr2buffer_wire(buffer, edns_rr, LDNS_SECTION_ADDITIONAL);
/* take the edns rdata back out of the rr before we free rr */
if (packet->_edns_data)
(void)ldns_rr_pop_rdf (edns_rr);
ldns_rr_free(edns_rr);
}
/* add TSIG to additional if it is there */
if (ldns_pkt_tsig(packet)) {
(void) ldns_rr2buffer_wire(buffer,
ldns_pkt_tsig(packet), LDNS_SECTION_ADDITIONAL);
}
return LDNS_STATUS_OK;
}
ldns_status
ldns_rdf2wire(uint8_t **dest, const ldns_rdf *rdf, size_t *result_size)
{
ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
uint8_t *result = NULL;
ldns_status status;
*result_size = 0;
*dest = NULL;
if(!buffer) return LDNS_STATUS_MEM_ERR;
status = ldns_rdf2buffer_wire(buffer, rdf);
if (status == LDNS_STATUS_OK) {
*result_size = ldns_buffer_position(buffer);
result = (uint8_t *) ldns_buffer_export(buffer);
} else {
ldns_buffer_free(buffer);
return status;
}
if (result) {
*dest = LDNS_XMALLOC(uint8_t, ldns_buffer_position(buffer));
if(!*dest) {
ldns_buffer_free(buffer);
return LDNS_STATUS_MEM_ERR;
}
memcpy(*dest, result, ldns_buffer_position(buffer));
}
ldns_buffer_free(buffer);
return status;
}
ldns_status
ldns_rr2wire(uint8_t **dest, const ldns_rr *rr, int section, size_t *result_size)
{
ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
uint8_t *result = NULL;
ldns_status status;
*result_size = 0;
*dest = NULL;
if(!buffer) return LDNS_STATUS_MEM_ERR;
status = ldns_rr2buffer_wire(buffer, rr, section);
if (status == LDNS_STATUS_OK) {
*result_size = ldns_buffer_position(buffer);
result = (uint8_t *) ldns_buffer_export(buffer);
} else {
ldns_buffer_free(buffer);
return status;
}
if (result) {
*dest = LDNS_XMALLOC(uint8_t, ldns_buffer_position(buffer));
if(!*dest) {
ldns_buffer_free(buffer);
return LDNS_STATUS_MEM_ERR;
}
memcpy(*dest, result, ldns_buffer_position(buffer));
}
ldns_buffer_free(buffer);
return status;
}
ldns_status
ldns_pkt2wire(uint8_t **dest, const ldns_pkt *packet, size_t *result_size)
{
ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
uint8_t *result = NULL;
ldns_status status;
*result_size = 0;
*dest = NULL;
if(!buffer) return LDNS_STATUS_MEM_ERR;
status = ldns_pkt2buffer_wire(buffer, packet);
if (status == LDNS_STATUS_OK) {
*result_size = ldns_buffer_position(buffer);
result = (uint8_t *) ldns_buffer_export(buffer);
} else {
ldns_buffer_free(buffer);
return status;
}
if (result) {
*dest = LDNS_XMALLOC(uint8_t, ldns_buffer_position(buffer));
if(!*dest) {
ldns_buffer_free(buffer);
return LDNS_STATUS_MEM_ERR;
}
memcpy(*dest, result, ldns_buffer_position(buffer));
}
ldns_buffer_free(buffer);
return status;
}

527
contrib/ldns/install-sh Executable file
View file

@ -0,0 +1,527 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2011-01-19.21; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
nl='
'
IFS=" "" $nl"
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
if test -z "$doit"; then
doit_exec=exec
else
doit_exec=$doit
fi
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_glob='?'
initialize_posix_glob='
test "$posix_glob" != "?" || {
if (set -f) 2>/dev/null; then
posix_glob=
else
posix_glob=:
fi
}
'
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
no_target_directory=
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *' '* | *'
'* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-t) dst_arg=$2
# Protect names problematic for `test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) no_target_directory=true;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for `test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call `install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for `test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
# Prefer dirname, but fall back on a substitute if dirname fails.
dstdir=`
(dirname "$dst") 2>/dev/null ||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$dst" : 'X\(//\)[^/]' \| \
X"$dst" : 'X\(//\)$' \| \
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
echo X"$dst" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'
`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writeable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
eval "$initialize_posix_glob"
oIFS=$IFS
IFS=/
$posix_glob set -f
set fnord $dstdir
shift
$posix_glob set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
eval "$initialize_posix_glob" &&
$posix_glob set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
$posix_glob set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

1693
contrib/ldns/keys.c Normal file

File diff suppressed because it is too large Load diff

644
contrib/ldns/ldns/buffer.h Normal file
View file

@ -0,0 +1,644 @@
/*
* buffer.h -- generic memory buffer.
*
* Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
*
* See LICENSE for the license.
*
*
* The buffer module implements a generic buffer. The API is based on
* the java.nio.Buffer interface.
*/
#ifndef LDNS_BUFFER_H
#define LDNS_BUFFER_H
#include <assert.h>
#include <stdarg.h>
#include <string.h>
#include <ldns/error.h>
#include <ldns/common.h>
#include "ldns/util.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* number of initial bytes in buffer of
* which we cannot tell the size before hand
*/
#define LDNS_MIN_BUFLEN 512
/**
* \file buffer.h
*
* This file contains the definition of ldns_buffer, and functions to manipulate those.
*/
/**
* implementation of buffers to ease operations
*
* ldns_buffers can contain arbitrary information, per octet. You can write
* to the current end of a buffer, read from the current position, and
* access any data within it.
*
* Example use of buffers is in the source code of \ref host2str.c
*/
struct ldns_struct_buffer
{
/** The current position used for reading/writing */
size_t _position;
/** The read/write limit */
size_t _limit;
/** The amount of data the buffer can contain */
size_t _capacity;
/** The data contained in the buffer */
uint8_t *_data;
/** If the buffer is fixed it cannot be resized */
unsigned _fixed : 1;
/** The current state of the buffer. If writing to the buffer fails
* for any reason, this value is changed. This way, you can perform
* multiple writes in sequence and check for success afterwards. */
ldns_status _status;
};
typedef struct ldns_struct_buffer ldns_buffer;
#ifdef NDEBUG
INLINE void
ldns_buffer_invariant(ldns_buffer *ATTR_UNUSED(buffer))
{
}
#else
INLINE void
ldns_buffer_invariant(ldns_buffer *buffer)
{
assert(buffer != NULL);
assert(buffer->_position <= buffer->_limit);
assert(buffer->_limit <= buffer->_capacity);
assert(buffer->_data != NULL);
}
#endif
/**
* creates a new buffer with the specified capacity.
*
* \param[in] capacity the size (in bytes) to allocate for the buffer
* \return the created buffer
*/
ldns_buffer *ldns_buffer_new(size_t capacity);
/**
* creates a buffer with the specified data. The data IS copied
* and MEMORY allocations are done. The buffer is not fixed and can
* be resized using buffer_reserve().
*
* \param[in] buffer pointer to the buffer to put the data in
* \param[in] data the data to encapsulate in the buffer
* \param[in] size the size of the data
*/
void ldns_buffer_new_frm_data(ldns_buffer *buffer, void *data, size_t size);
/**
* clears the buffer and make it ready for writing. The buffer's limit
* is set to the capacity and the position is set to 0.
* \param[in] buffer the buffer to clear
*/
INLINE void ldns_buffer_clear(ldns_buffer *buffer)
{
ldns_buffer_invariant(buffer);
/* reset status here? */
buffer->_position = 0;
buffer->_limit = buffer->_capacity;
}
/**
* makes the buffer ready for reading the data that has been written to
* the buffer. The buffer's limit is set to the current position and
* the position is set to 0.
*
* \param[in] buffer the buffer to flip
* \return void
*/
INLINE void ldns_buffer_flip(ldns_buffer *buffer)
{
ldns_buffer_invariant(buffer);
buffer->_limit = buffer->_position;
buffer->_position = 0;
}
/**
* make the buffer ready for re-reading the data. The buffer's
* position is reset to 0.
* \param[in] buffer the buffer to rewind
*/
INLINE void ldns_buffer_rewind(ldns_buffer *buffer)
{
ldns_buffer_invariant(buffer);
buffer->_position = 0;
}
/**
* returns the current position in the buffer (as a number of bytes)
* \param[in] buffer the buffer
* \return the current position
*/
INLINE size_t
ldns_buffer_position(ldns_buffer *buffer)
{
return buffer->_position;
}
/**
* sets the buffer's position to MARK. The position must be less than
* or equal to the buffer's limit.
* \param[in] buffer the buffer
* \param[in] mark the mark to use
*/
INLINE void
ldns_buffer_set_position(ldns_buffer *buffer, size_t mark)
{
assert(mark <= buffer->_limit);
buffer->_position = mark;
}
/**
* changes the buffer's position by COUNT bytes. The position must not
* be moved behind the buffer's limit or before the beginning of the
* buffer.
* \param[in] buffer the buffer
* \param[in] count the count to use
*/
INLINE void
ldns_buffer_skip(ldns_buffer *buffer, ssize_t count)
{
assert(buffer->_position + count <= buffer->_limit);
buffer->_position += count;
}
/**
* returns the maximum size of the buffer
* \param[in] buffer
* \return the size
*/
INLINE size_t
ldns_buffer_limit(ldns_buffer *buffer)
{
return buffer->_limit;
}
/**
* changes the buffer's limit. If the buffer's position is greater
* than the new limit the position is set to the limit.
* \param[in] buffer the buffer
* \param[in] limit the new limit
*/
INLINE void
ldns_buffer_set_limit(ldns_buffer *buffer, size_t limit)
{
assert(limit <= buffer->_capacity);
buffer->_limit = limit;
if (buffer->_position > buffer->_limit)
buffer->_position = buffer->_limit;
}
/**
* returns the number of bytes the buffer can hold.
* \param[in] buffer the buffer
* \return the number of bytes
*/
INLINE size_t
ldns_buffer_capacity(ldns_buffer *buffer)
{
return buffer->_capacity;
}
/**
* changes the buffer's capacity. The data is reallocated so any
* pointers to the data may become invalid. The buffer's limit is set
* to the buffer's new capacity.
* \param[in] buffer the buffer
* \param[in] capacity the capacity to use
* \return whether this failed or succeeded
*/
bool ldns_buffer_set_capacity(ldns_buffer *buffer, size_t capacity);
/**
* ensures BUFFER can contain at least AMOUNT more bytes. The buffer's
* capacity is increased if necessary using buffer_set_capacity().
*
* The buffer's limit is always set to the (possibly increased)
* capacity.
* \param[in] buffer the buffer
* \param[in] amount amount to use
* \return whether this failed or succeeded
*/
bool ldns_buffer_reserve(ldns_buffer *buffer, size_t amount);
/**
* returns a pointer to the data at the indicated position.
* \param[in] buffer the buffer
* \param[in] at position
* \return the pointer to the data
*/
INLINE uint8_t *
ldns_buffer_at(const ldns_buffer *buffer, size_t at)
{
assert(at <= buffer->_limit);
return buffer->_data + at;
}
/**
* returns a pointer to the beginning of the buffer (the data at
* position 0).
* \param[in] buffer the buffer
* \return the pointer
*/
INLINE uint8_t *
ldns_buffer_begin(const ldns_buffer *buffer)
{
return ldns_buffer_at(buffer, 0);
}
/**
* returns a pointer to the end of the buffer (the data at the buffer's
* limit).
* \param[in] buffer the buffer
* \return the pointer
*/
INLINE uint8_t *
ldns_buffer_end(ldns_buffer *buffer)
{
return ldns_buffer_at(buffer, buffer->_limit);
}
/**
* returns a pointer to the data at the buffer's current position.
* \param[in] buffer the buffer
* \return the pointer
*/
INLINE uint8_t *
ldns_buffer_current(ldns_buffer *buffer)
{
return ldns_buffer_at(buffer, buffer->_position);
}
/**
* returns the number of bytes remaining between the indicated position and
* the limit.
* \param[in] buffer the buffer
* \param[in] at indicated position
* \return number of bytes
*/
INLINE size_t
ldns_buffer_remaining_at(ldns_buffer *buffer, size_t at)
{
ldns_buffer_invariant(buffer);
assert(at <= buffer->_limit);
return buffer->_limit - at;
}
/**
* returns the number of bytes remaining between the buffer's position and
* limit.
* \param[in] buffer the buffer
* \return the number of bytes
*/
INLINE size_t
ldns_buffer_remaining(ldns_buffer *buffer)
{
return ldns_buffer_remaining_at(buffer, buffer->_position);
}
/**
* checks if the buffer has at least COUNT more bytes available.
* Before reading or writing the caller needs to ensure enough space
* is available!
* \param[in] buffer the buffer
* \param[in] at indicated position
* \param[in] count how much is available
* \return true or false (as int?)
*/
INLINE int
ldns_buffer_available_at(ldns_buffer *buffer, size_t at, size_t count)
{
return count <= ldns_buffer_remaining_at(buffer, at);
}
/**
* checks if the buffer has count bytes available at the current position
* \param[in] buffer the buffer
* \param[in] count how much is available
* \return true or false (as int?)
*/
INLINE int
ldns_buffer_available(ldns_buffer *buffer, size_t count)
{
return ldns_buffer_available_at(buffer, buffer->_position, count);
}
/**
* writes the given data to the buffer at the specified position
* \param[in] buffer the buffer
* \param[in] at the position (in number of bytes) to write the data at
* \param[in] data pointer to the data to write to the buffer
* \param[in] count the number of bytes of data to write
*/
INLINE void
ldns_buffer_write_at(ldns_buffer *buffer, size_t at, const void *data, size_t count)
{
assert(ldns_buffer_available_at(buffer, at, count));
memcpy(buffer->_data + at, data, count);
}
/**
* writes count bytes of data to the current position of the buffer
* \param[in] buffer the buffer
* \param[in] data the data to write
* \param[in] count the lenght of the data to write
*/
INLINE void
ldns_buffer_write(ldns_buffer *buffer, const void *data, size_t count)
{
ldns_buffer_write_at(buffer, buffer->_position, data, count);
buffer->_position += count;
}
/**
* copies the given (null-delimited) string to the specified position at the buffer
* \param[in] buffer the buffer
* \param[in] at the position in the buffer
* \param[in] str the string to write
*/
INLINE void
ldns_buffer_write_string_at(ldns_buffer *buffer, size_t at, const char *str)
{
ldns_buffer_write_at(buffer, at, str, strlen(str));
}
/**
* copies the given (null-delimited) string to the current position at the buffer
* \param[in] buffer the buffer
* \param[in] str the string to write
*/
INLINE void
ldns_buffer_write_string(ldns_buffer *buffer, const char *str)
{
ldns_buffer_write(buffer, str, strlen(str));
}
/**
* writes the given byte of data at the given position in the buffer
* \param[in] buffer the buffer
* \param[in] at the position in the buffer
* \param[in] data the 8 bits to write
*/
INLINE void
ldns_buffer_write_u8_at(ldns_buffer *buffer, size_t at, uint8_t data)
{
assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
buffer->_data[at] = data;
}
/**
* writes the given byte of data at the current position in the buffer
* \param[in] buffer the buffer
* \param[in] data the 8 bits to write
*/
INLINE void
ldns_buffer_write_u8(ldns_buffer *buffer, uint8_t data)
{
ldns_buffer_write_u8_at(buffer, buffer->_position, data);
buffer->_position += sizeof(data);
}
/**
* writes the given 2 byte integer at the given position in the buffer
* \param[in] buffer the buffer
* \param[in] at the position in the buffer
* \param[in] data the 16 bits to write
*/
INLINE void
ldns_buffer_write_u16_at(ldns_buffer *buffer, size_t at, uint16_t data)
{
assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
ldns_write_uint16(buffer->_data + at, data);
}
/**
* writes the given 2 byte integer at the current position in the buffer
* \param[in] buffer the buffer
* \param[in] data the 16 bits to write
*/
INLINE void
ldns_buffer_write_u16(ldns_buffer *buffer, uint16_t data)
{
ldns_buffer_write_u16_at(buffer, buffer->_position, data);
buffer->_position += sizeof(data);
}
/**
* writes the given 4 byte integer at the given position in the buffer
* \param[in] buffer the buffer
* \param[in] at the position in the buffer
* \param[in] data the 32 bits to write
*/
INLINE void
ldns_buffer_write_u32_at(ldns_buffer *buffer, size_t at, uint32_t data)
{
assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
ldns_write_uint32(buffer->_data + at, data);
}
/**
* writes the given 4 byte integer at the current position in the buffer
* \param[in] buffer the buffer
* \param[in] data the 32 bits to write
*/
INLINE void
ldns_buffer_write_u32(ldns_buffer *buffer, uint32_t data)
{
ldns_buffer_write_u32_at(buffer, buffer->_position, data);
buffer->_position += sizeof(data);
}
/**
* copies count bytes of data at the given position to the given data-array
* \param[in] buffer the buffer
* \param[in] at the position in the buffer to start
* \param[out] data buffer to copy to
* \param[in] count the length of the data to copy
*/
INLINE void
ldns_buffer_read_at(ldns_buffer *buffer, size_t at, void *data, size_t count)
{
assert(ldns_buffer_available_at(buffer, at, count));
memcpy(data, buffer->_data + at, count);
}
/**
* copies count bytes of data at the current position to the given data-array
* \param[in] buffer the buffer
* \param[out] data buffer to copy to
* \param[in] count the length of the data to copy
*/
INLINE void
ldns_buffer_read(ldns_buffer *buffer, void *data, size_t count)
{
ldns_buffer_read_at(buffer, buffer->_position, data, count);
buffer->_position += count;
}
/**
* returns the byte value at the given position in the buffer
* \param[in] buffer the buffer
* \param[in] at the position in the buffer
* \return 1 byte integer
*/
INLINE uint8_t
ldns_buffer_read_u8_at(ldns_buffer *buffer, size_t at)
{
assert(ldns_buffer_available_at(buffer, at, sizeof(uint8_t)));
return buffer->_data[at];
}
/**
* returns the byte value at the current position in the buffer
* \param[in] buffer the buffer
* \return 1 byte integer
*/
INLINE uint8_t
ldns_buffer_read_u8(ldns_buffer *buffer)
{
uint8_t result = ldns_buffer_read_u8_at(buffer, buffer->_position);
buffer->_position += sizeof(uint8_t);
return result;
}
/**
* returns the 2-byte integer value at the given position in the buffer
* \param[in] buffer the buffer
* \param[in] at position in the buffer
* \return 2 byte integer
*/
INLINE uint16_t
ldns_buffer_read_u16_at(ldns_buffer *buffer, size_t at)
{
assert(ldns_buffer_available_at(buffer, at, sizeof(uint16_t)));
return ldns_read_uint16(buffer->_data + at);
}
/**
* returns the 2-byte integer value at the current position in the buffer
* \param[in] buffer the buffer
* \return 2 byte integer
*/
INLINE uint16_t
ldns_buffer_read_u16(ldns_buffer *buffer)
{
uint16_t result = ldns_buffer_read_u16_at(buffer, buffer->_position);
buffer->_position += sizeof(uint16_t);
return result;
}
/**
* returns the 4-byte integer value at the given position in the buffer
* \param[in] buffer the buffer
* \param[in] at position in the buffer
* \return 4 byte integer
*/
INLINE uint32_t
ldns_buffer_read_u32_at(ldns_buffer *buffer, size_t at)
{
assert(ldns_buffer_available_at(buffer, at, sizeof(uint32_t)));
return ldns_read_uint32(buffer->_data + at);
}
/**
* returns the 4-byte integer value at the current position in the buffer
* \param[in] buffer the buffer
* \return 4 byte integer
*/
INLINE uint32_t
ldns_buffer_read_u32(ldns_buffer *buffer)
{
uint32_t result = ldns_buffer_read_u32_at(buffer, buffer->_position);
buffer->_position += sizeof(uint32_t);
return result;
}
/**
* returns the status of the buffer
* \param[in] buffer
* \return the status
*/
INLINE ldns_status
ldns_buffer_status(ldns_buffer *buffer)
{
return buffer->_status;
}
/**
* returns true if the status of the buffer is LDNS_STATUS_OK, false otherwise
* \param[in] buffer the buffer
* \return true or false
*/
INLINE bool
ldns_buffer_status_ok(ldns_buffer *buffer)
{
if (buffer) {
return ldns_buffer_status(buffer) == LDNS_STATUS_OK;
} else {
return false;
}
}
/**
* prints to the buffer, increasing the capacity if required using
* buffer_reserve(). The buffer's position is set to the terminating '\\0'
* Returns the number of characters written (not including the
* terminating '\\0') or -1 on failure.
*/
int ldns_buffer_printf(ldns_buffer *buffer, const char *format, ...);
/* ATTR_FORMAT(printf, 2, 3);*/
/**
* frees the buffer.
* \param[in] *buffer the buffer to be freed
* \return void
*/
void ldns_buffer_free(ldns_buffer *buffer);
/**
* Makes the buffer fixed and returns a pointer to the data. The
* caller is responsible for free'ing the result.
* \param[in] *buffer the buffer to be exported
* \return void
*/
void *ldns_buffer_export(ldns_buffer *buffer);
/**
* Copy contents of the other buffer to this buffer. Silently truncated
* if this buffer is too small.
* \param[out] *result resulting buffer which is copied to.
* \param[in] *from what to copy to result.
*/
void ldns_buffer_copy(ldns_buffer* result, ldns_buffer* from);
#ifdef __cplusplus
}
#endif
#endif /* LDNS_BUFFER_H */

View file

@ -0,0 +1,68 @@
/**
* \file common.h
*
* Common definitions for LDNS
*/
/**
* a Net::DNS like library for C
*
* (c) NLnet Labs, 2004-2006
*
* See the file LICENSE for the license
*/
#ifndef LDNS_COMMON_H
#define LDNS_COMMON_H
/*
* The build configuration that is used in the distributed headers,
* as detected and determined by the auto configure script.
*/
#define LDNS_BUILD_CONFIG_HAVE_SSL @ldns_build_config_have_ssl@
#define LDNS_BUILD_CONFIG_HAVE_INTTYPES_H @ldns_build_config_have_inttypes_h@
#define LDNS_BUILD_CONFIG_HAVE_ATTR_FORMAT @ldns_build_config_have_attr_format@
#define LDNS_BUILD_CONFIG_HAVE_ATTR_UNUSED @ldns_build_config_have_attr_unused@
/*
* HAVE_STDBOOL_H is not available when distributed as a library, but no build
* configuration variables may be used (like those above) because the header
* is sometimes only available when using special compiler flags to enable the
* c99 environment. Because we cannot force the usage of this flag, we have to
* provide a default type. Below what is suggested by the autoconf manual.
*/
/*@ignore@*/
/* splint barfs on this construct */
#ifdef HAVE_STDBOOL_H
# include <stdbool.h>
#else
# ifndef HAVE__BOOL
# ifdef __cplusplus
typedef bool _Bool;
# else
# define _Bool signed char
# endif
# endif
# define bool _Bool
# define false 0
# define true 1
# define __bool_true_false_are_defined 1
#endif
/*@end@*/
#if LDNS_BUILD_CONFIG_HAVE_ATTR_FORMAT
#define ATTR_FORMAT(archetype, string_index, first_to_check) \
__attribute__ ((format (archetype, string_index, first_to_check)))
#else /* !LDNS_BUILD_CONFIG_HAVE_ATTR_FORMAT */
#define ATTR_FORMAT(archetype, string_index, first_to_check) /* empty */
#endif /* !LDNS_BUILD_CONFIG_HAVE_ATTR_FORMAT */
#if defined(__cplusplus)
#define ATTR_UNUSED(x)
#elif LDNS_BUILD_CONFIG_HAVE_ATTR_UNUSED
#define ATTR_UNUSED(x) x __attribute__((unused))
#else /* !LDNS_BUILD_CONFIG_HAVE_ATTR_UNUSED */
#define ATTR_UNUSED(x) x
#endif /* !LDNS_BUILD_CONFIG_HAVE_ATTR_UNUSED */
#endif /* LDNS_COMMON_H */

View file

@ -0,0 +1,555 @@
/* ldns/config.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD
/* Define to 1 if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H
/* Whether the C compiler accepts the "format" attribute */
#undef HAVE_ATTR_FORMAT
/* Whether the C compiler accepts the "unused" attribute */
#undef HAVE_ATTR_UNUSED
/* Define to 1 if you have the `b32_ntop' function. */
#undef HAVE_B32_NTOP
/* Define to 1 if you have the `b32_pton' function. */
#undef HAVE_B32_PTON
/* Define to 1 if you have the `b64_ntop' function. */
#undef HAVE_B64_NTOP
/* Define to 1 if you have the `b64_pton' function. */
#undef HAVE_B64_PTON
/* Define to 1 if you have the `bzero' function. */
#undef HAVE_BZERO
/* Define to 1 if you have the `calloc' function. */
#undef HAVE_CALLOC
/* Define to 1 if you have the `ctime_r' function. */
#undef HAVE_CTIME_R
/* Define to 1 if you have the declaration of `NID_secp384r1', and to 0 if you
don't. */
#undef HAVE_DECL_NID_SECP384R1
/* Define to 1 if you have the declaration of `NID_X9_62_prime256v1', and to 0
if you don't. */
#undef HAVE_DECL_NID_X9_62_PRIME256V1
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the `endprotoent' function. */
#undef HAVE_ENDPROTOENT
/* Define to 1 if you have the `endservent' function. */
#undef HAVE_ENDSERVENT
/* Define to 1 if you have the `EVP_sha256' function. */
#undef HAVE_EVP_SHA256
/* Define to 1 if you have the `fcntl' function. */
#undef HAVE_FCNTL
/* Define to 1 if you have the `fork' function. */
#undef HAVE_FORK
/* Whether getaddrinfo is available */
#undef HAVE_GETADDRINFO
/* Define to 1 if you have the <getopt.h> header file. */
#undef HAVE_GETOPT_H
/* Define to 1 if you have the `gmtime_r' function. */
#undef HAVE_GMTIME_R
/* If you have HMAC_CTX_init */
#undef HAVE_HMAC_CTX_INIT
/* Define to 1 if you have the `inet_aton' function. */
#undef HAVE_INET_ATON
/* Define to 1 if you have the `inet_ntop' function. */
#undef HAVE_INET_NTOP
/* Define to 1 if you have the `inet_pton' function. */
#undef HAVE_INET_PTON
/* Define to 1 if the system has the type `intptr_t'. */
#undef HAVE_INTPTR_T
/* define if you have inttypes.h */
#undef HAVE_INTTYPES_H
/* if the function 'ioctlsocket' is available */
#undef HAVE_IOCTLSOCKET
/* Define to 1 if you have the `isascii' function. */
#undef HAVE_ISASCII
/* Define to 1 if you have the `isblank' function. */
#undef HAVE_ISBLANK
/* Define to 1 if you have the `pcap' library (-lpcap). */
#undef HAVE_LIBPCAP
/* Define to 1 if you have the `localtime_r' function. */
#undef HAVE_LOCALTIME_R
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#undef HAVE_MALLOC
/* Define to 1 if you have the `memmove' function. */
#undef HAVE_MEMMOVE
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `memset' function. */
#undef HAVE_MEMSET
/* Define to 1 if you have the <netdb.h> header file. */
#undef HAVE_NETDB_H
/* Define to 1 if you have the <netinet/if_ether.h> header file. */
#undef HAVE_NETINET_IF_ETHER_H
/* Define to 1 if you have the <netinet/igmp.h> header file. */
#undef HAVE_NETINET_IGMP_H
/* Define to 1 if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
/* Define to 1 if you have the <netinet/in_systm.h> header file. */
#undef HAVE_NETINET_IN_SYSTM_H
/* Define to 1 if you have the <netinet/ip6.h> header file. */
#undef HAVE_NETINET_IP6_H
/* Define to 1 if you have the <netinet/ip_compat.h> header file. */
#undef HAVE_NETINET_IP_COMPAT_H
/* Define to 1 if you have the <netinet/ip.h> header file. */
#undef HAVE_NETINET_IP_H
/* Define to 1 if you have the <netinet/udp.h> header file. */
#undef HAVE_NETINET_UDP_H
/* Define to 1 if you have the <net/ethernet.h> header file. */
#undef HAVE_NET_ETHERNET_H
/* Define to 1 if you have the <net/if.h> header file. */
#undef HAVE_NET_IF_H
/* Define to 1 if you have the <openssl/err.h> header file. */
#undef HAVE_OPENSSL_ERR_H
/* Define to 1 if you have the <openssl/rand.h> header file. */
#undef HAVE_OPENSSL_RAND_H
/* Define to 1 if you have the <openssl/ssl.h> header file. */
#undef HAVE_OPENSSL_SSL_H
/* Define to 1 if you have the <pcap.h> header file. */
#undef HAVE_PCAP_H
/* If available, contains the Python version number currently in use. */
#undef HAVE_PYTHON
/* Define to 1 if you have the `random' function. */
#undef HAVE_RANDOM
/* Define to 1 if your system has a GNU libc compatible `realloc' function,
and to 0 otherwise. */
#undef HAVE_REALLOC
/* Define to 1 if you have the `sleep' function. */
#undef HAVE_SLEEP
/* Define to 1 if you have the `snprintf' function. */
#undef HAVE_SNPRINTF
/* Define if you have the SSL libraries installed. */
#undef HAVE_SSL
/* Define to 1 if you have the <stdarg.h> header file. */
#undef HAVE_STDARG_H
/* Define to 1 if stdbool.h conforms to C99. */
#undef HAVE_STDBOOL_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strlcpy' function. */
#undef HAVE_STRLCPY
/* Define to 1 if you have the `strtoul' function. */
#undef HAVE_STRTOUL
/* Define if you have SWIG libraries and header files. */
#undef HAVE_SWIG
/* Define to 1 if you have the <sys/mount.h> header file. */
#undef HAVE_SYS_MOUNT_H
/* Define to 1 if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* define if you have sys/socket.h */
#undef HAVE_SYS_SOCKET_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* define if you have sys/types.h */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the `timegm' function. */
#undef HAVE_TIMEGM
/* Define to 1 if you have the <time.h> header file. */
#undef HAVE_TIME_H
/* define if you have unistd.h */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the `vfork' function. */
#undef HAVE_VFORK
/* Define to 1 if you have the <vfork.h> header file. */
#undef HAVE_VFORK_H
/* Define to 1 if you have the <winsock2.h> header file. */
#undef HAVE_WINSOCK2_H
/* Define to 1 if `fork' works. */
#undef HAVE_WORKING_FORK
/* Define to 1 if `vfork' works. */
#undef HAVE_WORKING_VFORK
/* Define to 1 if you have the <ws2tcpip.h> header file. */
#undef HAVE_WS2TCPIP_H
/* Define to 1 if the system has the type `_Bool'. */
#undef HAVE__BOOL
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* The size of `time_t', as computed by sizeof. */
#undef SIZEOF_TIME_T
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* System configuration dir */
#undef SYSCONFDIR
/* Define this to enable ECDSA support. */
#undef USE_ECDSA
/* Define this to enable GOST support. */
#undef USE_GOST
/* Define this to enable SHA256 and SHA512 support. */
#undef USE_SHA2
/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# undef _ALL_SOURCE
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# undef _GNU_SOURCE
#endif
/* Enable threading extensions on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# undef _POSIX_PTHREAD_SEMANTICS
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# undef _TANDEM_SOURCE
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# undef __EXTENSIONS__
#endif
/* Whether the windows socket API is used */
#undef USE_WINSOCK
/* the version of the windows API enabled */
#undef WINVER
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
# undef WORDS_BIGENDIAN
# endif
#endif
/* Define to 1 if on MINIX. */
#undef _MINIX
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
#undef _POSIX_1_SOURCE
/* Define to 1 if you need to in order for `stat' and other things to work. */
#undef _POSIX_SOURCE
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* in_addr_t */
#undef in_addr_t
/* in_port_t */
#undef in_port_t
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#undef inline
#endif
/* Define to `short' if <sys/types.h> does not define. */
#undef int16_t
/* Define to `int' if <sys/types.h> does not define. */
#undef int32_t
/* Define to `long long' if <sys/types.h> does not define. */
#undef int64_t
/* Define to `char' if <sys/types.h> does not define. */
#undef int8_t
/* Define to the type of a signed integer type wide enough to hold a pointer,
if such a type exists, and if the system does not define it. */
#undef intptr_t
/* Define to rpl_malloc if the replacement function should be used. */
#undef malloc
/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t
/* Define to rpl_realloc if the replacement function should be used. */
#undef realloc
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t
/* Define to 'int' if not defined */
#undef socklen_t
/* Fallback member name for socket family in struct sockaddr_storage */
#undef ss_family
/* Define to `int' if <sys/types.h> does not define. */
#undef ssize_t
/* Define to `unsigned short' if <sys/types.h> does not define. */
#undef uint16_t
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef uint32_t
/* Define to `unsigned long long' if <sys/types.h> does not define. */
#undef uint64_t
/* Define to `unsigned char' if <sys/types.h> does not define. */
#undef uint8_t
/* Define as `fork' if `vfork' does not work. */
#undef vfork
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN 1234
#endif
#ifndef BIG_ENDIAN
#define BIG_ENDIAN 4321
#endif
#ifndef BYTE_ORDER
#ifdef WORDS_BIGENDIAN
#define BYTE_ORDER BIG_ENDIAN
#else
#define BYTE_ORDER LITTLE_ENDIAN
#endif /* WORDS_BIGENDIAN */
#endif /* BYTE_ORDER */
#if STDC_HEADERS
#include <stdlib.h>
#include <stddef.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_WINSOCK2_H
#include <winsock2.h>
#endif
#ifdef HAVE_WS2TCPIP_H
#include <ws2tcpip.h>
#endif
/* detect if we need to cast to unsigned int for FD_SET to avoid warnings */
#ifdef HAVE_WINSOCK2_H
#define FD_SET_T (u_int)
#else
#define FD_SET_T
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifndef B64_PTON
int ldns_b64_ntop(uint8_t const *src, size_t srclength,
char *target, size_t targsize);
/**
* calculates the size needed to store the result of b64_ntop
*/
/*@unused@*/
static inline size_t ldns_b64_ntop_calculate_size(size_t srcsize)
{
return ((((srcsize + 2) / 3) * 4) + 1);
}
#endif /* !B64_PTON */
#ifndef B64_NTOP
int ldns_b64_pton(char const *src, uint8_t *target, size_t targsize);
/**
* calculates the size needed to store the result of ldns_b64_pton
*/
/*@unused@*/
static inline size_t ldns_b64_pton_calculate_size(size_t srcsize)
{
return (((((srcsize + 3) / 4) * 3)) + 1);
}
#endif /* !B64_NTOP */
#ifndef HAVE_SLEEP
/* use windows sleep, in millisecs, instead */
#define sleep(x) Sleep((x)*1000)
#endif
#ifndef HAVE_RANDOM
#define srandom(x) srand(x)
#define random(x) rand(x)
#endif
#ifndef HAVE_TIMEGM
#include <time.h>
time_t timegm (struct tm *tm);
#endif /* !TIMEGM */
#ifndef HAVE_GMTIME_R
struct tm *gmtime_r(const time_t *timep, struct tm *result);
#endif
#ifndef HAVE_LOCALTIME_R
struct tm *localtime_r(const time_t *timep, struct tm *result);
#endif
#ifndef HAVE_ISBLANK
int isblank(int c);
#endif /* !HAVE_ISBLANK */
#ifndef HAVE_ISASCII
int isascii(int c);
#endif /* !HAVE_ISASCII */
#ifndef HAVE_SNPRINTF
#include <stdarg.h>
int snprintf (char *str, size_t count, const char *fmt, ...);
int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
#endif /* HAVE_SNPRINTF */
#ifndef HAVE_INET_PTON
int inet_pton(int af, const char* src, void* dst);
#endif /* HAVE_INET_PTON */
#ifndef HAVE_INET_NTOP
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
#endif
#ifndef HAVE_INET_ATON
int inet_aton(const char *cp, struct in_addr *addr);
#endif
#ifndef HAVE_MEMMOVE
void *memmove(void *dest, const void *src, size_t n);
#endif
#ifndef HAVE_STRLCPY
size_t strlcpy(char *dst, const char *src, size_t siz);
#endif
#ifdef __cplusplus
}
#endif
#ifndef HAVE_GETADDRINFO
#include "compat/fake-rfc2553.h"
#endif
#ifndef HAVE_STRTOUL
#define strtoul (unsigned long)strtol
#endif

201
contrib/ldns/ldns/dname.h Normal file
View file

@ -0,0 +1,201 @@
/*
* dname.h
*
* dname definitions
*
* a Net::DNS like library for C
*
* (c) NLnet Labs, 2004-2006
*
* See the file LICENSE for the license
*/
/**
* \file dname.h
*
* dname contains function to read and manipulate domain names.
*
* Example domain names are "www.nlnetlabs.nl." and "." (the root)
*
* If a domain name ends with a dot ("."), it is called a Fully Qualified
* Domain Name (FQDN). In certain places (for instance when reading a zone
* file), an origin (which is just another domain name) non-FQDNs will be
* placed after the current. For instance, if i have a zone file where the
* origin has been set to "nl.", and my file contains the name
* "www.nlnetlabs", it will result in "www.nlnetlabs.nl.". Internally, dnames are
* always absolute (the dot is added when it is missing and there is no origin).
*
* An FQDN is also
* known as an absolute domain name, therefore the function to check this is
* called \ref ldns_dname_str_absolute
*
* Domain names are stored in \ref ldns_rdf structures, with the type
* \ref LDNS_RDF_TYPE_DNAME
*
* This module is *NOT* about the RR type called DNAME.
*/
#ifndef LDNS_DNAME_H
#define LDNS_DNAME_H
#include <ldns/common.h>
#include <ldns/rdata.h>
#ifdef __cplusplus
extern "C" {
#endif
#define LDNS_DNAME_NORMALIZE tolower
/**
* concatenates two dnames together
* \param[in] rd1 the leftside
* \param[in] rd2 the rightside
* \return a new rdf with leftside/rightside
*/
ldns_rdf *ldns_dname_cat_clone(const ldns_rdf *rd1, const ldns_rdf *rd2);
/**
* concatenates rd2 after rd1 (rd2 is copied, rd1 is modified)
* \param[in] rd1 the leftside
* \param[in] rd2 the rightside
* \return LDNS_STATUS_OK on success
*/
ldns_status ldns_dname_cat(ldns_rdf *rd1, ldns_rdf *rd2);
/**
* Returns a clone of the given dname with the labels
* reversed
* \param[in] d the dname to reverse
* \return clone of the dname with the labels reversed.
*/
ldns_rdf *ldns_dname_reverse(const ldns_rdf *d);
/**
* Clones the given dname from the nth label on
* \param[in] d The dname to clone
* \param[in] n the label nr to clone from, if this is 0, the complete
* dname is cloned
* \return A newly allocated *rdf structure, containing the cloned dname,
* or NULL if either d was NULL, not a dname, or if n >=
* label_count
*/
ldns_rdf *
ldns_dname_clone_from(const ldns_rdf *d, uint16_t n);
/**
* chop one label off the left side of a dname. so
* wwww.nlnetlabs.nl, becomes nlnetlabs.nl
* This new name is a clone and must be freed with ldns_deep_free()
* \param[in] d the dname to chop
* \return the remaining dname
*/
ldns_rdf *ldns_dname_left_chop(const ldns_rdf *d);
/**
* count the number of labels inside a LDNS_RDF_DNAME type rdf.
* \param[in] *r the rdf
* \return the number of labels
*/
uint8_t ldns_dname_label_count(const ldns_rdf *r);
/**
* creates a new dname rdf from a string.
* \param[in] str string to use
* \return ldns_rdf* or NULL in case of an error
*/
ldns_rdf *ldns_dname_new_frm_str(const char *str);
/**
* Create a new dname rdf from a string
* \param[in] s the size of the new dname
* \param[in] *data pointer to the actual data
* \return ldns_rdf*
*/
ldns_rdf *ldns_dname_new(uint16_t s, void *data);
/**
* Create a new dname rdf from data (the data is copied)
* \param[in] size the size of the data
* \param[in] *data pointer to the actual data
* \return ldns_rdf*
*/
ldns_rdf *ldns_dname_new_frm_data(uint16_t size, const void *data);
/**
* Put a dname into canonical fmt - ie. lowercase it
* \param[in] rdf the dname to lowercase
* \return void
*/
void ldns_dname2canonical(const ldns_rdf *rdf);
/**
* test wether the name sub falls under parent (i.e. is a subdomain
* of parent). This function will return false if the given dnames are
* equal.
* \param[in] sub the name to test
* \param[in] parent the parent's name
* \return true if sub falls under parent, otherwise false
*/
bool ldns_dname_is_subdomain(const ldns_rdf *sub, const ldns_rdf *parent);
/**
* Compares the two dname rdf's according to the algorithm for ordering
* in RFC4034 Section 6.
* \param[in] dname1 First dname rdf to compare
* \param[in] dname2 Second dname rdf to compare
* \return -1 if dname1 comes before dname2, 1 if dname1 comes after dname2, and 0 if they are equal.
*/
int ldns_dname_compare(const ldns_rdf *dname1, const ldns_rdf *dname2);
/**
* Checks whether the dname matches the given wildcard
* \param[in] dname The dname to check
* \param[in] wildcard The wildcard to check with
* \return 1 If the wildcard matches, OR if 'wildcard' is not a wildcard and
* the names are *exactly* the same
* 0 If the wildcard does not match, or if it is not a wildcard and
* the names are not the same
*/
int ldns_dname_match_wildcard(const ldns_rdf *dname, const ldns_rdf *wildcard);
/**
* check if middle lays in the interval defined by prev and next
* prev <= middle < next. This is usefull for nsec checking
* \param[in] prev the previous dname
* \param[in] middle the dname to check
* \param[in] next the next dname
* return 0 on error or unknown, -1 when middle is in the interval, +1 when not
*/
int ldns_dname_interval(const ldns_rdf *prev, const ldns_rdf *middle, const ldns_rdf *next);
/**
* Checks whether the given dname string is absolute (i.e. ends with a '.')
* \param[in] *dname_str a string representing the dname
* \return true or false
*/
bool ldns_dname_str_absolute(const char *dname_str);
/**
* look inside the rdf and if it is an LDNS_RDF_TYPE_DNAME
* try and retrieve a specific label. The labels are numbered
* starting from 0 (left most).
* \param[in] rdf the rdf to look in
* \param[in] labelpos return the label with this number
* \return a ldns_rdf* with the label as name or NULL on error
*/
ldns_rdf * ldns_dname_label(const ldns_rdf *rdf, uint8_t labelpos);
/**
* Check if dname is a wildcard, starts with *.
* \param[in] dname: the rdf to look in
* \return true if a wildcard, false if not.
*/
int ldns_dname_is_wildcard(const ldns_rdf* dname);
#ifdef __cplusplus
}
#endif
#endif /* LDNS_DNAME_H */

522
contrib/ldns/ldns/dnssec.h Normal file
View file

@ -0,0 +1,522 @@
/*
* dnssec.h -- defines for the Domain Name System (SEC) (DNSSEC)
*
* Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
*
* See LICENSE for the license.
*
* A bunch of defines that are used in the DNS
*/
/**
* \file dnssec.h
*
* This module contains base functions for DNSSEC operations
* (RFC4033 t/m RFC4035).
*
* Since those functions heavily rely op cryptographic operations,
* this module is dependent on openssl.
*
*/
#ifndef LDNS_DNSSEC_H
#define LDNS_DNSSEC_H
#include <ldns/common.h>
#if LDNS_BUILD_CONFIG_HAVE_SSL
#include <openssl/ssl.h>
#include <openssl/evp.h>
#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
#include <ldns/packet.h>
#include <ldns/keys.h>
#include <ldns/zone.h>
#include <ldns/resolver.h>
#include <ldns/dnssec_zone.h>
#ifdef __cplusplus
extern "C" {
#endif
#define LDNS_MAX_KEYLEN 2048
#define LDNS_DNSSEC_KEYPROTO 3
/* default time before sigs expire */
#define LDNS_DEFAULT_EXP_TIME 2419200 /* 4 weeks */
/** return values for the old-signature callback */
#define LDNS_SIGNATURE_LEAVE_ADD_NEW 0
#define LDNS_SIGNATURE_LEAVE_NO_ADD 1
#define LDNS_SIGNATURE_REMOVE_ADD_NEW 2
#define LDNS_SIGNATURE_REMOVE_NO_ADD 3
/**
* Returns the first RRSIG rr that corresponds to the rrset
* with the given name and type
*
* \param[in] name The dname of the RRset covered by the RRSIG to find
* \param[in] type The type of the RRset covered by the RRSIG to find
* \param[in] rrs List of rrs to search in
* \returns Pointer to the first RRsig ldns_rr found, or NULL if it is
* not present
*/
ldns_rr *ldns_dnssec_get_rrsig_for_name_and_type(const ldns_rdf *name,
const ldns_rr_type type,
const ldns_rr_list *rrs);
/**
* Returns the DNSKEY that corresponds to the given RRSIG rr from the list, if
* any
*
* \param[in] rrsig The rrsig to find the DNSKEY for
* \param[in] rrs The rr list to find the key in
* \return The DNSKEY that corresponds to the given RRSIG, or NULL if it was
* not found.
*/
ldns_rr *ldns_dnssec_get_dnskey_for_rrsig(const ldns_rr *rrsig, const ldns_rr_list *rrs);
/**
* Returns the rdata field that contains the bitmap of the covered types of
* the given NSEC record
*
* \param[in] nsec The nsec to get the covered type bitmap of
* \return An ldns_rdf containing the bitmap, or NULL on error
*/
ldns_rdf *ldns_nsec_get_bitmap(ldns_rr *nsec);
#define LDNS_NSEC3_MAX_ITERATIONS 65535
/**
* Returns the dname of the closest (provable) encloser
*/
ldns_rdf *
ldns_dnssec_nsec3_closest_encloser(ldns_rdf *qname,
ldns_rr_type qtype,
ldns_rr_list *nsec3s);
/**
* Checks whether the packet contains rrsigs
*/
bool
ldns_dnssec_pkt_has_rrsigs(const ldns_pkt *pkt);
/**
* Returns a ldns_rr_list containing the signatures covering the given name
* and type
*/
ldns_rr_list *ldns_dnssec_pkt_get_rrsigs_for_name_and_type(const ldns_pkt *pkt, ldns_rdf *name, ldns_rr_type type);
/**
* Returns a ldns_rr_list containing the signatures covering the given type
*/
ldns_rr_list *ldns_dnssec_pkt_get_rrsigs_for_type(const ldns_pkt *pkt, ldns_rr_type type);
/**
* calculates a keytag of a key for use in DNSSEC.
*
* \param[in] key the key as an RR to use for the calc.
* \return the keytag
*/
uint16_t ldns_calc_keytag(const ldns_rr *key);
/**
* Calculates keytag of DNSSEC key, operates on wireformat rdata.
* \param[in] key the key as uncompressed wireformat rdata.
* \param[in] keysize length of key data.
* \return the keytag
*/
uint16_t ldns_calc_keytag_raw(uint8_t* key, size_t keysize);
#if LDNS_BUILD_CONFIG_HAVE_SSL
/**
* converts a buffer holding key material to a DSA key in openssl.
*
* \param[in] key the key to convert
* \return a DSA * structure with the key material
*/
DSA *ldns_key_buf2dsa(ldns_buffer *key);
/**
* Like ldns_key_buf2dsa, but uses raw buffer.
* \param[in] key the uncompressed wireformat of the key.
* \param[in] len length of key data
* \return a DSA * structure with the key material
*/
DSA *ldns_key_buf2dsa_raw(unsigned char* key, size_t len);
/**
* Utility function to calculate hash using generic EVP_MD pointer.
* \param[in] data the data to hash.
* \param[in] len length of data.
* \param[out] dest the destination of the hash, must be large enough.
* \param[in] md the message digest to use.
* \return true if worked, false on failure.
*/
int ldns_digest_evp(unsigned char* data, unsigned int len,
unsigned char* dest, const EVP_MD* md);
/**
* Converts a holding buffer with key material to EVP PKEY in openssl.
* Only available if ldns was compiled with GOST.
* \param[in] key data to convert
* \param[in] keylen length of the key data
* \return the key or NULL on error.
*/
EVP_PKEY* ldns_gost2pkey_raw(unsigned char* key, size_t keylen);
/**
* Converts a holding buffer with key material to EVP PKEY in openssl.
* Only available if ldns was compiled with ECDSA.
* \param[in] key data to convert
* \param[in] keylen length of the key data
* \param[in] algo precise algorithm to initialize ECC group values.
* \return the key or NULL on error.
*/
EVP_PKEY* ldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo);
#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
#if LDNS_BUILD_CONFIG_HAVE_SSL
/**
* converts a buffer holding key material to a RSA key in openssl.
*
* \param[in] key the key to convert
* \return a RSA * structure with the key material
*/
RSA *ldns_key_buf2rsa(ldns_buffer *key);
/**
* Like ldns_key_buf2rsa, but uses raw buffer.
* \param[in] key the uncompressed wireformat of the key.
* \param[in] len length of key data
* \return a RSA * structure with the key material
*/
RSA *ldns_key_buf2rsa_raw(unsigned char* key, size_t len);
#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
/**
* returns a new DS rr that represents the given key rr.
*
* \param[in] *key the key to convert
* \param[in] h the hash to use LDNS_SHA1/LDNS_SHA256
* \return ldns_rr* a new rr pointer to a DS
*/
ldns_rr *ldns_key_rr2ds(const ldns_rr *key, ldns_hash h);
/**
* Create the type bitmap for an NSEC(3) record
*/
ldns_rdf *
ldns_dnssec_create_nsec_bitmap(ldns_rr_type rr_type_list[],
size_t size,
ldns_rr_type nsec_type);
/**
* returns whether a rrset of the given type is found in the rrsets.
*
* \param[in] rrsets the rrsets to be tested
* \param[in] type the type to test for
* \return int 1 if the type was found, 0 otherwise.
*/
int
ldns_dnssec_rrsets_contains_type (ldns_dnssec_rrsets *rrsets, ldns_rr_type type);
/**
* Creates NSEC
*/
ldns_rr *
ldns_dnssec_create_nsec(ldns_dnssec_name *from,
ldns_dnssec_name *to,
ldns_rr_type nsec_type);
/**
* Creates NSEC3
*/
ldns_rr *
ldns_dnssec_create_nsec3(ldns_dnssec_name *from,
ldns_dnssec_name *to,
ldns_rdf *zone_name,
uint8_t algorithm,
uint8_t flags,
uint16_t iterations,
uint8_t salt_length,
uint8_t *salt);
/**
* Create a NSEC record
* \param[in] cur_owner the current owner which should be taken as the starting point
* \param[in] next_owner the rrlist which the nsec rr should point to
* \param[in] rrs all rrs from the zone, to find all RR types of cur_owner in
* \return a ldns_rr with the nsec record in it
*/
ldns_rr * ldns_create_nsec(ldns_rdf *cur_owner, ldns_rdf *next_owner, ldns_rr_list *rrs);
/**
* Calculates the hashed name using the given parameters
* \param[in] *name The owner name to calculate the hash for
* \param[in] algorithm The hash algorithm to use
* \param[in] iterations The number of hash iterations to use
* \param[in] salt_length The length of the salt in bytes
* \param[in] salt The salt to use
* \return The hashed owner name rdf, without the domain name
*/
ldns_rdf *ldns_nsec3_hash_name(ldns_rdf *name, uint8_t algorithm, uint16_t iterations, uint8_t salt_length, uint8_t *salt);
/**
* Sets all the NSEC3 options. The rr to set them in must be initialized with _new() and
* type LDNS_RR_TYPE_NSEC3
* \param[in] *rr The RR to set the values in
* \param[in] algorithm The NSEC3 hash algorithm
* \param[in] flags The flags field
* \param[in] iterations The number of hash iterations
* \param[in] salt_length The length of the salt in bytes
* \param[in] salt The salt bytes
*/
void ldns_nsec3_add_param_rdfs(ldns_rr *rr,
uint8_t algorithm,
uint8_t flags,
uint16_t iterations,
uint8_t salt_length,
uint8_t *salt);
/* this will NOT return the NSEC3 completed, you will have to run the
finalize function on the rrlist later! */
ldns_rr *
ldns_create_nsec3(ldns_rdf *cur_owner,
ldns_rdf *cur_zone,
ldns_rr_list *rrs,
uint8_t algorithm,
uint8_t flags,
uint16_t iterations,
uint8_t salt_length,
uint8_t *salt,
bool emptynonterminal);
/**
* Returns the hash algorithm used in the given NSEC3 RR
* \param[in] *nsec3_rr The RR to read from
* \return The algorithm identifier, or 0 on error
*/
uint8_t ldns_nsec3_algorithm(const ldns_rr *nsec3_rr);
/**
* Returns flags field
*/
uint8_t
ldns_nsec3_flags(const ldns_rr *nsec3_rr);
/**
* Returns true if the opt-out flag has been set in the given NSEC3 RR
* \param[in] *nsec3_rr The RR to read from
* \return true if the RR has type NSEC3 and the opt-out bit has been set, false otherwise
*/
bool ldns_nsec3_optout(const ldns_rr *nsec3_rr);
/**
* Returns the number of hash iterations used in the given NSEC3 RR
* \param[in] *nsec3_rr The RR to read from
* \return The number of iterations
*/
uint16_t ldns_nsec3_iterations(const ldns_rr *nsec3_rr);
/**
* Returns the salt used in the given NSEC3 RR
* \param[in] *nsec3_rr The RR to read from
* \return The salt rdf, or NULL on error
*/
ldns_rdf *ldns_nsec3_salt(const ldns_rr *nsec3_rr);
/**
* Returns the length of the salt used in the given NSEC3 RR
* \param[in] *nsec3_rr The RR to read from
* \return The length of the salt in bytes
*/
uint8_t ldns_nsec3_salt_length(const ldns_rr *nsec3_rr);
/**
* Returns the salt bytes used in the given NSEC3 RR
* \param[in] *nsec3_rr The RR to read from
* \return The salt in bytes, this is alloced, so you need to free it
*/
uint8_t *ldns_nsec3_salt_data(const ldns_rr *nsec3_rr);
/**
* Returns the first label of the next ownername in the NSEC3 chain (ie. without the domain)
* \param[in] nsec3_rr The RR to read from
* \return The first label of the next owner name in the NSEC3 chain, or NULL on error
*/
ldns_rdf *ldns_nsec3_next_owner(const ldns_rr *nsec3_rr);
/**
* Returns the bitmap specifying the covered types of the given NSEC3 RR
* \param[in] *nsec3_rr The RR to read from
* \return The covered type bitmap rdf
*/
ldns_rdf *ldns_nsec3_bitmap(const ldns_rr *nsec3_rr);
/**
* Calculates the hashed name using the parameters of the given NSEC3 RR
* \param[in] *nsec The RR to use the parameters from
* \param[in] *name The owner name to calculate the hash for
* \return The hashed owner name rdf, without the domain name
*/
ldns_rdf *ldns_nsec3_hash_name_frm_nsec3(const ldns_rr *nsec, ldns_rdf *name);
/**
* Checks coverage of NSEC RR type bitmap
* \param[in] nsec_bitmap The NSEC bitmap rdata field to check
* \param[in] type The type to check
* \return true if the NSEC RR covers the type
*/
bool ldns_nsec_bitmap_covers_type(const ldns_rdf *nsec_bitmap, ldns_rr_type type);
/**
* Checks coverage of NSEC(3) RR name span
* Remember that nsec and name must both be in canonical form (ie use
* \ref ldns_rr2canonical and \ref ldns_dname2canonical prior to calling this
* function)
*
* \param[in] nsec The NSEC RR to check
* \param[in] name The owner dname to check, if the nsec record is a NSEC3 record, this should be the hashed name
* \return true if the NSEC RR covers the owner name
*/
bool ldns_nsec_covers_name(const ldns_rr *nsec, const ldns_rdf *name);
#if LDNS_BUILD_CONFIG_HAVE_SSL
/**
* verify a packet
* \param[in] p the packet
* \param[in] t the rr set type to check
* \param[in] o the rr set name to check
* \param[in] k list of keys
* \param[in] s list of sigs (may be null)
* \param[out] good_keys keys which validated the packet
* \return status
*
*/
ldns_status ldns_pkt_verify(ldns_pkt *p, ldns_rr_type t, ldns_rdf *o, ldns_rr_list *k, ldns_rr_list *s, ldns_rr_list *good_keys);
/**
* verify a packet
* \param[in] p the packet
* \param[in] t the rr set type to check
* \param[in] o the rr set name to check
* \param[in] k list of keys
* \param[in] s list of sigs (may be null)
* \param[in] check_time the time for which the validation is performed
* \param[out] good_keys keys which validated the packet
* \return status
*
*/
ldns_status ldns_pkt_verify_time(ldns_pkt *p, ldns_rr_type t, ldns_rdf *o, ldns_rr_list *k, ldns_rr_list *s, time_t check_time, ldns_rr_list *good_keys);
#endif
/**
* chains nsec3 list
*/
ldns_status
ldns_dnssec_chain_nsec3_list(ldns_rr_list *nsec3_rrs);
/**
* compare for nsec3 sort
*/
int
qsort_rr_compare_nsec3(const void *a, const void *b);
/**
* sort nsec3 list
*/
void
ldns_rr_list_sort_nsec3(ldns_rr_list *unsorted);
/**
* Default callback function to always leave present signatures, and
* add new ones
* \param[in] sig The signature to check for removal (unused)
* \param[in] n Optional argument (unused)
* \return LDNS_SIGNATURE_LEAVE_ADD_NEW
*/
int ldns_dnssec_default_add_to_signatures(ldns_rr *sig, void *n);
/**
* Default callback function to always leave present signatures, and
* add no new ones for the keys of these signatures
* \param[in] sig The signature to check for removal (unused)
* \param[in] n Optional argument (unused)
* \return LDNS_SIGNATURE_LEAVE_NO_ADD
*/
int ldns_dnssec_default_leave_signatures(ldns_rr *sig, void *n);
/**
* Default callback function to always remove present signatures, but
* add no new ones
* \param[in] sig The signature to check for removal (unused)
* \param[in] n Optional argument (unused)
* \return LDNS_SIGNATURE_REMOVE_NO_ADD
*/
int ldns_dnssec_default_delete_signatures(ldns_rr *sig, void *n);
/**
* Default callback function to always leave present signatures, and
* add new ones
* \param[in] sig The signature to check for removal (unused)
* \param[in] n Optional argument (unused)
* \return LDNS_SIGNATURE_REMOVE_ADD_NEW
*/
int ldns_dnssec_default_replace_signatures(ldns_rr *sig, void *n);
#if LDNS_BUILD_CONFIG_HAVE_SSL
/**
* Converts the DSA signature from ASN1 representation (RFC2459, as
* used by OpenSSL) to raw signature data as used in DNS (rfc2536)
*
* \param[in] sig The signature in RFC2459 format
* \param[in] sig_len The length of the signature
* \return a new rdf with the signature
*/
ldns_rdf *
ldns_convert_dsa_rrsig_asn12rdf(const ldns_buffer *sig,
const long sig_len);
/**
* Converts the RRSIG signature RDF (in rfc2536 format) to a buffer
* with the signature in rfc2459 format
*
* \param[out] target_buffer buffer to place the signature data
* \param[in] sig_rdf The signature rdf to convert
* \return LDNS_STATUS_OK on success, error code otherwise
*/
ldns_status
ldns_convert_dsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
const ldns_rdf *sig_rdf);
/**
* Converts the ECDSA signature from ASN1 representation (as
* used by OpenSSL) to raw signature data as used in DNS
* This routine is only present if ldns is compiled with ecdsa support.
*
* \param[in] sig The signature in ASN1 format
* \param[in] sig_len The length of the signature
* \return a new rdf with the signature
*/
ldns_rdf *
ldns_convert_ecdsa_rrsig_asn12rdf(const ldns_buffer *sig, const long sig_len);
/**
* Converts the RRSIG signature RDF (from DNS) to a buffer with the
* signature in ASN1 format as openssl uses it.
* This routine is only present if ldns is compiled with ecdsa support.
*
* \param[out] target_buffer buffer to place the signature data in ASN1.
* \param[in] sig_rdf The signature rdf to convert
* \return LDNS_STATUS_OK on success, error code otherwise
*/
ldns_status
ldns_convert_ecdsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
const ldns_rdf *sig_rdf);
#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
#ifdef __cplusplus
}
#endif
#endif /* LDNS_DNSSEC_H */

View file

@ -0,0 +1,383 @@
/** dnssec_verify */
#ifndef LDNS_DNSSEC_SIGN_H
#define LDNS_DNSSEC_SIGN_H
#include <ldns/dnssec.h>
#ifdef __cplusplus
extern "C" {
#endif
/* sign functions */
/** Sign flag that makes DNSKEY type signed by all keys, not only by SEP keys*/
#define LDNS_SIGN_DNSKEY_WITH_ZSK 1
/**
* Create an empty RRSIG RR (i.e. without the actual signature data)
* \param[in] rrset The RRset to create the signature for
* \param[in] key The key that will create the signature
* \return signature rr
*/
ldns_rr *
ldns_create_empty_rrsig(ldns_rr_list *rrset,
ldns_key *key);
/**
* Sign the buffer which contains the wiredata of an rrset, and the
* corresponding empty rrsig rr with the given key
* \param[in] sign_buf the buffer with data to sign
* \param[in] key the key to sign with
* \return an rdata field with the signature data
*/
ldns_rdf *
ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *key);
/**
* Sign an rrset
* \param[in] rrset the rrset
* \param[in] keys the keys to use
* \return a rr_list with the signatures
*/
ldns_rr_list *ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys);
#if LDNS_BUILD_CONFIG_HAVE_SSL
/**
* Sign a buffer with the DSA key (hash with SHA1)
* \param[in] to_sign buffer with the data
* \param[in] key the key to use
* \return a ldns_rdf with the signed data
*/
ldns_rdf *ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key);
/**
* Sign data with EVP (general method for different algorithms)
*
* \param[in] to_sign The ldns_buffer containing raw data that is
* to be signed
* \param[in] key The EVP_PKEY key structure to sign with
* \param[in] digest_type The digest algorithm to use in the creation of
* the signature
* \return ldns_rdf for the RRSIG ldns_rr
*/
ldns_rdf *ldns_sign_public_evp(ldns_buffer *to_sign,
EVP_PKEY *key,
const EVP_MD *digest_type);
/**
* Sign a buffer with the RSA key (hash with SHA1)
* \param[in] to_sign buffer with the data
* \param[in] key the key to use
* \return a ldns_rdf with the signed data
*/
ldns_rdf *ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key);
/**
* Sign a buffer with the RSA key (hash with MD5)
* \param[in] to_sign buffer with the data
* \param[in] key the key to use
* \return a ldns_rdf with the signed data
*/
ldns_rdf *ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key);
#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
/**
* Marks the names in the zone that are occluded. Those names will be skipped
* when walking the tree with the ldns_dnssec_name_node_next_nonglue()
* function. But watch out! Names that are partially occluded (like glue with
* the same name as the delegation) will not be marked and should specifically
* be taken into account seperately.
*
* When glue_list is given (not NULL), in the process of marking the names, all
* glue resource records will be pushed to that list, even glue at the delegation name.
*
* \param[in] zone the zone in which to mark the names
* \param[in] glue_list the list to which to push the glue rrs
* \return LDNS_STATUS_OK on success, an error code otherwise
*/
ldns_status
ldns_dnssec_zone_mark_and_get_glue(
ldns_dnssec_zone *zone, ldns_rr_list *glue_list);
/**
* Marks the names in the zone that are occluded. Those names will be skipped
* when walking the tree with the ldns_dnssec_name_node_next_nonglue()
* function. But watch out! Names that are partially occluded (like glue with
* the same name as the delegation) will not be marked and should specifically
* be taken into account seperately.
*
* \param[in] zone the zone in which to mark the names
* \return LDNS_STATUS_OK on succesful completion
*/
ldns_status
ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone);
/**
* Finds the first dnssec_name node in the rbtree that is not occluded.
* It *does* return names that are partially occluded.
*
* \param[in] node the first node to check
* \return the first node that has not been marked as glue, or NULL
* if not found (TODO: make that LDNS_RBTREE_NULL?)
*/
ldns_rbnode_t *ldns_dnssec_name_node_next_nonglue(ldns_rbnode_t *node);
/**
* Adds NSEC records to the given dnssec_zone
*
* \param[in] zone the zone to add the records to
* \param[in] new_rrs ldns_rr's created by this function are
* added to this rr list, so the caller can free them later
* \return LDNS_STATUS_OK on success, an error code otherwise
*/
ldns_status ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone,
ldns_rr_list *new_rrs);
/**
* Adds NSEC3 records to the zone
*/
ldns_status
ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
ldns_rr_list *new_rrs,
uint8_t algorithm,
uint8_t flags,
uint16_t iterations,
uint8_t salt_length,
uint8_t *salt);
/**
* remove signatures if callback function tells to
*
* \param[in] signatures list of signatures to check, and
* possibly remove, depending on the value of the
* callback
* \param[in] key_list these are marked to be used or not,
* on the return value of the callback
* \param[in] func this function is called to specify what to
* do with each signature (and corresponding key)
* \param[in] arg Optional argument for the callback function
* \returns pointer to the new signatures rrs (the original
* passed to this function may have been removed)
*/
ldns_dnssec_rrs *ldns_dnssec_remove_signatures(ldns_dnssec_rrs *signatures,
ldns_key_list *key_list,
int (*func)(ldns_rr *, void *),
void *arg);
/**
* Adds signatures to the zone
*
* \param[in] zone the zone to add RRSIG Resource Records to
* \param[in] new_rrs the RRSIG RRs that are created are also
* added to this list, so the caller can free them
* later
* \param[in] key_list list of keys to sign with.
* \param[in] func Callback function to decide what keys to
* use and what to do with old signatures
* \param[in] arg Optional argument for the callback function
* \param[in] flags option flags for signing process. 0 makes DNSKEY
* RRset signed with the minimal key set, that is only SEP keys are used
* for signing. If there are no SEP keys available, non-SEP keys will
* be used. LDNS_SIGN_DNSKEY_WITH_ZSK makes DNSKEY type signed with all
* keys. 0 is the default.
* \return LDNS_STATUS_OK on success, error otherwise
*/
ldns_status ldns_dnssec_zone_create_rrsigs_flg(ldns_dnssec_zone *zone,
ldns_rr_list *new_rrs,
ldns_key_list *key_list,
int (*func)(ldns_rr *, void*),
void *arg,
int flags);
/**
* Adds signatures to the zone
*
* \param[in] zone the zone to add RRSIG Resource Records to
* \param[in] new_rrs the RRSIG RRs that are created are also
* added to this list, so the caller can free them
* later
* \param[in] key_list list of keys to sign with.
* \param[in] func Callback function to decide what keys to
* use and what to do with old signatures
* \param[in] arg Optional argument for the callback function
* \return LDNS_STATUS_OK on success, error otherwise
*/
ldns_status ldns_dnssec_zone_create_rrsigs(ldns_dnssec_zone *zone,
ldns_rr_list *new_rrs,
ldns_key_list *key_list,
int (*func)(ldns_rr *, void*),
void *arg);
/**
* signs the given zone with the given keys
*
* \param[in] zone the zone to sign
* \param[in] key_list the list of keys to sign the zone with
* \param[in] new_rrs newly created resource records are added to this list, to free them later
* \param[in] func callback function that decides what to do with old signatures
* This function takes an ldns_rr* and an optional void *arg argument, and returns one of four values:
* LDNS_SIGNATURE_LEAVE_ADD_NEW:
* leave the signature and add a new one for the corresponding key
* LDNS_SIGNATURE_REMOVE_ADD_NEW:
* remove the signature and replace is with a new one from the same key
* LDNS_SIGNATURE_LEAVE_NO_ADD:
* leave the signature and do not add a new one with the corresponding key
* LDNS_SIGNATURE_REMOVE_NO_ADD:
* remove the signature and do not replace
*
* \param[in] arg optional argument for the callback function
* \param[in] flags option flags for signing process. 0 makes DNSKEY
* RRset signed with the minimal key set, that is only SEP keys are used
* for signing. If there are no SEP keys available, non-SEP keys will
* be used. LDNS_SIGN_DNSKEY_WITH_ZSK makes DNSKEY type signed with all
* keys. 0 is the default.
* \return LDNS_STATUS_OK on success, an error code otherwise
*/
ldns_status ldns_dnssec_zone_sign_flg(ldns_dnssec_zone *zone,
ldns_rr_list *new_rrs,
ldns_key_list *key_list,
int (*func)(ldns_rr *, void *),
void *arg,
int flags);
/**
* signs the given zone with the given new zone, with NSEC3
*
* \param[in] zone the zone to sign
* \param[in] key_list the list of keys to sign the zone with
* \param[in] new_rrs newly created resource records are added to this list, to free them later
* \param[in] func callback function that decides what to do with old signatures
* \param[in] arg optional argument for the callback function
* \param[in] algorithm the NSEC3 hashing algorithm to use
* \param[in] flags NSEC3 flags
* \param[in] iterations the number of NSEC3 hash iterations to use
* \param[in] salt_length the length (in octets) of the NSEC3 salt
* \param[in] salt the NSEC3 salt data
* \param[in] signflags option flags for signing process. 0 is the default.
* \return LDNS_STATUS_OK on success, an error code otherwise
*/
ldns_status ldns_dnssec_zone_sign_nsec3_flg(ldns_dnssec_zone *zone,
ldns_rr_list *new_rrs,
ldns_key_list *key_list,
int (*func)(ldns_rr *, void *),
void *arg,
uint8_t algorithm,
uint8_t flags,
uint16_t iterations,
uint8_t salt_length,
uint8_t *salt,
int signflags);
/**
* signs the given zone with the given new zone, with NSEC3
*
* \param[in] zone the zone to sign
* \param[in] key_list the list of keys to sign the zone with
* \param[in] new_rrs newly created resource records are added to this list, to free them later
* \param[in] func callback function that decides what to do with old signatures
* \param[in] arg optional argument for the callback function
* \param[in] algorithm the NSEC3 hashing algorithm to use
* \param[in] flags NSEC3 flags
* \param[in] iterations the number of NSEC3 hash iterations to use
* \param[in] salt_length the length (in octets) of the NSEC3 salt
* \param[in] salt the NSEC3 salt data
* \param[in] signflags option flags for signing process. 0 is the default.
* \param[out] map a referenced rbtree pointer variable. The newly created
* rbtree will contain mappings from hashed owner names to the
* unhashed name.
* \return LDNS_STATUS_OK on success, an error code otherwise
*/
ldns_status ldns_dnssec_zone_sign_nsec3_flg_mkmap(ldns_dnssec_zone *zone,
ldns_rr_list *new_rrs,
ldns_key_list *key_list,
int (*func)(ldns_rr *, void *),
void *arg,
uint8_t algorithm,
uint8_t flags,
uint16_t iterations,
uint8_t salt_length,
uint8_t *salt,
int signflags,
ldns_rbtree_t **map
);
/**
* signs the given zone with the given keys
*
* \param[in] zone the zone to sign
* \param[in] key_list the list of keys to sign the zone with
* \param[in] new_rrs newly created resource records are added to this list, to free them later
* \param[in] func callback function that decides what to do with old signatures
* This function takes an ldns_rr* and an optional void *arg argument, and returns one of four values:
* LDNS_SIGNATURE_LEAVE_ADD_NEW:
* leave the signature and add a new one for the corresponding key
* LDNS_SIGNATURE_REMOVE_ADD_NEW:
* remove the signature and replace is with a new one from the same key
* LDNS_SIGNATURE_LEAVE_NO_ADD:
* leave the signature and do not add a new one with the corresponding key
* LDNS_SIGNATURE_REMOVE_NO_ADD:
* remove the signature and do not replace
*
* \param[in] arg optional argument for the callback function
* \return LDNS_STATUS_OK on success, an error code otherwise
*/
ldns_status ldns_dnssec_zone_sign(ldns_dnssec_zone *zone,
ldns_rr_list *new_rrs,
ldns_key_list *key_list,
int (*func)(ldns_rr *, void *),
void *arg);
/**
* signs the given zone with the given new zone, with NSEC3
*
* \param[in] zone the zone to sign
* \param[in] key_list the list of keys to sign the zone with
* \param[in] new_rrs newly created resource records are added to this list, to free them later
* \param[in] func callback function that decides what to do with old signatures
* \param[in] arg optional argument for the callback function
* \param[in] algorithm the NSEC3 hashing algorithm to use
* \param[in] flags NSEC3 flags
* \param[in] iterations the number of NSEC3 hash iterations to use
* \param[in] salt_length the length (in octets) of the NSEC3 salt
* \param[in] salt the NSEC3 salt data
* \return LDNS_STATUS_OK on success, an error code otherwise
*/
ldns_status ldns_dnssec_zone_sign_nsec3(ldns_dnssec_zone *zone,
ldns_rr_list *new_rrs,
ldns_key_list *key_list,
int (*func)(ldns_rr *, void *),
void *arg,
uint8_t algorithm,
uint8_t flags,
uint16_t iterations,
uint8_t salt_length,
uint8_t *salt);
/**
* Signs the zone, and returns a newly allocated signed zone
* \param[in] zone the zone to sign
* \param[in] key_list list of keys to sign with
* \return signed zone
*/
ldns_zone *ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list);
/**
* Signs the zone with NSEC3, and returns a newly allocated signed zone
* \param[in] zone the zone to sign
* \param[in] key_list list of keys to sign with
* \param[in] algorithm the NSEC3 hashing algorithm to use
* \param[in] flags NSEC3 flags
* \param[in] iterations the number of NSEC3 hash iterations to use
* \param[in] salt_length the length (in octets) of the NSEC3 salt
* \param[in] salt the NSEC3 salt data
* \return signed zone
*/
ldns_zone *ldns_zone_sign_nsec3(ldns_zone *zone, ldns_key_list *key_list, uint8_t algorithm, uint8_t flags, uint16_t iterations, uint8_t salt_length, uint8_t *salt);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,873 @@
/** dnssec_verify */
#ifndef LDNS_DNSSEC_VERIFY_H
#define LDNS_DNSSEC_VERIFY_H
#define LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS 10
#include <ldns/dnssec.h>
#include <ldns/host2str.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Chain structure that contains all DNSSEC data needed to
* verify an rrset
*/
typedef struct ldns_dnssec_data_chain_struct ldns_dnssec_data_chain;
struct ldns_dnssec_data_chain_struct
{
ldns_rr_list *rrset;
ldns_rr_list *signatures;
ldns_rr_type parent_type;
ldns_dnssec_data_chain *parent;
ldns_pkt_rcode packet_rcode;
ldns_rr_type packet_qtype;
bool packet_nodata;
};
/**
* Creates a new dnssec_chain structure
* \return ldns_dnssec_data_chain *
*/
ldns_dnssec_data_chain *ldns_dnssec_data_chain_new(void);
/**
* Frees a dnssec_data_chain structure
*
* \param[in] *chain The chain to free
*/
void ldns_dnssec_data_chain_free(ldns_dnssec_data_chain *chain);
/**
* Frees a dnssec_data_chain structure, and all data
* contained therein
*
* \param[in] *chain The dnssec_data_chain to free
*/
void ldns_dnssec_data_chain_deep_free(ldns_dnssec_data_chain *chain);
/**
* Prints the dnssec_data_chain to the given file stream
*
* \param[in] *out The file stream to print to
* \param[in] *chain The dnssec_data_chain to print
*/
void ldns_dnssec_data_chain_print(FILE *out, const ldns_dnssec_data_chain *chain);
/**
* Prints the dnssec_data_chain to the given file stream
*
* \param[in] *out The file stream to print to
* \param[in] *fmt The format of the textual representation
* \param[in] *chain The dnssec_data_chain to print
*/
void ldns_dnssec_data_chain_print_fmt(FILE *out,
const ldns_output_format *fmt,
const ldns_dnssec_data_chain *chain);
/**
* Build an ldns_dnssec_data_chain, which contains all
* DNSSEC data that is needed to derive the trust tree later
*
* The data_set will be cloned
*
* \param[in] *res resolver structure for further needed queries
* \param[in] qflags resolution flags
* \param[in] *data_set The original rrset where the chain ends
* \param[in] *pkt optional, can contain the original packet
* (and hence the sigs and maybe the key)
* \param[in] *orig_rr The original Resource Record
*
* \return the DNSSEC data chain
*/
ldns_dnssec_data_chain *ldns_dnssec_build_data_chain(ldns_resolver *res,
const uint16_t qflags,
const ldns_rr_list *data_set,
const ldns_pkt *pkt,
ldns_rr *orig_rr);
/**
* Tree structure that contains the relation of DNSSEC data,
* and their cryptographic status.
*
* This tree is derived from a data_chain, and can be used
* to look whether there is a connection between an RRSET
* and a trusted key. The tree only contains pointers to the
* data_chain, and therefore one should *never* free() the
* data_chain when there is still a trust tree derived from
* that chain.
*
* Example tree:
* key key key
* \ | /
* \ | /
* \ | /
* ds
* |
* key
* |
* key
* |
* rr
*
* For each signature there is a parent; if the parent
* pointer is null, it couldn't be found and there was no
* denial; otherwise is a tree which contains either a
* DNSKEY, a DS, or a NSEC rr
*/
typedef struct ldns_dnssec_trust_tree_struct ldns_dnssec_trust_tree;
struct ldns_dnssec_trust_tree_struct
{
ldns_rr *rr;
/* the complete rrset this rr was in */
ldns_rr_list *rrset;
ldns_dnssec_trust_tree *parents[LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS];
ldns_status parent_status[LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS];
/** for debugging, add signatures too (you might want
those if they contain errors) */
ldns_rr *parent_signature[LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS];
size_t parent_count;
};
/**
* Creates a new (empty) dnssec_trust_tree structure
*
* \return ldns_dnssec_trust_tree *
*/
ldns_dnssec_trust_tree *ldns_dnssec_trust_tree_new(void);
/**
* Frees the dnssec_trust_tree recursively
*
* There is no deep free; all data in the trust tree
* consists of pointers to a data_chain
*
* \param[in] tree The tree to free
*/
void ldns_dnssec_trust_tree_free(ldns_dnssec_trust_tree *tree);
/**
* returns the depth of the trust tree
*
* \param[in] tree tree to calculate the depth of
* \return The depth of the tree
*/
size_t ldns_dnssec_trust_tree_depth(ldns_dnssec_trust_tree *tree);
/**
* Prints the dnssec_trust_tree structure to the given file
* stream.
*
* If a link status is not LDNS_STATUS_OK; the status and
* relevant signatures are printed too
*
* \param[in] *out The file stream to print to
* \param[in] tree The trust tree to print
* \param[in] tabs Prepend each line with tabs*2 spaces
* \param[in] extended If true, add little explanation lines to the output
*/
void ldns_dnssec_trust_tree_print(FILE *out,
ldns_dnssec_trust_tree *tree,
size_t tabs,
bool extended);
/**
* Prints the dnssec_trust_tree structure to the given file
* stream.
*
* If a link status is not LDNS_STATUS_OK; the status and
* relevant signatures are printed too
*
* \param[in] *out The file stream to print to
* \param[in] *fmt The format of the textual representation
* \param[in] tree The trust tree to print
* \param[in] tabs Prepend each line with tabs*2 spaces
* \param[in] extended If true, add little explanation lines to the output
*/
void ldns_dnssec_trust_tree_print_fmt(FILE *out,
const ldns_output_format *fmt,
ldns_dnssec_trust_tree *tree,
size_t tabs,
bool extended);
/**
* Adds a trust tree as a parent for the given trust tree
*
* \param[in] *tree The tree to add the parent to
* \param[in] *parent The parent tree to add
* \param[in] *parent_signature The RRSIG relevant to this parent/child
* connection
* \param[in] parent_status The DNSSEC status for this parent, child and RRSIG
* \return LDNS_STATUS_OK if the addition succeeds, error otherwise
*/
ldns_status ldns_dnssec_trust_tree_add_parent(ldns_dnssec_trust_tree *tree,
const ldns_dnssec_trust_tree *parent,
const ldns_rr *parent_signature,
const ldns_status parent_status);
/**
* Generates a dnssec_trust_tree for the given rr from the
* given data_chain
*
* This does not clone the actual data; Don't free the
* data_chain before you are done with this tree
*
* \param[in] *data_chain The chain to derive the trust tree from
* \param[in] *rr The RR this tree will be about
* \return ldns_dnssec_trust_tree *
*/
ldns_dnssec_trust_tree *ldns_dnssec_derive_trust_tree(
ldns_dnssec_data_chain *data_chain,
ldns_rr *rr);
/**
* Generates a dnssec_trust_tree for the given rr from the
* given data_chain
*
* This does not clone the actual data; Don't free the
* data_chain before you are done with this tree
*
* \param[in] *data_chain The chain to derive the trust tree from
* \param[in] *rr The RR this tree will be about
* \param[in] check_time the time for which the validation is performed
* \return ldns_dnssec_trust_tree *
*/
ldns_dnssec_trust_tree *ldns_dnssec_derive_trust_tree_time(
ldns_dnssec_data_chain *data_chain,
ldns_rr *rr, time_t check_time);
/**
* Sub function for derive_trust_tree that is used for a 'normal' rrset
*
* \param[in] new_tree The trust tree that we are building
* \param[in] data_chain The data chain containing the data for the trust tree
* \param[in] cur_sig_rr The currently relevant signature
*/
void ldns_dnssec_derive_trust_tree_normal_rrset(
ldns_dnssec_trust_tree *new_tree,
ldns_dnssec_data_chain *data_chain,
ldns_rr *cur_sig_rr);
/**
* Sub function for derive_trust_tree that is used for a 'normal' rrset
*
* \param[in] new_tree The trust tree that we are building
* \param[in] data_chain The data chain containing the data for the trust tree
* \param[in] cur_sig_rr The currently relevant signature
* \param[in] check_time the time for which the validation is performed
*/
void ldns_dnssec_derive_trust_tree_normal_rrset_time(
ldns_dnssec_trust_tree *new_tree,
ldns_dnssec_data_chain *data_chain,
ldns_rr *cur_sig_rr, time_t check_time);
/**
* Sub function for derive_trust_tree that is used for DNSKEY rrsets
*
* \param[in] new_tree The trust tree that we are building
* \param[in] data_chain The data chain containing the data for the trust tree
* \param[in] cur_rr The currently relevant DNSKEY RR
* \param[in] cur_sig_rr The currently relevant signature
*/
void ldns_dnssec_derive_trust_tree_dnskey_rrset(
ldns_dnssec_trust_tree *new_tree,
ldns_dnssec_data_chain *data_chain,
ldns_rr *cur_rr,
ldns_rr *cur_sig_rr);
/**
* Sub function for derive_trust_tree that is used for DNSKEY rrsets
*
* \param[in] new_tree The trust tree that we are building
* \param[in] data_chain The data chain containing the data for the trust tree
* \param[in] cur_rr The currently relevant DNSKEY RR
* \param[in] cur_sig_rr The currently relevant signature
* \param[in] check_time the time for which the validation is performed
*/
void ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
ldns_dnssec_trust_tree *new_tree,
ldns_dnssec_data_chain *data_chain,
ldns_rr *cur_rr, ldns_rr *cur_sig_rr,
time_t check_time);
/**
* Sub function for derive_trust_tree that is used for DNSKEY rrsets
*
* \param[in] new_tree The trust tree that we are building
* \param[in] data_chain The data chain containing the data for the trust tree
* \param[in] cur_rr The currently relevant DNSKEY RR
* \param[in] cur_sig_rr The currently relevant signature
* \param[in] check_time the time for which the validation is performed
*/
void ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
ldns_dnssec_trust_tree *new_tree,
ldns_dnssec_data_chain *data_chain,
ldns_rr *cur_rr, ldns_rr *cur_sig_rr,
time_t check_time);
/**
* Sub function for derive_trust_tree that is used for DS rrsets
*
* \param[in] new_tree The trust tree that we are building
* \param[in] data_chain The data chain containing the data for the trust tree
* \param[in] cur_rr The currently relevant DS RR
*/
void ldns_dnssec_derive_trust_tree_ds_rrset(
ldns_dnssec_trust_tree *new_tree,
ldns_dnssec_data_chain *data_chain,
ldns_rr *cur_rr);
/**
* Sub function for derive_trust_tree that is used for DS rrsets
*
* \param[in] new_tree The trust tree that we are building
* \param[in] data_chain The data chain containing the data for the trust tree
* \param[in] cur_rr The currently relevant DS RR
* \param[in] check_time the time for which the validation is performed
*/
void ldns_dnssec_derive_trust_tree_ds_rrset_time(
ldns_dnssec_trust_tree *new_tree,
ldns_dnssec_data_chain *data_chain,
ldns_rr *cur_rr, time_t check_time);
/**
* Sub function for derive_trust_tree that is used when there are no
* signatures
*
* \param[in] new_tree The trust tree that we are building
* \param[in] data_chain The data chain containing the data for the trust tree
*/
void ldns_dnssec_derive_trust_tree_no_sig(
ldns_dnssec_trust_tree *new_tree,
ldns_dnssec_data_chain *data_chain);
/**
* Sub function for derive_trust_tree that is used when there are no
* signatures
*
* \param[in] new_tree The trust tree that we are building
* \param[in] data_chain The data chain containing the data for the trust tree
* \param[in] check_time the time for which the validation is performed
*/
void ldns_dnssec_derive_trust_tree_no_sig_time(
ldns_dnssec_trust_tree *new_tree,
ldns_dnssec_data_chain *data_chain,
time_t check_time);
/**
* Returns OK if there is a trusted path in the tree to one of
* the DNSKEY or DS RRs in the given list
*
* \param *tree The trust tree so search
* \param *keys A ldns_rr_list of DNSKEY and DS rrs to look for
* \return LDNS_STATUS_OK if there is a trusted path to one of
* the keys, or the *first* error encountered
* if there were no paths
*/
ldns_status ldns_dnssec_trust_tree_contains_keys(
ldns_dnssec_trust_tree *tree,
ldns_rr_list *keys);
/**
* Verifies a list of signatures for one rrset.
*
* \param[in] rrset the rrset to verify
* \param[in] rrsig a list of signatures to check
* \param[in] keys a list of keys to check with
* \param[out] good_keys if this is a (initialized) list, the pointer to keys
* from keys that validate one of the signatures
* are added to it
* \return status LDNS_STATUS_OK if there is at least one correct key
*/
ldns_status ldns_verify(ldns_rr_list *rrset,
ldns_rr_list *rrsig,
const ldns_rr_list *keys,
ldns_rr_list *good_keys);
/**
* Verifies a list of signatures for one rrset.
*
* \param[in] rrset the rrset to verify
* \param[in] rrsig a list of signatures to check
* \param[in] keys a list of keys to check with
* \param[in] check_time the time for which the validation is performed
* \param[out] good_keys if this is a (initialized) list, the pointer to keys
* from keys that validate one of the signatures
* are added to it
* \return status LDNS_STATUS_OK if there is at least one correct key
*/
ldns_status ldns_verify_time(ldns_rr_list *rrset,
ldns_rr_list *rrsig,
const ldns_rr_list *keys,
time_t check_time,
ldns_rr_list *good_keys);
/**
* Verifies a list of signatures for one rrset, but disregard the time.
* Inception and Expiration are not checked.
*
* \param[in] rrset the rrset to verify
* \param[in] rrsig a list of signatures to check
* \param[in] keys a list of keys to check with
* \param[out] good_keys if this is a (initialized) list, the pointer to keys
* from keys that validate one of the signatures
* are added to it
* \return status LDNS_STATUS_OK if there is at least one correct key
*/
ldns_status ldns_verify_notime(ldns_rr_list *rrset,
ldns_rr_list *rrsig,
const ldns_rr_list *keys,
ldns_rr_list *good_keys);
/**
* Tries to build an authentication chain from the given
* keys down to the queried domain.
*
* If we find a valid trust path, return the valid keys for the domain.
*
* \param[in] res the current resolver
* \param[in] domain the domain we want valid keys for
* \param[in] keys the current set of trusted keys
* \param[out] status pointer to the status variable where the result
* code will be stored
* \return the set of trusted keys for the domain, or NULL if no
* trust path could be built.
*/
ldns_rr_list *ldns_fetch_valid_domain_keys(const ldns_resolver * res,
const ldns_rdf * domain,
const ldns_rr_list * keys,
ldns_status *status);
/**
* Tries to build an authentication chain from the given
* keys down to the queried domain.
*
* If we find a valid trust path, return the valid keys for the domain.
*
* \param[in] res the current resolver
* \param[in] domain the domain we want valid keys for
* \param[in] keys the current set of trusted keys
* \param[in] check_time the time for which the validation is performed
* \param[out] status pointer to the status variable where the result
* code will be stored
* \return the set of trusted keys for the domain, or NULL if no
* trust path could be built.
*/
ldns_rr_list *ldns_fetch_valid_domain_keys_time(const ldns_resolver * res,
const ldns_rdf * domain, const ldns_rr_list * keys,
time_t check_time, ldns_status *status);
/**
* Validates the DNSKEY RRset for the given domain using the provided
* trusted keys.
*
* \param[in] res the current resolver
* \param[in] domain the domain we want valid keys for
* \param[in] keys the current set of trusted keys
* \return the set of trusted keys for the domain, or NULL if the RRSET
* could not be validated
*/
ldns_rr_list *ldns_validate_domain_dnskey (const ldns_resolver *res,
const ldns_rdf *domain,
const ldns_rr_list *keys);
/**
* Validates the DNSKEY RRset for the given domain using the provided
* trusted keys.
*
* \param[in] res the current resolver
* \param[in] domain the domain we want valid keys for
* \param[in] keys the current set of trusted keys
* \param[in] check_time the time for which the validation is performed
* \return the set of trusted keys for the domain, or NULL if the RRSET
* could not be validated
*/
ldns_rr_list *ldns_validate_domain_dnskey_time(
const ldns_resolver *res, const ldns_rdf *domain,
const ldns_rr_list *keys, time_t check_time);
/**
* Validates the DS RRset for the given domain using the provided trusted keys.
*
* \param[in] res the current resolver
* \param[in] domain the domain we want valid keys for
* \param[in] keys the current set of trusted keys
* \return the set of trusted keys for the domain, or NULL if the RRSET could not be validated
*/
ldns_rr_list *ldns_validate_domain_ds(const ldns_resolver *res,
const ldns_rdf *
domain,
const ldns_rr_list * keys);
/**
* Validates the DS RRset for the given domain using the provided trusted keys.
*
* \param[in] res the current resolver
* \param[in] domain the domain we want valid keys for
* \param[in] keys the current set of trusted keys
* \param[in] check_time the time for which the validation is performed
* \return the set of trusted keys for the domain, or NULL if the RRSET could not be validated
*/
ldns_rr_list *ldns_validate_domain_ds_time(
const ldns_resolver *res, const ldns_rdf *domain,
const ldns_rr_list * keys, time_t check_time);
/**
* Verifies a list of signatures for one RRset using a valid trust path.
*
* \param[in] res the current resolver
* \param[in] rrset the rrset to verify
* \param[in] rrsigs a list of signatures to check
* \param[out] validating_keys if this is a (initialized) list, the
* keys from keys that validate one of
* the signatures are added to it
* \return status LDNS_STATUS_OK if there is at least one correct key
*/
ldns_status ldns_verify_trusted(ldns_resolver *res,
ldns_rr_list *rrset,
ldns_rr_list *rrsigs,
ldns_rr_list *validating_keys);
/**
* Verifies a list of signatures for one RRset using a valid trust path.
*
* \param[in] res the current resolver
* \param[in] rrset the rrset to verify
* \param[in] rrsigs a list of signatures to check
* \param[in] check_time the time for which the validation is performed
* \param[out] validating_keys if this is a (initialized) list, the
* keys from keys that validate one of
* the signatures are added to it
* \return status LDNS_STATUS_OK if there is at least one correct key
*/
ldns_status ldns_verify_trusted_time(
ldns_resolver *res, ldns_rr_list *rrset,
ldns_rr_list *rrsigs, time_t check_time,
ldns_rr_list *validating_keys);
/**
* denial is not just a river in egypt
*
* \param[in] rr The (query) RR to check the denial of existence for
* \param[in] nsecs The list of NSEC RRs that are supposed to deny the
* existence of the RR
* \param[in] rrsigs The RRSIG RR covering the NSEC RRs
* \return LDNS_STATUS_OK if the NSEC RRs deny the existence, error code
* containing the reason they do not otherwise
*/
ldns_status ldns_dnssec_verify_denial(ldns_rr *rr,
ldns_rr_list *nsecs,
ldns_rr_list *rrsigs);
/**
* Denial of existence using NSEC3 records
* Since NSEC3 is a bit more complicated than normal denial, some
* context arguments are needed
*
* \param[in] rr The (query) RR to check the denial of existence for
* \param[in] nsecs The list of NSEC3 RRs that are supposed to deny the
* existence of the RR
* \param[in] rrsigs The RRSIG rr covering the NSEC RRs
* \param[in] packet_rcode The RCODE value of the packet that provided the
* NSEC3 RRs
* \param[in] packet_qtype The original query RR type
* \param[in] packet_nodata True if the providing packet had an empty ANSWER
* section
* \return LDNS_STATUS_OK if the NSEC3 RRs deny the existence, error code
* containing the reason they do not otherwise
*/
ldns_status ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
ldns_rr_list *nsecs,
ldns_rr_list *rrsigs,
ldns_pkt_rcode packet_rcode,
ldns_rr_type packet_qtype,
bool packet_nodata);
/**
* Same as ldns_status ldns_dnssec_verify_denial_nsec3 but also returns
* the nsec rr that matched.
*
* \param[in] rr The (query) RR to check the denial of existence for
* \param[in] nsecs The list of NSEC3 RRs that are supposed to deny the
* existence of the RR
* \param[in] rrsigs The RRSIG rr covering the NSEC RRs
* \param[in] packet_rcode The RCODE value of the packet that provided the
* NSEC3 RRs
* \param[in] packet_qtype The original query RR type
* \param[in] packet_nodata True if the providing packet had an empty ANSWER
* section
* \param[in] match On match, the given (reference to a) pointer will be set
* to point to the matching nsec resource record.
* \return LDNS_STATUS_OK if the NSEC3 RRs deny the existence, error code
* containing the reason they do not otherwise
*/
ldns_status ldns_dnssec_verify_denial_nsec3_match(ldns_rr *rr,
ldns_rr_list *nsecs,
ldns_rr_list *rrsigs,
ldns_pkt_rcode packet_rcode,
ldns_rr_type packet_qtype,
bool packet_nodata,
ldns_rr **match);
/**
* Verifies the already processed data in the buffers
* This function should probably not be used directly.
*
* \param[in] rawsig_buf Buffer containing signature data to use
* \param[in] verify_buf Buffer containing data to verify
* \param[in] key_buf Buffer containing key data to use
* \param[in] algo Signing algorithm
* \return status LDNS_STATUS_OK if the data verifies. Error if not.
*/
ldns_status ldns_verify_rrsig_buffers(ldns_buffer *rawsig_buf,
ldns_buffer *verify_buf,
ldns_buffer *key_buf,
uint8_t algo);
/**
* Like ldns_verify_rrsig_buffers, but uses raw data.
*
* \param[in] sig signature data to use
* \param[in] siglen length of signature data to use
* \param[in] verify_buf Buffer containing data to verify
* \param[in] key key data to use
* \param[in] keylen length of key data to use
* \param[in] algo Signing algorithm
* \return status LDNS_STATUS_OK if the data verifies. Error if not.
*/
ldns_status ldns_verify_rrsig_buffers_raw(unsigned char* sig,
size_t siglen,
ldns_buffer *verify_buf,
unsigned char* key,
size_t keylen,
uint8_t algo);
/**
* Verifies an rrsig. All keys in the keyset are tried.
* \param[in] rrset the rrset to check
* \param[in] rrsig the signature of the rrset
* \param[in] keys the keys to try
* \param[out] good_keys if this is a (initialized) list, the pointer to keys
* from keys that validate one of the signatures
* are added to it
* \return a list of keys which validate the rrsig + rrset. Returns
* status LDNS_STATUS_OK if at least one key matched. Else an error.
*/
ldns_status ldns_verify_rrsig_keylist(ldns_rr_list *rrset,
ldns_rr *rrsig,
const ldns_rr_list *keys,
ldns_rr_list *good_keys);
/**
* Verifies an rrsig. All keys in the keyset are tried.
* \param[in] rrset the rrset to check
* \param[in] rrsig the signature of the rrset
* \param[in] keys the keys to try
* \param[in] check_time the time for which the validation is performed
* \param[out] good_keys if this is a (initialized) list, the pointer to keys
* from keys that validate one of the signatures
* are added to it
* \return a list of keys which validate the rrsig + rrset. Returns
* status LDNS_STATUS_OK if at least one key matched. Else an error.
*/
ldns_status ldns_verify_rrsig_keylist_time(
ldns_rr_list *rrset, ldns_rr *rrsig,
const ldns_rr_list *keys, time_t check_time,
ldns_rr_list *good_keys);
/**
* Verifies an rrsig. All keys in the keyset are tried. Time is not checked.
* \param[in] rrset the rrset to check
* \param[in] rrsig the signature of the rrset
* \param[in] keys the keys to try
* \param[out] good_keys if this is a (initialized) list, the pointer to keys
* from keys that validate one of the signatures
* are added to it
* \return a list of keys which validate the rrsig + rrset. Returns
* status LDNS_STATUS_OK if at least one key matched. Else an error.
*/
ldns_status ldns_verify_rrsig_keylist_notime(ldns_rr_list *rrset,
ldns_rr *rrsig,
const ldns_rr_list *keys,
ldns_rr_list *good_keys);
/**
* verify an rrsig with 1 key
* \param[in] rrset the rrset
* \param[in] rrsig the rrsig to verify
* \param[in] key the key to use
* \return status message wether verification succeeded.
*/
ldns_status ldns_verify_rrsig(ldns_rr_list *rrset,
ldns_rr *rrsig,
ldns_rr *key);
/**
* verify an rrsig with 1 key
* \param[in] rrset the rrset
* \param[in] rrsig the rrsig to verify
* \param[in] key the key to use
* \param[in] check_time the time for which the validation is performed
* \return status message wether verification succeeded.
*/
ldns_status ldns_verify_rrsig_time(
ldns_rr_list *rrset, ldns_rr *rrsig,
ldns_rr *key, time_t check_time);
#if LDNS_BUILD_CONFIG_HAVE_SSL
/**
* verifies a buffer with signature data for a buffer with rrset data
* with an EVP_PKEY
*
* \param[in] sig the signature data
* \param[in] rrset the rrset data, sorted and processed for verification
* \param[in] key the EVP key structure
* \param[in] digest_type The digest type of the signature
*/
ldns_status ldns_verify_rrsig_evp(ldns_buffer *sig,
ldns_buffer *rrset,
EVP_PKEY *key,
const EVP_MD *digest_type);
/**
* Like ldns_verify_rrsig_evp, but uses raw signature data.
* \param[in] sig the signature data, wireformat uncompressed
* \param[in] siglen length of the signature data
* \param[in] rrset the rrset data, sorted and processed for verification
* \param[in] key the EVP key structure
* \param[in] digest_type The digest type of the signature
*/
ldns_status ldns_verify_rrsig_evp_raw(unsigned char *sig,
size_t siglen,
ldns_buffer *rrset,
EVP_PKEY *key,
const EVP_MD *digest_type);
#endif
/**
* verifies a buffer with signature data (DSA) for a buffer with rrset data
* with a buffer with key data.
*
* \param[in] sig the signature data
* \param[in] rrset the rrset data, sorted and processed for verification
* \param[in] key the key data
*/
ldns_status ldns_verify_rrsig_dsa(ldns_buffer *sig,
ldns_buffer *rrset,
ldns_buffer *key);
/**
* verifies a buffer with signature data (RSASHA1) for a buffer with rrset data
* with a buffer with key data.
*
* \param[in] sig the signature data
* \param[in] rrset the rrset data, sorted and processed for verification
* \param[in] key the key data
*/
ldns_status ldns_verify_rrsig_rsasha1(ldns_buffer *sig,
ldns_buffer *rrset,
ldns_buffer *key);
/**
* verifies a buffer with signature data (RSAMD5) for a buffer with rrset data
* with a buffer with key data.
*
* \param[in] sig the signature data
* \param[in] rrset the rrset data, sorted and processed for verification
* \param[in] key the key data
*/
ldns_status ldns_verify_rrsig_rsamd5(ldns_buffer *sig,
ldns_buffer *rrset,
ldns_buffer *key);
/**
* Like ldns_verify_rrsig_dsa, but uses raw signature and key data.
* \param[in] sig raw uncompressed wireformat signature data
* \param[in] siglen length of signature data
* \param[in] rrset ldns buffer with prepared rrset data.
* \param[in] key raw uncompressed wireformat key data
* \param[in] keylen length of key data
*/
ldns_status ldns_verify_rrsig_dsa_raw(unsigned char* sig,
size_t siglen,
ldns_buffer* rrset,
unsigned char* key,
size_t keylen);
/**
* Like ldns_verify_rrsig_rsasha1, but uses raw signature and key data.
* \param[in] sig raw uncompressed wireformat signature data
* \param[in] siglen length of signature data
* \param[in] rrset ldns buffer with prepared rrset data.
* \param[in] key raw uncompressed wireformat key data
* \param[in] keylen length of key data
*/
ldns_status ldns_verify_rrsig_rsasha1_raw(unsigned char* sig,
size_t siglen,
ldns_buffer* rrset,
unsigned char* key,
size_t keylen);
/**
* Like ldns_verify_rrsig_rsasha256, but uses raw signature and key data.
* \param[in] sig raw uncompressed wireformat signature data
* \param[in] siglen length of signature data
* \param[in] rrset ldns buffer with prepared rrset data.
* \param[in] key raw uncompressed wireformat key data
* \param[in] keylen length of key data
*/
ldns_status ldns_verify_rrsig_rsasha256_raw(unsigned char* sig,
size_t siglen,
ldns_buffer* rrset,
unsigned char* key,
size_t keylen);
/**
* Like ldns_verify_rrsig_rsasha512, but uses raw signature and key data.
* \param[in] sig raw uncompressed wireformat signature data
* \param[in] siglen length of signature data
* \param[in] rrset ldns buffer with prepared rrset data.
* \param[in] key raw uncompressed wireformat key data
* \param[in] keylen length of key data
*/
ldns_status ldns_verify_rrsig_rsasha512_raw(unsigned char* sig,
size_t siglen,
ldns_buffer* rrset,
unsigned char* key,
size_t keylen);
/**
* Like ldns_verify_rrsig_rsamd5, but uses raw signature and key data.
* \param[in] sig raw uncompressed wireformat signature data
* \param[in] siglen length of signature data
* \param[in] rrset ldns buffer with prepared rrset data.
* \param[in] key raw uncompressed wireformat key data
* \param[in] keylen length of key data
*/
ldns_status ldns_verify_rrsig_rsamd5_raw(unsigned char* sig,
size_t siglen,
ldns_buffer* rrset,
unsigned char* key,
size_t keylen);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,476 @@
/*
* special zone file structures and functions for better dnssec handling
*
* A zone contains a SOA dnssec_zone_rrset, and an AVL tree of 'normal'
* dnssec_zone_rrsets, indexed by name and type
*/
#ifndef LDNS_DNSSEC_ZONE_H
#define LDNS_DNSSEC_ZONE_H
#include <ldns/ldns.h>
#include <ldns/rbtree.h>
#include <ldns/host2str.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Singly linked list of rrs
*/
typedef struct ldns_struct_dnssec_rrs ldns_dnssec_rrs;
struct ldns_struct_dnssec_rrs
{
ldns_rr *rr;
ldns_dnssec_rrs *next;
};
/**
* Singly linked list of RRsets
*/
typedef struct ldns_struct_dnssec_rrsets ldns_dnssec_rrsets;
struct ldns_struct_dnssec_rrsets
{
ldns_dnssec_rrs *rrs;
ldns_rr_type type;
ldns_dnssec_rrs *signatures;
ldns_dnssec_rrsets *next;
};
/**
* Structure containing all resource records for a domain name
* Including the derived NSEC3, if present
*/
typedef struct ldns_struct_dnssec_name ldns_dnssec_name;
struct ldns_struct_dnssec_name
{
/**
* pointer to a dname containing the name.
* Usually points to the owner name of the first RR of the first RRset
*/
ldns_rdf *name;
/**
* Usually, the name is a pointer to the owner name of the first rr for
* this name, but sometimes there is no actual data to point to,
* for instance in
* names representing empty nonterminals. If so, set alloced to true to
* indicate that this data must also be freed when the name is freed
*/
bool name_alloced;
/**
* The rrsets for this name
*/
ldns_dnssec_rrsets *rrsets;
/**
* NSEC pointing to the next name (or NSEC3 pointing to the next NSEC3)
*/
ldns_rr *nsec;
/**
* signatures for the NSEC record
*/
ldns_dnssec_rrs *nsec_signatures;
/**
* Unlike what the name is_glue suggests, this field is set to true by
* ldns_dnssec_zone_mark_glue() or ldns_dnssec_zone_mark_and_get_glue()
* when the name, this dnssec_name struct represents, is occluded.
* Names that contain other occluded rrsets and records with glue on
* the delegation point will NOT have this bool set to true.
* This field should NOT be read directly, but only via the
* ldns_dnssec_name_is_glue() function!
*/
bool is_glue;
/**
* pointer to store the hashed name (only used when in an NSEC3 zone
*/
ldns_rdf *hashed_name;
};
/**
* Structure containing a dnssec zone
*/
struct ldns_struct_dnssec_zone {
/** points to the name containing the SOA RR */
ldns_dnssec_name *soa;
/** tree of ldns_dnssec_names */
ldns_rbtree_t *names;
};
typedef struct ldns_struct_dnssec_zone ldns_dnssec_zone;
/**
* Creates a new entry for 1 pointer to an rr and 1 pointer to the next rrs
* \return the allocated data
*/
ldns_dnssec_rrs *ldns_dnssec_rrs_new(void);
/**
* Frees the list of rrs, but *not* the individual ldns_rr records
* contained in the list
*
* \param[in] rrs the data structure to free
*/
void ldns_dnssec_rrs_free(ldns_dnssec_rrs *rrs);
/**
* Frees the list of rrs, and the individual ldns_rr records
* contained in the list
*
* \param[in] rrs the data structure to free
*/
void ldns_dnssec_rrs_deep_free(ldns_dnssec_rrs *rrs);
/**
* Adds an RR to the list of RRs. The list will remain ordered
*
* \param[in] rrs the list to add to
* \param[in] rr the RR to add
* \return LDNS_STATUS_OK on success
*/
ldns_status ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr);
/**
* Prints the given rrs to the file descriptor
*
* \param[in] out the file descriptor to print to
* \param[in] rrs the list of RRs to print
*/
void ldns_dnssec_rrs_print(FILE *out, ldns_dnssec_rrs *rrs);
/**
* Prints the given rrs to the file descriptor
*
* \param[in] out the file descriptor to print to
* \param[in] fmt the format of the textual representation
* \param[in] rrs the list of RRs to print
*/
void ldns_dnssec_rrs_print_fmt(FILE *out,
const ldns_output_format *fmt, ldns_dnssec_rrs *rrs);
/**
* Creates a new list (entry) of RRsets
* \return the newly allocated structure
*/
ldns_dnssec_rrsets *ldns_dnssec_rrsets_new(void);
/**
* Frees the list of rrsets and their rrs, but *not* the ldns_rr
* records in the sets
*
* \param[in] rrsets the data structure to free
*/
void ldns_dnssec_rrsets_free(ldns_dnssec_rrsets *rrsets);
/**
* Frees the list of rrsets and their rrs, and the ldns_rr
* records in the sets
*
* \param[in] rrsets the data structure to free
*/
void ldns_dnssec_rrsets_deep_free(ldns_dnssec_rrsets *rrsets);
/**
* Returns the rr type of the rrset (that is head of the given list)
*
* \param[in] rrsets the rrset to get the type of
* \return the rr type
*/
ldns_rr_type ldns_dnssec_rrsets_type(ldns_dnssec_rrsets *rrsets);
/**
* Sets the RR type of the rrset (that is head of the given list)
*
* \param[in] rrsets the rrset to set the type of
* \param[in] type the type to set
* \return LDNS_STATUS_OK on success
*/
ldns_status ldns_dnssec_rrsets_set_type(ldns_dnssec_rrsets *rrsets,
ldns_rr_type type);
/**
* Add an ldns_rr to the corresponding RRset in the given list of RRsets.
* If it is not present, add it as a new RRset with 1 record.
*
* \param[in] rrsets the list of rrsets to add the RR to
* \param[in] rr the rr to add to the list of rrsets
* \return LDNS_STATUS_OK on success
*/
ldns_status ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr);
/**
* Print the given list of rrsets to the fiven file descriptor
*
* \param[in] out the file descriptor to print to
* \param[in] rrsets the list of RRsets to print
* \param[in] follow if set to false, only print the first RRset
*/
void ldns_dnssec_rrsets_print(FILE *out,
ldns_dnssec_rrsets *rrsets,
bool follow);
/**
* Print the given list of rrsets to the fiven file descriptor
*
* \param[in] out the file descriptor to print to
* \param[in] fmt the format of the textual representation
* \param[in] rrsets the list of RRsets to print
* \param[in] follow if set to false, only print the first RRset
*/
void ldns_dnssec_rrsets_print_fmt(FILE *out,
const ldns_output_format *fmt,
ldns_dnssec_rrsets *rrsets,
bool follow);
/**
* Create a new data structure for a dnssec name
* \return the allocated structure
*/
ldns_dnssec_name *ldns_dnssec_name_new(void);
/**
* Create a new data structure for a dnssec name for the given RR
*
* \param[in] rr the RR to derive properties from, and to add to the name
*/
ldns_dnssec_name *ldns_dnssec_name_new_frm_rr(ldns_rr *rr);
/**
* Frees the name structure and its rrs and rrsets.
* Individual ldns_rr records therein are not freed
*
* \param[in] name the structure to free
*/
void ldns_dnssec_name_free(ldns_dnssec_name *name);
/**
* Frees the name structure and its rrs and rrsets.
* Individual ldns_rr records contained in the name are also freed
*
* \param[in] name the structure to free
*/
void ldns_dnssec_name_deep_free(ldns_dnssec_name *name);
/**
* Returns the domain name of the given dnssec_name structure
*
* \param[in] name the dnssec name to get the domain name from
* \return the domain name
*/
ldns_rdf *ldns_dnssec_name_name(ldns_dnssec_name *name);
/**
* Sets the domain name of the given dnssec_name structure
*
* \param[in] name the dnssec name to set the domain name of
* \param[in] dname the domain name to set it to. This data is *not* copied.
*/
void ldns_dnssec_name_set_name(ldns_dnssec_name *name,
ldns_rdf *dname);
/**
* Returns if dnssec_name structure is marked as glue.
* The ldns_dnssec_zone_mark_glue() function has to be called on a zone before
* using this function.
* Only names that have only glue rrsets will be marked.
* Names that have other occluded rrsets and names containing glue on the
* delegation point will NOT be marked!
*
* \param[in] name the dnssec name to get the domain name from
* \return true if the structure is marked as glue, false otherwise.
*/
bool ldns_dnssec_name_is_glue(ldns_dnssec_name *name);
/**
* Sets the NSEC(3) RR of the given dnssec_name structure
*
* \param[in] name the dnssec name to set the domain name of
* \param[in] nsec the nsec rr to set it to. This data is *not* copied.
*/
void ldns_dnssec_name_set_nsec(ldns_dnssec_name *name, ldns_rr *nsec);
/**
* Compares the domain names of the two arguments in their
* canonical ordening.
*
* \param[in] a The first dnssec_name to compare
* \param[in] b The second dnssec_name to compare
* \return -1 if the domain name of a comes before that of b in canonical
* ordening, 1 if it is the other way around, and 0 if they are
* equal
*/
int ldns_dnssec_name_cmp(const void *a, const void *b);
/**
* Inserts the given rr at the right place in the current dnssec_name
* No checking is done whether the name matches
*
* \param[in] name The ldns_dnssec_name to add the RR to
* \param[in] rr The RR to add
* \return LDNS_STATUS_OK on success, error code otherwise
*/
ldns_status ldns_dnssec_name_add_rr(ldns_dnssec_name *name,
ldns_rr *rr);
/**
* Find the RRset with the given type in within this name structure
*
* \param[in] name the name to find the RRset in
* \param[in] type the type of the RRset to find
* \return the RRset, or NULL if not present
*/
ldns_dnssec_rrsets *ldns_dnssec_name_find_rrset(ldns_dnssec_name *name,
ldns_rr_type type);
/**
* Find the RRset with the given name and type in the zone
*
* \param[in] zone the zone structure to find the RRset in
* \param[in] dname the domain name of the RRset to find
* \param[in] type the type of the RRset to find
* \return the RRset, or NULL if not present
*/
ldns_dnssec_rrsets *ldns_dnssec_zone_find_rrset(ldns_dnssec_zone *zone,
ldns_rdf *dname,
ldns_rr_type type);
/**
* Prints the RRs in the dnssec name structure to the given
* file descriptor
*
* \param[in] out the file descriptor to print to
* \param[in] name the name structure to print the contents of
*/
void ldns_dnssec_name_print(FILE *out, ldns_dnssec_name *name);
/**
* Prints the RRs in the dnssec name structure to the given
* file descriptor
*
* \param[in] out the file descriptor to print to
* \param[in] fmt the format of the textual representation
* \param[in] name the name structure to print the contents of
*/
void ldns_dnssec_name_print_fmt(FILE *out,
const ldns_output_format *fmt, ldns_dnssec_name *name);
/**
* Creates a new dnssec_zone structure
* \return the allocated structure
*/
ldns_dnssec_zone *ldns_dnssec_zone_new(void);
/**
* Create a new dnssec zone from a file.
* \param[out] z the new zone
* \param[in] *fp the filepointer to use
* \param[in] *origin the zones' origin
* \param[in] c default class to use (IN)
* \param[in] ttl default ttl to use
*
* \return ldns_status mesg with an error or LDNS_STATUS_OK
*/
ldns_status ldns_dnssec_zone_new_frm_fp(ldns_dnssec_zone** z, FILE* fp,
ldns_rdf* origin, uint32_t ttl, ldns_rr_class c);
/**
* Create a new dnssec zone from a file, keep track of the line numbering
* \param[out] z the new zone
* \param[in] *fp the filepointer to use
* \param[in] *origin the zones' origin
* \param[in] ttl default ttl to use
* \param[in] c default class to use (IN)
* \param[out] line_nr used for error msg, to get to the line number
*
* \return ldns_status mesg with an error or LDNS_STATUS_OK
*/
ldns_status ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone** z, FILE* fp,
ldns_rdf* origin, uint32_t ttl, ldns_rr_class c, int* line_nr);
/**
* Frees the given zone structure, and its rbtree of dnssec_names
* Individual ldns_rr RRs within those names are *not* freed
* \param[in] *zone the zone to free
*/
void ldns_dnssec_zone_free(ldns_dnssec_zone *zone);
/**
* Frees the given zone structure, and its rbtree of dnssec_names
* Individual ldns_rr RRs within those names are also freed
* \param[in] *zone the zone to free
*/
void ldns_dnssec_zone_deep_free(ldns_dnssec_zone *zone);
/**
* Adds the given RR to the zone.
* It find whether there is a dnssec_name with that name present.
* If so, add it to that, if not create a new one.
* Special handling of NSEC and RRSIG provided
*
* \param[in] zone the zone to add the RR to
* \param[in] rr The RR to add
* \return LDNS_STATUS_OK on success, an error code otherwise
*/
ldns_status ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone,
ldns_rr *rr);
/**
* Prints the rbtree of ldns_dnssec_name structures to the file descriptor
*
* \param[in] out the file descriptor to print the names to
* \param[in] tree the tree of ldns_dnssec_name structures to print
* \param[in] print_soa if true, print SOA records, if false, skip them
*/
void ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa);
/**
* Prints the rbtree of ldns_dnssec_name structures to the file descriptor
*
* \param[in] out the file descriptor to print the names to
* \param[in] fmt the format of the textual representation
* \param[in] tree the tree of ldns_dnssec_name structures to print
* \param[in] print_soa if true, print SOA records, if false, skip them
*/
void ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt,
ldns_rbtree_t *tree, bool print_soa);
/**
* Prints the complete zone to the given file descriptor
*
* \param[in] out the file descriptor to print to
* \param[in] zone the dnssec_zone to print
*/
void ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone);
/**
* Prints the complete zone to the given file descriptor
*
* \param[in] out the file descriptor to print to
* \param[in] fmt the format of the textual representation
* \param[in] zone the dnssec_zone to print
*/
void ldns_dnssec_zone_print_fmt(FILE *out,
const ldns_output_format *fmt, ldns_dnssec_zone *zone);
/**
* Adds explicit dnssec_name structures for the empty nonterminals
* in this zone. (this is needed for NSEC3 generation)
*
* \param[in] zone the zone to check for empty nonterminals
* return LDNS_STATUS_OK on success.
*/
ldns_status ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone);
/**
* If a NSEC3PARAM is available in the apex, walks the zone and returns true
* on the first optout nsec3.
*
* \param[in] zone the zone to check for nsec3 optout records
* return true when the zone has at least one nsec3 optout record.
*/
bool ldns_dnssec_zone_is_nsec3_optout(ldns_dnssec_zone* zone);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,109 @@
/*
* $Id: duration.h 4341 2011-01-31 15:21:09Z matthijs $
*
* Copyright (c) 2009 NLNet Labs. 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*
*/
/**
*
* This file is copied from the OpenDNSSEC source repository
* and only slightly adapted to make it fit.
*/
/**
*
* Durations.
*/
#ifndef LDNS_DURATION_H
#define LDNS_DURATION_H
#include <stdint.h>
#include <time.h>
/**
* Duration.
*
*/
typedef struct ldns_duration_struct ldns_duration_type;
struct ldns_duration_struct
{
time_t years;
time_t months;
time_t weeks;
time_t days;
time_t hours;
time_t minutes;
time_t seconds;
};
/**
* Create a new 'instant' duration.
* \return ldns_duration_type* created duration
*
*/
ldns_duration_type* ldns_duration_create(void);
/**
* Compare durations.
* \param[in] d1 one duration
* \param[in] d2 another duration
* \return int 0 if equal, -1 if d1 < d2, 1 if d2 < d1
*
*/
int ldns_duration_compare(ldns_duration_type* d1, ldns_duration_type* d2);
/**
* Create a duration from string.
* \param[in] str string-format duration
* \return ldns_duration_type* created duration
*
*/
ldns_duration_type* ldns_duration_create_from_string(const char* str);
/**
* Convert a duration to a string.
* \param[in] duration duration to be converted
* \return char* string-format duration
*
*/
char* ldns_duration2string(ldns_duration_type* duration);
/**
* Convert a duration to a time.
* \param[in] duration duration to be converted
* \return time_t time-format duration
*
*/
time_t ldns_duration2time(ldns_duration_type* duration);
/**
* Clean up duration.
* \param[in] duration duration to be cleaned up
*
*/
void ldns_duration_cleanup(ldns_duration_type* duration);
#endif /* LDNS_DURATION_H */

123
contrib/ldns/ldns/error.h Normal file
View file

@ -0,0 +1,123 @@
/**
* \file error.h
*
* Defines error numbers and functions to translate those to a readable string.
*
*/
/**
* a Net::DNS like library for C
*
* (c) NLnet Labs, 2005-2006
*
* See the file LICENSE for the license
*/
#ifndef LDNS_ERROR_H
#define LDNS_ERROR_H
#include <ldns/util.h>
#ifdef __cplusplus
extern "C" {
#endif
enum ldns_enum_status {
LDNS_STATUS_OK,
LDNS_STATUS_EMPTY_LABEL,
LDNS_STATUS_LABEL_OVERFLOW,
LDNS_STATUS_DOMAINNAME_OVERFLOW,
LDNS_STATUS_DOMAINNAME_UNDERFLOW,
LDNS_STATUS_DDD_OVERFLOW,
LDNS_STATUS_PACKET_OVERFLOW,
LDNS_STATUS_INVALID_POINTER,
LDNS_STATUS_MEM_ERR,
LDNS_STATUS_INTERNAL_ERR,
LDNS_STATUS_SSL_ERR,
LDNS_STATUS_ERR,
LDNS_STATUS_INVALID_INT,
LDNS_STATUS_INVALID_IP4,
LDNS_STATUS_INVALID_IP6,
LDNS_STATUS_INVALID_STR,
LDNS_STATUS_INVALID_B32_EXT,
LDNS_STATUS_INVALID_B64,
LDNS_STATUS_INVALID_HEX,
LDNS_STATUS_INVALID_TIME,
LDNS_STATUS_NETWORK_ERR,
LDNS_STATUS_ADDRESS_ERR,
LDNS_STATUS_FILE_ERR,
LDNS_STATUS_UNKNOWN_INET,
LDNS_STATUS_NOT_IMPL,
LDNS_STATUS_NULL,
LDNS_STATUS_CRYPTO_UNKNOWN_ALGO,
LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL,
LDNS_STATUS_CRYPTO_NO_RRSIG,
LDNS_STATUS_CRYPTO_NO_DNSKEY,
LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY,
LDNS_STATUS_CRYPTO_NO_DS,
LDNS_STATUS_CRYPTO_NO_TRUSTED_DS,
LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY,
LDNS_STATUS_CRYPTO_VALIDATED,
LDNS_STATUS_CRYPTO_BOGUS,
LDNS_STATUS_CRYPTO_SIG_EXPIRED,
LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED,
LDNS_STATUS_CRYPTO_TSIG_BOGUS,
LDNS_STATUS_CRYPTO_TSIG_ERR,
LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION,
LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR,
LDNS_STATUS_ENGINE_KEY_NOT_LOADED,
LDNS_STATUS_NSEC3_ERR,
LDNS_STATUS_RES_NO_NS,
LDNS_STATUS_RES_QUERY,
LDNS_STATUS_WIRE_INCOMPLETE_HEADER,
LDNS_STATUS_WIRE_INCOMPLETE_QUESTION,
LDNS_STATUS_WIRE_INCOMPLETE_ANSWER,
LDNS_STATUS_WIRE_INCOMPLETE_AUTHORITY,
LDNS_STATUS_WIRE_INCOMPLETE_ADDITIONAL,
LDNS_STATUS_NO_DATA,
LDNS_STATUS_CERT_BAD_ALGORITHM,
LDNS_STATUS_SYNTAX_TYPE_ERR,
LDNS_STATUS_SYNTAX_CLASS_ERR,
LDNS_STATUS_SYNTAX_TTL_ERR,
LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL,
LDNS_STATUS_SYNTAX_RDATA_ERR,
LDNS_STATUS_SYNTAX_DNAME_ERR,
LDNS_STATUS_SYNTAX_VERSION_ERR,
LDNS_STATUS_SYNTAX_ALG_ERR,
LDNS_STATUS_SYNTAX_KEYWORD_ERR,
LDNS_STATUS_SYNTAX_TTL,
LDNS_STATUS_SYNTAX_ORIGIN,
LDNS_STATUS_SYNTAX_INCLUDE,
LDNS_STATUS_SYNTAX_EMPTY,
LDNS_STATUS_SYNTAX_ITERATIONS_OVERFLOW,
LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR,
LDNS_STATUS_SYNTAX_INTEGER_OVERFLOW,
LDNS_STATUS_SYNTAX_BAD_ESCAPE,
LDNS_STATUS_SOCKET_ERROR,
LDNS_STATUS_SYNTAX_ERR,
LDNS_STATUS_DNSSEC_EXISTENCE_DENIED,
LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED,
LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED,
LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND,
LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG,
LDNS_STATUS_MISSING_RDATA_FIELDS_KEY,
LDNS_STATUS_CRYPTO_SIG_EXPIRED_WITHIN_MARGIN,
LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED_WITHIN_MARGIN
};
typedef enum ldns_enum_status ldns_status;
extern ldns_lookup_table ldns_error_str[];
/**
* look up a descriptive text by each error. This function
* could use a better name
* \param[in] err ldns_status number
* \return the string for that error
*/
const char *ldns_get_errorstr_by_id(ldns_status err);
#ifdef __cplusplus
}
#endif
#endif /* LDNS_ERROR_H */

113
contrib/ldns/ldns/higher.h Normal file
View file

@ -0,0 +1,113 @@
/**
* \file higher.h
*
* Specifies some higher level functions that could
* be useful for certain applications
*/
/*
* a Net::DNS like library for C
*
* (c) NLnet Labs, 2005-2006
*
* See the file LICENSE for the license
*/
#ifndef LDNS_HIGHER_H
#define LDNS_HIGHER_H
#include <ldns/resolver.h>
#include <ldns/rdata.h>
#include <ldns/rr.h>
#include <ldns/host2str.h>
#include <ldns/tsig.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Ask the resolver about name
* and return all address records
* \param[in] r the resolver to use
* \param[in] name the name to look for
* \param[in] c the class to use
* \param[in] flags give some optional flags to the query
*/
ldns_rr_list *ldns_get_rr_list_addr_by_name(ldns_resolver *r, ldns_rdf *name, ldns_rr_class c, uint16_t flags);
/**
* ask the resolver about the address
* and return the name
* \param[in] r the resolver to use
* \param[in] addr the addr to look for
* \param[in] c the class to use
* \param[in] flags give some optional flags to the query
*/
ldns_rr_list *ldns_get_rr_list_name_by_addr(ldns_resolver *r, ldns_rdf *addr, ldns_rr_class c, uint16_t flags);
/**
* wade through fp (a /etc/hosts like file)
* and return a rr_list containing all the
* defined hosts in there
* \param[in] fp the file pointer to use
* \return ldns_rr_list * with the names
*/
ldns_rr_list *ldns_get_rr_list_hosts_frm_fp(FILE *fp);
/**
* wade through fp (a /etc/hosts like file)
* and return a rr_list containing all the
* defined hosts in there
* \param[in] fp the file pointer to use
* \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
* \return ldns_rr_list * with the names
*/
ldns_rr_list *ldns_get_rr_list_hosts_frm_fp_l(FILE *fp, int *line_nr);
/**
* wade through fp (a /etc/hosts like file)
* and return a rr_list containing all the
* defined hosts in there
* \param[in] filename the filename to use (NULL for /etc/hosts)
* \return ldns_rr_list * with the names
*/
ldns_rr_list *ldns_get_rr_list_hosts_frm_file(char *filename);
/**
* This function is a wrapper function for ldns_get_rr_list_name_by_addr
* and ldns_get_rr_list_addr_by_name. It's name is from the getaddrinfo()
* library call. It tries to mimic that call, but without the lowlevel
* stuff.
* \param[in] res The resolver. If this value is NULL then a resolver will
* be created by ldns_getaddrinfo.
* \param[in] node the name or ip address to look up
* \param[in] c the class to look in
* \param[out] list put the found RR's in this list
* \return the number of RR found.
*/
uint16_t ldns_getaddrinfo(ldns_resolver *res, ldns_rdf *node, ldns_rr_class c, ldns_rr_list **list);
/**
* Check if t is enumerated in the nsec type rdata
* \param[in] nsec the NSEC Record to look in
* \param[in] t the type to check for
* \return true when t is found, otherwise return false
*/
bool ldns_nsec_type_check(ldns_rr *nsec, ldns_rr_type t);
/**
* Print a number of rdf's of the RR. The rdfnum-list must
* be ended by -1, otherwise unpredictable things might happen.
* rdfs may be printed multiple times
* \param[in] fp FILE * to write to
* \param[in] r RR to write
* \param[in] rdfnum a list of rdf to print.
*/
void ldns_print_rr_rdf(FILE *fp, ldns_rr *r, int rdfnum, ...);
#ifdef __cplusplus
}
#endif
#endif /* LDNS_HIGHER_H */

View file

@ -0,0 +1,759 @@
/**
* host2str.h - txt presentation of RRs
*
* a Net::DNS like library for C
*
* (c) NLnet Labs, 2005-2006
*
* See the file LICENSE for the license
*/
/**
* \file
*
* Contains functions to translate the main structures to their text
* representation, as well as functions to print them.
*/
#ifndef LDNS_HOST2STR_H
#define LDNS_HOST2STR_H
#include <ldns/common.h>
#include <ldns/error.h>
#include <ldns/rr.h>
#include <ldns/rdata.h>
#include <ldns/packet.h>
#include <ldns/buffer.h>
#include <ldns/resolver.h>
#include <ldns/zone.h>
#include <ctype.h>
#include "ldns/util.h"
#ifdef __cplusplus
extern "C" {
#endif
#define LDNS_APL_IP4 1
#define LDNS_APL_IP6 2
#define LDNS_APL_MASK 0x7f
#define LDNS_APL_NEGATION 0x80
/**
* Represent a NULL pointer (in stead of a pointer to a ldns_rr as "; (null)"
* as opposed to outputting nothing at all in such a case.
*/
#define LDNS_COMMENT_NULLS 0x0001
/** Show key id with DNSKEY RR's as comment */
#define LDNS_COMMENT_KEY_ID 0x0002
/** Show if a DNSKEY is a ZSK or KSK as comment */
#define LDNS_COMMENT_KEY_TYPE 0x0004
/** Show DNSKEY key size as comment */
#define LDNS_COMMENT_KEY_SIZE 0x0008
/** Show key id, type and size as comment for DNSKEY RR's */
#define LDNS_COMMENT_KEY (LDNS_COMMENT_KEY_ID \
|LDNS_COMMENT_KEY_TYPE\
|LDNS_COMMENT_KEY_SIZE)
/** Provide bubblebabble representation for DS RR's as comment */
#define LDNS_COMMENT_BUBBLEBABBLE 0x0010
/** Show when a NSEC3 RR has the optout flag set as comment */
#define LDNS_COMMENT_FLAGS 0x0020
/** Show the unhashed owner and next owner names for NSEC3 RR's as comment */
#define LDNS_COMMENT_NSEC3_CHAIN 0x0040
/** Print mark up */
#define LDNS_COMMENT_LAYOUT 0x0080
/** Also comment KEY_ID with RRSIGS **/
#define LDNS_COMMENT_RRSIGS 0x0100
/**
* Output format specifier
*
* Determines how Packets, Resource Records and Resource record data fiels are
* formatted when printing or converting to string.
* Currently it is only used to specify what aspects of a Resource Record are
* annotated in the comment section of the textual representation the record.
* This is speciefed with flags and potential exra data (such as for example
* a lookup map of hashes to real names for annotation NSEC3 records).
*/
struct ldns_struct_output_format
{
/** Specification of how RR's should be formatted in text */
int flags;
/** Potential extra data to be used with formatting RR's in text */
void *data;
};
typedef struct ldns_struct_output_format ldns_output_format;
/**
* Standard output format record that disables commenting in the textual
* representation of Resource Records completely.
*/
extern const ldns_output_format *ldns_output_format_nocomments;
/**
* Standard output format record that annotated only DNSKEY RR's with commenti
* text.
*/
extern const ldns_output_format *ldns_output_format_onlykeyids;
/**
* The default output format record. Same as ldns_output_format_onlykeyids.
*/
extern const ldns_output_format *ldns_output_format_default;
/**
* Standard output format record that shows all DNSKEY related information in
* the comment text, plus the optout flag when set with NSEC3's, plus the
* bubblebabble representation of DS RR's.
*/
extern const ldns_output_format *ldns_output_format_bubblebabble;
/**
* Converts an ldns packet opcode value to its mnemonic, and adds that
* to the output buffer
* \param[in] *output the buffer to add the data to
* \param[in] opcode to find the string representation of
* \return LDNS_STATUS_OK on success, or a buffer failure mode on error
*/
ldns_status
ldns_pkt_opcode2buffer_str(ldns_buffer *output, ldns_pkt_opcode opcode);
/**
* Converts an ldns packet rcode value to its mnemonic, and adds that
* to the output buffer
* \param[in] *output the buffer to add the data to
* \param[in] rcode to find the string representation of
* \return LDNS_STATUS_OK on success, or a buffer failure mode on error
*/
ldns_status
ldns_pkt_rcode2buffer_str(ldns_buffer *output, ldns_pkt_rcode rcode);
/**
* Converts an ldns algorithm type to its mnemonic, and adds that
* to the output buffer
* \param[in] *output the buffer to add the data to
* \param[in] algorithm to find the string representation of
* \return LDNS_STATUS_OK on success, or a buffer failure mode on error
*/
ldns_status
ldns_algorithm2buffer_str(ldns_buffer *output,
ldns_algorithm algorithm);
/**
* Converts an ldns certificate algorithm type to its mnemonic,
* and adds that to the output buffer
* \param[in] *output the buffer to add the data to
* \param[in] cert_algorithm to find the string representation of
* \return LDNS_STATUS_OK on success, or a buffer failure mode on error
*/
ldns_status
ldns_cert_algorithm2buffer_str(ldns_buffer *output,
ldns_cert_algorithm cert_algorithm);
/**
* Converts a packet opcode to its mnemonic and returns that as
* an allocated null-terminated string.
* Remember to free it.
*
* \param[in] opcode the opcode to convert to text
* \return null terminated char * data, or NULL on error
*/
char *ldns_pkt_opcode2str(ldns_pkt_opcode opcode);
/**
* Converts a packet rcode to its mnemonic and returns that as
* an allocated null-terminated string.
* Remember to free it.
*
* \param[in] rcode the rcode to convert to text
* \return null terminated char * data, or NULL on error
*/
char *ldns_pkt_rcode2str(ldns_pkt_rcode rcode);
/**
* Converts a signing algorithms to its mnemonic and returns that as
* an allocated null-terminated string.
* Remember to free it.
*
* \param[in] algorithm the algorithm to convert to text
* \return null terminated char * data, or NULL on error
*/
char *ldns_pkt_algorithm2str(ldns_algorithm algorithm);
/**
* Converts a cert algorithm to its mnemonic and returns that as
* an allocated null-terminated string.
* Remember to free it.
*
* \param[in] cert_algorithm to convert to text
* \return null terminated char * data, or NULL on error
*/
char *ldns_pkt_cert_algorithm2str(ldns_cert_algorithm cert_algorithm);
/**
* Converts an LDNS_RDF_TYPE_A rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_a(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts an LDNS_RDF_TYPE_AAAA rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_aaaa(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts an LDNS_RDF_TYPE_STR rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_str(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts an LDNS_RDF_TYPE_B64 rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_b64(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts an LDNS_RDF_TYPE_B32_EXT rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_b32_ext(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts an LDNS_RDF_TYPE_HEX rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_hex(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts an LDNS_RDF_TYPE_TYPE rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_type(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts an LDNS_RDF_TYPE_CLASS rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_class(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts an LDNS_RDF_TYPE_ALG rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_alg(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts an ldns_rr_type value to its string representation,
* and places it in the given buffer
* \param[in] *output The buffer to add the data to
* \param[in] type the ldns_rr_type to convert
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rr_type2buffer_str(ldns_buffer *output,
const ldns_rr_type type);
/**
* Converts an ldns_rr_type value to its string representation,
* and returns that string. For unknown types, the string
* "TYPE<id>" is returned. This function allocates data that must be
* freed by the caller
* \param[in] type the ldns_rr_type to convert
* \return a newly allocated string
*/
char *ldns_rr_type2str(const ldns_rr_type type);
/**
* Converts an ldns_rr_class value to its string representation,
* and places it in the given buffer
* \param[in] *output The buffer to add the data to
* \param[in] klass the ldns_rr_class to convert
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rr_class2buffer_str(ldns_buffer *output,
const ldns_rr_class klass);
/**
* Converts an ldns_rr_class value to its string representation,
* and returns that string. For unknown types, the string
* "CLASS<id>" is returned. This function allocates data that must be
* freed by the caller
* \param[in] klass the ldns_rr_class to convert
* \return a newly allocated string
*/
char *ldns_rr_class2str(const ldns_rr_class klass);
/**
* Converts an LDNS_RDF_TYPE_CERT rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_cert_alg(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts an LDNS_RDF_TYPE_LOC rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_loc(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts an LDNS_RDF_TYPE_UNKNOWN rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_unknown(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts an LDNS_RDF_TYPE_NSAP rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_nsap(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts an LDNS_RDF_TYPE_ATMA rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_atma(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts an LDNS_RDF_TYPE_WKS rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_wks(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts an LDNS_RDF_TYPE_NSEC rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_nsec(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts an LDNS_RDF_TYPE_PERIOD rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_period(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts an LDNS_RDF_TYPE_TSIGTIME rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_tsigtime(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts an LDNS_RDF_TYPE_APL rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_apl(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts an LDNS_RDF_TYPE_INT16_DATA rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_int16_data(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts an LDNS_RDF_TYPE_IPSECKEY rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_ipseckey(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts an LDNS_RDF_TYPE_TSIG rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_tsig(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts the data in the rdata field to presentation
* format (as char *) and appends it to the given buffer
*
* \param[in] output pointer to the buffer to append the data to
* \param[in] rdf the pointer to the rdafa field containing the data
* \return status
*/
ldns_status ldns_rdf2buffer_str(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts the data in the resource record to presentation
* format (as char *) and appends it to the given buffer.
* The presentation format of DNSKEY record is annotated with comments giving
* the id, type and size of the key.
*
* \param[in] output pointer to the buffer to append the data to
* \param[in] rr the pointer to the rr field to convert
* \return status
*/
ldns_status ldns_rr2buffer_str(ldns_buffer *output, const ldns_rr *rr);
/**
* Converts the data in the resource record to presentation
* format (as char *) and appends it to the given buffer.
* The presentation format is annotated with comments giving
* additional information on the record.
*
* \param[in] output pointer to the buffer to append the data to
* \param[in] fmt how to format the textual representation of the
* resource record.
* \param[in] rr the pointer to the rr field to convert
* \return status
*/
ldns_status ldns_rr2buffer_str_fmt(ldns_buffer *output,
const ldns_output_format *fmt, const ldns_rr *rr);
/**
* Converts the data in the DNS packet to presentation
* format (as char *) and appends it to the given buffer
*
* \param[in] output pointer to the buffer to append the data to
* \param[in] pkt the pointer to the packet to convert
* \return status
*/
ldns_status ldns_pkt2buffer_str(ldns_buffer *output, const ldns_pkt *pkt);
/**
* Converts the data in the DNS packet to presentation
* format (as char *) and appends it to the given buffer
*
* \param[in] output pointer to the buffer to append the data to
* \param[in] fmt how to format the textual representation of the packet
* \param[in] pkt the pointer to the packet to convert
* \return status
*/
ldns_status ldns_pkt2buffer_str_fmt(ldns_buffer *output,
const ldns_output_format *fmt, const ldns_pkt *pkt);
/**
* Converts an LDNS_RDF_TYPE_NSEC3_SALT rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_nsec3_salt(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts the data in the DNS packet to presentation
* format (as char *) and appends it to the given buffer
*
* \param[in] output pointer to the buffer to append the data to
* \param[in] k the pointer to the private key to convert
* \return status
*/
ldns_status ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k);
/**
* Converts an LDNS_RDF_TYPE_INT8 rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_int8(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts an LDNS_RDF_TYPE_INT16 rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_int16(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts an LDNS_RDF_TYPE_INT32 rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_int32(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts an LDNS_RDF_TYPE_TIME rdata element to string format and adds it to the output buffer
* \param[in] *rdf The rdata to convert
* \param[in] *output The buffer to add the data to
* \return LDNS_STATUS_OK on success, and error status on failure
*/
ldns_status ldns_rdf2buffer_str_time(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Converts the data in the rdata field to presentation format and
* returns that as a char *.
* Remember to free it.
*
* \param[in] rdf The rdata field to convert
* \return null terminated char * data, or NULL on error
*/
char *ldns_rdf2str(const ldns_rdf *rdf);
/**
* Converts the data in the resource record to presentation format and
* returns that as a char *.
* Remember to free it.
*
* \param[in] rr The rdata field to convert
* \return null terminated char * data, or NULL on error
*/
char *ldns_rr2str(const ldns_rr *rr);
/**
* Converts the data in the resource record to presentation format and
* returns that as a char *.
* Remember to free it.
*
* \param[in] fmt how to format the resource record
* \param[in] rr The rdata field to convert
* \return null terminated char * data, or NULL on error
*/
char *ldns_rr2str_fmt(const ldns_output_format *fmt, const ldns_rr *rr);
/**
* Converts the data in the DNS packet to presentation format and
* returns that as a char *.
* Remember to free it.
*
* \param[in] pkt The rdata field to convert
* \return null terminated char * data, or NULL on error
*/
char *ldns_pkt2str(const ldns_pkt *pkt);
/**
* Converts the data in the DNS packet to presentation format and
* returns that as a char *.
* Remember to free it.
*
* \param[in] fmt how to format the packet
* \param[in] pkt The rdata field to convert
* \return null terminated char * data, or NULL on error
*/
char *ldns_pkt2str_fmt(const ldns_output_format *fmt, const ldns_pkt *pkt);
/**
* Converts a private key to the test presentation fmt and
* returns that as a char *.
* Remember to free it.
*
* \param[in] k the key to convert to text
* \return null terminated char * data, or NULL on error
*/
char *ldns_key2str(const ldns_key *k);
/**
* Converts a list of resource records to presentation format
* and returns that as a char *.
* Remember to free it.
*
* \param[in] rr_list the rr_list to convert to text
* \return null terminated char * data, or NULL on error
*/
char *ldns_rr_list2str(const ldns_rr_list *rr_list);
/**
* Converts a list of resource records to presentation format
* and returns that as a char *.
* Remember to free it.
*
* \param[in] fmt how to format the list of resource records
* \param[in] rr_list the rr_list to convert to text
* \return null terminated char * data, or NULL on error
*/
char *ldns_rr_list2str_fmt(
const ldns_output_format *fmt, const ldns_rr_list *rr_list);
/**
* Returns the data in the buffer as a null terminated char * string
* Buffer data must be char * type, and must be freed by the caller
*
* \param[in] buffer buffer containing char * data
* \return null terminated char * data, or NULL on error
*/
char *ldns_buffer2str(ldns_buffer *buffer);
/**
* Prints the data in the rdata field to the given file stream
* (in presentation format)
*
* \param[in] output the file stream to print to
* \param[in] rdf the rdata field to print
* \return void
*/
void ldns_rdf_print(FILE *output, const ldns_rdf *rdf);
/**
* Prints the data in the resource record to the given file stream
* (in presentation format)
*
* \param[in] output the file stream to print to
* \param[in] rr the resource record to print
* \return void
*/
void ldns_rr_print(FILE *output, const ldns_rr *rr);
/**
* Prints the data in the resource record to the given file stream
* (in presentation format)
*
* \param[in] output the file stream to print to
* \param[in] fmt format of the textual representation
* \param[in] rr the resource record to print
* \return void
*/
void ldns_rr_print_fmt(FILE *output,
const ldns_output_format *fmt, const ldns_rr *rr);
/**
* Prints the data in the DNS packet to the given file stream
* (in presentation format)
*
* \param[in] output the file stream to print to
* \param[in] pkt the packet to print
* \return void
*/
void ldns_pkt_print(FILE *output, const ldns_pkt *pkt);
/**
* Prints the data in the DNS packet to the given file stream
* (in presentation format)
*
* \param[in] output the file stream to print to
* \param[in] fmt format of the textual representation
* \param[in] pkt the packet to print
* \return void
*/
void ldns_pkt_print_fmt(FILE *output,
const ldns_output_format *fmt, const ldns_pkt *pkt);
/**
* Converts a rr_list to presentation format and appends it to
* the output buffer
* \param[in] output the buffer to append output to
* \param[in] list the ldns_rr_list to print
* \return ldns_status
*/
ldns_status ldns_rr_list2buffer_str(ldns_buffer *output, const ldns_rr_list *list);
/**
* Converts a rr_list to presentation format and appends it to
* the output buffer
* \param[in] output the buffer to append output to
* \param[in] fmt format of the textual representation
* \param[in] list the ldns_rr_list to print
* \return ldns_status
*/
ldns_status ldns_rr_list2buffer_str_fmt(ldns_buffer *output,
const ldns_output_format *fmt, const ldns_rr_list *list);
/**
* Converts the header of a packet to presentation format and appends it to
* the output buffer
* \param[in] output the buffer to append output to
* \param[in] pkt the packet to convert the header of
* \return ldns_status
*/
ldns_status ldns_pktheader2buffer_str(ldns_buffer *output, const ldns_pkt *pkt);
/**
* print a rr_list to output
* \param[in] output the fd to print to
* \param[in] list the rr_list to print
*/
void ldns_rr_list_print(FILE *output, const ldns_rr_list *list);
/**
* print a rr_list to output
* \param[in] output the fd to print to
* \param[in] fmt format of the textual representation
* \param[in] list the rr_list to print
*/
void ldns_rr_list_print_fmt(FILE *output,
const ldns_output_format *fmt, const ldns_rr_list *list);
/**
* Print a resolver (in sofar that is possible) state
* to output.
* \param[in] output the fd to print to
* \param[in] r the resolver to print
*/
void ldns_resolver_print(FILE *output, const ldns_resolver *r);
/**
* Print a resolver (in sofar that is possible) state
* to output.
* \param[in] output the fd to print to
* \param[in] fmt format of the textual representation
* \param[in] r the resolver to print
*/
void ldns_resolver_print_fmt(FILE *output,
const ldns_output_format *fmt, const ldns_resolver *r);
/**
* Print a zone structure * to output. Note the SOA record
* is included in this output
* \param[in] output the fd to print to
* \param[in] z the zone to print
*/
void ldns_zone_print(FILE *output, const ldns_zone *z);
/**
* Print a zone structure * to output. Note the SOA record
* is included in this output
* \param[in] output the fd to print to
* \param[in] fmt format of the textual representation
* \param[in] z the zone to print
*/
void ldns_zone_print_fmt(FILE *output,
const ldns_output_format *fmt, const ldns_zone *z);
/**
* Print the ldns_rdf containing a dname to the buffer
* \param[in] output the buffer to print to
* \param[in] dname the dname to print
* \return ldns_status message if the printing succeeded
*/
ldns_status ldns_rdf2buffer_str_dname(ldns_buffer *output, const ldns_rdf *dname);
#ifdef __cplusplus
}
#endif
#endif /* LDNS_HOST2STR_H */

View file

@ -0,0 +1,164 @@
/*
* host2wire.h - 2wire conversion routines
*
* a Net::DNS like library for C
*
* (c) NLnet Labs, 2005-2006
*
* See the file LICENSE for the license
*/
/**
* \file
*
* Contains all functions to translate the main structures to wire format
*/
#ifndef LDNS_HOST2WIRE_H
#define LDNS_HOST2WIRE_H
#include <ldns/common.h>
#include <ldns/error.h>
#include <ldns/rr.h>
#include <ldns/rdata.h>
#include <ldns/packet.h>
#include <ldns/buffer.h>
#include <ctype.h>
#include "ldns/util.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Copies the dname data to the buffer in wire format
* \param[out] *buffer buffer to append the result to
* \param[in] *name rdata dname to convert
* \return ldns_status
*/
ldns_status ldns_dname2buffer_wire(ldns_buffer *buffer, const ldns_rdf *name);
/**
* Copies the rdata data to the buffer in wire format
* \param[out] *output buffer to append the result to
* \param[in] *rdf rdata to convert
* \return ldns_status
*/
ldns_status ldns_rdf2buffer_wire(ldns_buffer *output, const ldns_rdf *rdf);
/**
* Copies the rdata data to the buffer in wire format
* If the rdata is a dname, the letters will be lowercased
* during the conversion
* \param[out] *output buffer to append the result to
* \param[in] *rdf rdata to convert
* \return ldns_status
*/
ldns_status ldns_rdf2buffer_wire_canonical(ldns_buffer *output,
const ldns_rdf *rdf);
/**
* Copies the rr data to the buffer in wire format
* \param[out] *output buffer to append the result to
* \param[in] *rr resource record to convert
* \param[in] section the section in the packet this rr is supposed to be in
* (to determine whether to add rdata or not)
* \return ldns_status
*/
ldns_status ldns_rr2buffer_wire(ldns_buffer *output,
const ldns_rr *rr,
int section);
/**
* Copies the rr data to the buffer in wire format, in canonical format
* according to RFC3597 (every dname in rdata fields of RR's mentioned in
* that RFC will be lowercased)
* \param[out] *output buffer to append the result to
* \param[in] *rr resource record to convert
* \param[in] section the section in the packet this rr is supposed to be in
* (to determine whether to add rdata or not)
* \return ldns_status
*/
ldns_status ldns_rr2buffer_wire_canonical(ldns_buffer *output,
const ldns_rr *rr,
int section);
/**
* Converts a rrsig to wireformat BUT EXCLUDE the rrsig rdata
* This is needed in DNSSEC verification
* \param[out] output buffer to append the result to
* \param[in] sigrr signature rr to operate on
* \return ldns_status
*/
ldns_status ldns_rrsig2buffer_wire(ldns_buffer *output, const ldns_rr *sigrr);
/**
* Converts an rr's rdata to wireformat, while excluding
* the ownername and all the stuff before the rdata.
* This is needed in DNSSEC keytag calculation, the ds
* calcalution from the key and maybe elsewhere.
*
* \param[out] *output buffer where to put the result
* \param[in] *rr rr to operate on
* \return ldns_status
*/
ldns_status ldns_rr_rdata2buffer_wire(ldns_buffer *output, const ldns_rr *rr);
/**
* Copies the packet data to the buffer in wire format
* \param[out] *output buffer to append the result to
* \param[in] *pkt packet to convert
* \return ldns_status
*/
ldns_status ldns_pkt2buffer_wire(ldns_buffer *output, const ldns_pkt *pkt);
/**
* Copies the rr_list data to the buffer in wire format
* \param[out] *output buffer to append the result to
* \param[in] *rrlist rr_list to to convert
* \return ldns_status
*/
ldns_status ldns_rr_list2buffer_wire(ldns_buffer *output, const ldns_rr_list *rrlist);
/**
* Allocates an array of uint8_t at dest, and puts the wireformat of the
* given rdf in that array. The result_size value contains the
* length of the array, if it succeeds, and 0 otherwise (in which case
* the function also returns NULL)
*
* \param[out] dest pointer to the array of bytes to be created
* \param[in] rdf the rdata field to convert
* \param[out] size the size of the converted result
*/
ldns_status ldns_rdf2wire(uint8_t **dest, const ldns_rdf *rdf, size_t *size);
/**
* Allocates an array of uint8_t at dest, and puts the wireformat of the
* given rr in that array. The result_size value contains the
* length of the array, if it succeeds, and 0 otherwise (in which case
* the function also returns NULL)
*
* If the section argument is LDNS_SECTION_QUESTION, data like ttl and rdata
* are not put into the result
*
* \param[out] dest pointer to the array of bytes to be created
* \param[in] rr the rr to convert
* \param[out] size the size of the converted result
*/
ldns_status ldns_rr2wire(uint8_t **dest, const ldns_rr *rr, int, size_t *size);
/**
* Allocates an array of uint8_t at dest, and puts the wireformat of the
* given packet in that array. The result_size value contains the
* length of the array, if it succeeds, and 0 otherwise (in which case
* the function also returns NULL)
*/
ldns_status ldns_pkt2wire(uint8_t **dest, const ldns_pkt *p, size_t *size);
#ifdef __cplusplus
}
#endif
#endif /* LDNS_HOST2WIRE_H */

603
contrib/ldns/ldns/keys.h Normal file
View file

@ -0,0 +1,603 @@
/*
*
* keys.h
*
* priv key definitions
*
* a Net::DNS like library for C
*
* (c) NLnet Labs, 2005-2006
*
* See the file LICENSE for the license
*/
/**
* \file
*
* Addendum to \ref dnssec.h, this module contains key and algorithm definitions and functions.
*/
#ifndef LDNS_KEYS_H
#define LDNS_KEYS_H
#include <ldns/common.h>
#if LDNS_BUILD_CONFIG_HAVE_SSL
#include <openssl/ssl.h>
#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
#include <ldns/dnssec.h>
#include <ldns/util.h>
#include <errno.h>
#ifdef __cplusplus
extern "C" {
#endif
extern ldns_lookup_table ldns_signing_algorithms[];
#define LDNS_KEY_ZONE_KEY 0x0100 /* rfc 4034 */
#define LDNS_KEY_SEP_KEY 0x0001 /* rfc 4034 */
#define LDNS_KEY_REVOKE_KEY 0x0080 /* rfc 5011 */
/**
* Algorithms used in dns
*/
enum ldns_enum_algorithm
{
LDNS_RSAMD5 = 1, /* RFC 4034,4035 */
LDNS_DH = 2,
LDNS_DSA = 3,
LDNS_ECC = 4,
LDNS_RSASHA1 = 5,
LDNS_DSA_NSEC3 = 6,
LDNS_RSASHA1_NSEC3 = 7,
LDNS_RSASHA256 = 8, /* RFC 5702 */
LDNS_RSASHA512 = 10, /* RFC 5702 */
LDNS_ECC_GOST = 12, /* RFC 5933 */
LDNS_ECDSAP256SHA256 = 13, /* RFC 6605 */
LDNS_ECDSAP384SHA384 = 14, /* RFC 6605 */
LDNS_INDIRECT = 252,
LDNS_PRIVATEDNS = 253,
LDNS_PRIVATEOID = 254
};
typedef enum ldns_enum_algorithm ldns_algorithm;
/**
* Hashing algorithms used in the DS record
*/
enum ldns_enum_hash
{
LDNS_SHA1 = 1, /* RFC 4034 */
LDNS_SHA256 = 2, /* RFC 4509 */
LDNS_HASH_GOST = 3, /* RFC 5933 */
LDNS_SHA384 = 4 /* RFC 6605 */
};
typedef enum ldns_enum_hash ldns_hash;
/**
* Algorithms used in dns for signing
*/
enum ldns_enum_signing_algorithm
{
LDNS_SIGN_RSAMD5 = LDNS_RSAMD5,
LDNS_SIGN_RSASHA1 = LDNS_RSASHA1,
LDNS_SIGN_DSA = LDNS_DSA,
LDNS_SIGN_RSASHA1_NSEC3 = LDNS_RSASHA1_NSEC3,
LDNS_SIGN_RSASHA256 = LDNS_RSASHA256,
LDNS_SIGN_RSASHA512 = LDNS_RSASHA512,
LDNS_SIGN_DSA_NSEC3 = LDNS_DSA_NSEC3,
LDNS_SIGN_ECC_GOST = LDNS_ECC_GOST,
LDNS_SIGN_ECDSAP256SHA256 = LDNS_ECDSAP256SHA256,
LDNS_SIGN_ECDSAP384SHA384 = LDNS_ECDSAP384SHA384,
LDNS_SIGN_HMACMD5 = 157, /* not official! This type is for TSIG, not DNSSEC */
LDNS_SIGN_HMACSHA1 = 158, /* not official! This type is for TSIG, not DNSSEC */
LDNS_SIGN_HMACSHA256 = 159 /* ditto */
};
typedef enum ldns_enum_signing_algorithm ldns_signing_algorithm;
/**
* General key structure, can contain all types of keys that
* are used in DNSSEC. Mostly used to store private keys, since
* public keys can also be stored in a \ref ldns_rr with type
* \ref LDNS_RR_TYPE_DNSKEY.
*
* This structure can also store some variables that influence the
* signatures generated by signing with this key, for instance the
* inception date.
*/
struct ldns_struct_key {
ldns_signing_algorithm _alg;
/** Whether to use this key when signing */
bool _use;
/** Storage pointers for the types of keys supported */
/* TODO remove unions? */
struct {
#if LDNS_BUILD_CONFIG_HAVE_SSL
#ifndef S_SPLINT_S
/* The key can be an OpenSSL EVP Key
*/
EVP_PKEY *key;
#endif
#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
/**
* The key can be an HMAC key
*/
struct {
unsigned char *key;
size_t size;
} hmac;
/** the key structure can also just point to some external
* key data
*/
void *external_key;
} _key;
/** Depending on the key we can have extra data */
union {
/** Some values that influence generated signatures */
struct {
/** The TTL of the rrset that is currently signed */
uint32_t orig_ttl;
/** The inception date of signatures made with this key. */
uint32_t inception;
/** The expiration date of signatures made with this key. */
uint32_t expiration;
/** The keytag of this key. */
uint16_t keytag;
/** The dnssec key flags as specified in RFC4035, like ZSK and KSK */
uint16_t flags;
} dnssec;
} _extra;
/** Owner name of the key */
ldns_rdf *_pubkey_owner;
};
typedef struct ldns_struct_key ldns_key;
/**
* Same as rr_list, but now for keys
*/
struct ldns_struct_key_list
{
size_t _key_count;
ldns_key **_keys;
};
typedef struct ldns_struct_key_list ldns_key_list;
/**
* Creates a new empty key list
* \return a new ldns_key_list structure pointer
*/
ldns_key_list *ldns_key_list_new(void);
/**
* Creates a new empty key structure
* \return a new ldns_key * structure
*/
ldns_key *ldns_key_new(void);
/**
* Creates a new key based on the algorithm
*
* \param[in] a The algorithm to use
* \param[in] size the number of bytes for the keysize
* \return a new ldns_key structure with the key
*/
ldns_key *ldns_key_new_frm_algorithm(ldns_signing_algorithm a, uint16_t size);
/**
* Creates a new priv key based on the
* contents of the file pointed by fp.
*
* The file should be in Private-key-format v1.x.
*
* \param[out] k the new ldns_key structure
* \param[in] fp the file pointer to use
* \return an error or LDNS_STATUS_OK
*/
ldns_status ldns_key_new_frm_fp(ldns_key **k, FILE *fp);
/**
* Creates a new private key based on the
* contents of the file pointed by fp
*
* The file should be in Private-key-format v1.x.
*
* \param[out] k the new ldns_key structure
* \param[in] fp the file pointer to use
* \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
* \return an error or LDNS_STATUS_OK
*/
ldns_status ldns_key_new_frm_fp_l(ldns_key **k, FILE *fp, int *line_nr);
#if LDNS_BUILD_CONFIG_HAVE_SSL
/**
* Read the key with the given id from the given engine and store it
* in the given ldns_key structure. The algorithm type is set
*/
ldns_status ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldns_algorithm);
/**
* frm_fp helper function. This function parses the
* remainder of the (RSA) priv. key file generated from bind9
* \param[in] fp the file to parse
* \return NULL on failure otherwise a RSA structure
*/
RSA *ldns_key_new_frm_fp_rsa(FILE *fp);
#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
#if LDNS_BUILD_CONFIG_HAVE_SSL
/**
* frm_fp helper function. This function parses the
* remainder of the (RSA) priv. key file generated from bind9
* \param[in] fp the file to parse
* \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
* \return NULL on failure otherwise a RSA structure
*/
RSA *ldns_key_new_frm_fp_rsa_l(FILE *fp, int *line_nr);
#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
#if LDNS_BUILD_CONFIG_HAVE_SSL
/**
* frm_fp helper function. This function parses the
* remainder of the (DSA) priv. key file
* \param[in] fp the file to parse
* \return NULL on failure otherwise a RSA structure
*/
DSA *ldns_key_new_frm_fp_dsa(FILE *fp);
#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
#if LDNS_BUILD_CONFIG_HAVE_SSL
/**
* frm_fp helper function. This function parses the
* remainder of the (DSA) priv. key file
* \param[in] fp the file to parse
* \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
* \return NULL on failure otherwise a RSA structure
*/
DSA *ldns_key_new_frm_fp_dsa_l(FILE *fp, int *line_nr);
#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
#if LDNS_BUILD_CONFIG_HAVE_SSL
/**
* frm_fp helper function. This function parses the
* remainder of the (HMAC-MD5) key file
* This function allocated a buffer that needs to be freed
* \param[in] fp the file to parse
* \param[out] hmac_size the number of bits in the resulting buffer
* \return NULL on failure otherwise a newly allocated char buffer
*/
unsigned char *ldns_key_new_frm_fp_hmac(FILE *fp, size_t *hmac_size);
#endif
#if LDNS_BUILD_CONFIG_HAVE_SSL
/**
* frm_fp helper function. This function parses the
* remainder of the (HMAC-MD5) key file
* This function allocated a buffer that needs to be freed
* \param[in] fp the file to parse
* \param[in] line_nr pointer to an integer containing the current line number (for error reporting purposes)
* \param[out] hmac_size the number of bits in the resulting buffer
* \return NULL on failure otherwise a newly allocated char buffer
*/
unsigned char *ldns_key_new_frm_fp_hmac_l(FILE *fp, int *line_nr, size_t *hmac_size);
#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
/* acces write functions */
/**
* Set the key's algorithm
* \param[in] k the key
* \param[in] l the algorithm
*/
void ldns_key_set_algorithm(ldns_key *k, ldns_signing_algorithm l);
#if LDNS_BUILD_CONFIG_HAVE_SSL
/**
* Set the key's evp key
* \param[in] k the key
* \param[in] e the evp key
*/
void ldns_key_set_evp_key(ldns_key *k, EVP_PKEY *e);
/**
* Set the key's rsa data
* \param[in] k the key
* \param[in] r the rsa data
*/
void ldns_key_set_rsa_key(ldns_key *k, RSA *r);
/**
* Set the key's dsa data
* \param[in] k the key
* \param[in] d the dsa data
*/
void ldns_key_set_dsa_key(ldns_key *k, DSA *d);
/**
* Get the PKEY id for GOST, loads GOST into openssl as a side effect.
* Only available if GOST is compiled into the library and openssl.
* \return the gost id for EVP_CTX creation.
*/
int ldns_key_EVP_load_gost_id(void);
/** Release the engine reference held for the GOST engine. */
void ldns_key_EVP_unload_gost(void);
#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
/**
* Set the key's hmac data
* \param[in] k the key
* \param[in] hmac the raw key data
*/
void ldns_key_set_hmac_key(ldns_key *k, unsigned char *hmac);
/**
* Set the key id data. This is used if the key points to
* some externally stored key data
*
* Only the pointer is set, the data there is not copied,
* and must be freed manually; ldns_key_deep_free() does
* *not* free this data
* \param[in] key the key
* \param[in] external_key key id data
*/
void ldns_key_set_external_key(ldns_key *key, void *external_key);
/**
* Set the key's hmac size
* \param[in] k the key
* \param[in] hmac_size the size of the hmac data
*/
void ldns_key_set_hmac_size(ldns_key *k, size_t hmac_size);
/**
* Set the key's original ttl
* \param[in] k the key
* \param[in] t the ttl
*/
void ldns_key_set_origttl(ldns_key *k, uint32_t t);
/**
* Set the key's inception date (seconds after epoch)
* \param[in] k the key
* \param[in] i the inception
*/
void ldns_key_set_inception(ldns_key *k, uint32_t i);
/**
* Set the key's expiration date (seconds after epoch)
* \param[in] k the key
* \param[in] e the expiration
*/
void ldns_key_set_expiration(ldns_key *k, uint32_t e);
/**
* Set the key's pubkey owner
* \param[in] k the key
* \param[in] r the owner
*/
void ldns_key_set_pubkey_owner(ldns_key *k, ldns_rdf *r);
/**
* Set the key's key tag
* \param[in] k the key
* \param[in] tag the keytag
*/
void ldns_key_set_keytag(ldns_key *k, uint16_t tag);
/**
* Set the key's flags
* \param[in] k the key
* \param[in] flags the flags
*/
void ldns_key_set_flags(ldns_key *k, uint16_t flags);
/**
* Set the keylist's key count to count
* \param[in] key the key
* \param[in] count the cuont
*/
void ldns_key_list_set_key_count(ldns_key_list *key, size_t count);
/**
* pushes a key to a keylist
* \param[in] key_list the key_list to push to
* \param[in] key the key to push
* \return false on error, otherwise true
*/
bool ldns_key_list_push_key(ldns_key_list *key_list, ldns_key *key);
/**
* returns the number of keys in the key list
* \param[in] key_list the key_list
* \return the numbers of keys in the list
*/
size_t ldns_key_list_key_count(const ldns_key_list *key_list);
/**
* returns a pointer to the key in the list at the given position
* \param[in] key the key
* \param[in] nr the position in the list
* \return the key
*/
ldns_key *ldns_key_list_key(const ldns_key_list *key, size_t nr);
#if LDNS_BUILD_CONFIG_HAVE_SSL
/**
* returns the (openssl) RSA struct contained in the key
* \param[in] k the key to look in
* \return the RSA * structure in the key
*/
RSA *ldns_key_rsa_key(const ldns_key *k);
/**
* returns the (openssl) EVP struct contained in the key
* \param[in] k the key to look in
* \return the RSA * structure in the key
*/
EVP_PKEY *ldns_key_evp_key(const ldns_key *k);
#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
/**
* returns the (openssl) DSA struct contained in the key
*/
#if LDNS_BUILD_CONFIG_HAVE_SSL
DSA *ldns_key_dsa_key(const ldns_key *k);
#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
/**
* return the signing alg of the key
* \param[in] k the key
* \return the algorithm
*/
ldns_signing_algorithm ldns_key_algorithm(const ldns_key *k);
/**
* set the use flag
* \param[in] k the key
* \param[in] v the boolean value to set the _use field to
*/
void ldns_key_set_use(ldns_key *k, bool v);
/**
* return the use flag
* \param[in] k the key
* \return the boolean value of the _use field
*/
bool ldns_key_use(const ldns_key *k);
/**
* return the hmac key data
* \param[in] k the key
* \return the hmac key data
*/
unsigned char *ldns_key_hmac_key(const ldns_key *k);
/**
* return the key id key data
* \param[in] k the key
* \return the key id data
*/
void *ldns_key_external_key(const ldns_key *k);
/**
* return the hmac key size
* \param[in] k the key
* \return the hmac key size
*/
size_t ldns_key_hmac_size(const ldns_key *k);
/**
* return the original ttl of the key
* \param[in] k the key
* \return the original ttl
*/
uint32_t ldns_key_origttl(const ldns_key *k);
/**
* return the key's inception date
* \param[in] k the key
* \return the inception date
*/
uint32_t ldns_key_inception(const ldns_key *k);
/**
* return the key's expiration date
* \param[in] k the key
* \return the experiration date
*/
uint32_t ldns_key_expiration(const ldns_key *k);
/**
* return the keytag
* \param[in] k the key
* \return the keytag
*/
uint16_t ldns_key_keytag(const ldns_key *k);
/**
* return the public key's owner
* \param[in] k the key
* \return the owner
*/
ldns_rdf *ldns_key_pubkey_owner(const ldns_key *k);
/**
* Set the 'use' flag for all keys in the list
* \param[in] keys The key_list
* \param[in] v The value to set the use flags to
*/
void
ldns_key_list_set_use(ldns_key_list *keys, bool v);
/**
* return the flag of the key
* \param[in] k the key
* \return the flag
*/
uint16_t ldns_key_flags(const ldns_key *k);
/**
* pops the last rr from a keylist
* \param[in] key_list the rr_list to pop from
* \return NULL if nothing to pop. Otherwise the popped RR
*/
ldns_key *ldns_key_list_pop_key(ldns_key_list *key_list);
/**
* converts a ldns_key to a public key rr
* If the key data exists at an external point, the corresponding
* rdata field must still be added with ldns_rr_rdf_push() to the
* result rr of this function
*
* \param[in] k the ldns_key to convert
* \return ldns_rr representation of the key
*/
ldns_rr *ldns_key2rr(const ldns_key *k);
/**
* print a private key to the file ouput
*
* \param[in] output the FILE descriptor where to print to
* \param[in] k the ldns_key to print
*/
void ldns_key_print(FILE *output, const ldns_key *k);
/**
* frees a key structure, but not its internal data structures
*
* \param[in] key the key object to free
*/
void ldns_key_free(ldns_key *key);
/**
* frees a key structure and all its internal data structures, except
* the data set by ldns_key_set_external_key()
*
* \param[in] key the key object to free
*/
void ldns_key_deep_free(ldns_key *key);
/**
* Frees a key list structure
* \param[in] key_list the key list object to free
*/
void ldns_key_list_free(ldns_key_list *key_list);
/**
* Instantiates a DNSKEY or DS RR from file.
* \param[in] filename the file to read the record from
* \return the corresponding RR, or NULL if the parsing failed
*/
ldns_rr * ldns_read_anchor_file(const char *filename);
/**
* Returns the 'default base name' for key files;
* IE. K\<zone\>+\<alg\>+\<keytag\>
* (without the .key or .private)
* The memory for this is allocated by this function,
* and should be freed by the caller
*
* \param[in] key the key to get the file name from
* \returns A string containing the file base name
*/
char *ldns_key_get_file_base_name(ldns_key *key);
/**
* See if a key algorithm is supported
* \param[in] algo the signing algorithm number.
* \returns true if supported.
*/
int ldns_key_algo_supported(int algo);
/**
* Get signing algorithm by name. Comparison is case insensitive.
* \param[in] name string with the name.
* \returns 0 on parse failure or the algorithm number.
*/
ldns_signing_algorithm ldns_get_signing_algorithm_by_name(const char* name);
#ifdef __cplusplus
}
#endif
#endif /* LDNS_KEYS_H */

156
contrib/ldns/ldns/ldns.h Normal file
View file

@ -0,0 +1,156 @@
/*
* dns.h -- defines for the Domain Name System
*
* Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
*
* See LICENSE for the license.
*
* This library was created by:
* Jelte Jansen, Erik Rozendaal and Miek Gieben
*
* A bunch of defines that are used in the DNS.
*/
/**
\mainpage LDNS Documentation
\section introduction Introduction
The goal of ldns is to simplify DNS programming, it supports recent RFCs
like the DNSSEC documents, and allow developers to easily create software
conforming to current RFCs, and experimental software for current Internet
drafts. A secondary benefit of using ldns is speed, because ldns is written
in C, and although it is not optimized for performance, it should be a lot
faster than Perl.
The first main tool to use ldns is Drill, from which part of the library was
derived. From version 1.0.0 on, drill is included in the ldns release
and will not be distributed seperately anymore. The library also includes some
other examples and tools to show how it can be used. These can be found in the
examples/ directory in the tarball.
ldns depends on OpenSSL for it's cryptographic functions.
Feature list
- Transparent IPv4 and IPv6 support (overridable if necessary),
- TSIG support,
- DNSSEC support; signing and verification,
- small size,
- online documentation as well as manual pages.
If you want to send us patches please use the code from subversion (trunk).
\section using_ldns Using ldns
Almost all interaction between an application and ldns goes through the ldns
data structures (\ref ldns_rr, \ref ldns_pkt, etc.). These are input or
output to the functions of ldns. For example, \ref ldns_zone_new_frm_fp
reads a zone from a \c FILE pointer, and returns an \ref ldns_zone
structure.
Let's use Drill as an example. Drill is a tool much like dig, whose most
basic function is to send 1 query to a nameserver and print the response.
To be able to do this, drill uses the resolver module of ldns, which acts as
a stub resolver. The resolver module uses the net module to actually send
the query that drill requested. It then uses the wire2host module to
translate the response and place it in ldns' internal structures. These are
passed back to drill, which then uses the host2str module to print the
response in presentation format.
\section gettingstarted Getting Started
See the \ref design page for a very high level description of the design
choices made for ldns.
For an overview of the functions and types ldns provides, you can check out
the \ref ldns ldns header file descriptions.
If you want to see some libdns action, you can read our tutorials:
- \ref tutorial1_mx
- \ref tutorial2_zone
- \ref tutorial3_signzone
Or you can just use the menu above to browse through the API docs.
<div style="visibility:hidden;">
\image html LogoInGradientBar2-y100.png
</div>
*/
/**
* \file ldns.h
*
* Including this file will include all ldns files, and define some lookup tables.
*/
#ifndef LDNS_DNS_H
#define LDNS_DNS_H
#include <stdio.h>
#include <stdlib.h>
#include <ldns/util.h>
#include <ldns/buffer.h>
#include <ldns/common.h>
#include <ldns/dname.h>
#include <ldns/dnssec.h>
#include <ldns/dnssec_verify.h>
#include <ldns/dnssec_sign.h>
#include <ldns/duration.h>
#include <ldns/error.h>
#include <ldns/higher.h>
#include <ldns/host2str.h>
#include <ldns/host2wire.h>
#include <ldns/net.h>
#include <ldns/packet.h>
#include <ldns/rdata.h>
#include <ldns/resolver.h>
#include <ldns/rr.h>
#include <ldns/str2host.h>
#include <ldns/tsig.h>
#include <ldns/update.h>
#include <ldns/wire2host.h>
#include <ldns/rr_functions.h>
#include <ldns/keys.h>
#include <ldns/parse.h>
#include <ldns/zone.h>
#include <ldns/dnssec_zone.h>
#include <ldns/rbtree.h>
#include <ldns/sha1.h>
#include <ldns/sha2.h>
#ifdef __cplusplus
extern "C" {
#endif
#define LDNS_IP4ADDRLEN (32/8)
#define LDNS_IP6ADDRLEN (128/8)
#define LDNS_PORT 53
#define LDNS_ROOT_LABEL_STR "."
#define LDNS_DEFAULT_TTL 3600
/* lookup tables for standard DNS stuff */
/** Taken from RFC 2538, section 2.1. */
extern ldns_lookup_table ldns_certificate_types[];
/** Taken from RFC 2535, section 7. */
extern ldns_lookup_table ldns_algorithms[];
/** Taken from RFC 2538. */
extern ldns_lookup_table ldns_cert_algorithms[];
/** rr types */
extern ldns_lookup_table ldns_rr_classes[];
/** Response codes */
extern ldns_lookup_table ldns_rcodes[];
/** Operation codes */
extern ldns_lookup_table ldns_opcodes[];
/** EDNS flags */
extern ldns_lookup_table ldns_edns_flags[];
#ifdef __cplusplus
}
#endif
#endif /* LDNS_DNS_H */

208
contrib/ldns/ldns/net.h.in Normal file
View file

@ -0,0 +1,208 @@
/*
* net.h
*
* DNS Resolver definitions
*
* a Net::DNS like library for C
*
* (c) NLnet Labs, 2005-2006
*
* See the file LICENSE for the license
*/
#ifndef LDNS_NET_H
#define LDNS_NET_H
#include <ldns/ldns.h>
@include_sys_socket_h@
#ifdef __cplusplus
extern "C" {
#endif
#define LDNS_DEFAULT_TIMEOUT_SEC 5
#define LDNS_DEFAULT_TIMEOUT_USEC 0
/**
* \file
*
* Contains functions to send and receive packets over a network.
*/
/**
* Sends a buffer to an ip using udp and return the respons as a ldns_pkt
* \param[in] qbin the ldns_buffer to be send
* \param[in] to the ip addr to send to
* \param[in] tolen length of the ip addr
* \param[in] timeout the timeout value for the network
* \param[out] answersize size of the packet
* \param[out] result packet with the answer
* \return status
*/
ldns_status ldns_udp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout, size_t *answersize);
/**
* Send an udp query and don't wait for an answer but return
* the socket
* \param[in] qbin the ldns_buffer to be send
* \param[in] to the ip addr to send to
* \param[in] tolen length of the ip addr
* \param[in] timeout *unused*, was the timeout value for the network
* \return the socket used
*/
int ldns_udp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout);
/**
* Send an tcp query and don't wait for an answer but return
* the socket
* \param[in] qbin the ldns_buffer to be send
* \param[in] to the ip addr to send to
* \param[in] tolen length of the ip addr
* \param[in] timeout the timeout value for the connect attempt
* \return the socket used
*/
int ldns_tcp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout);
/**
* Sends a buffer to an ip using tcp and return the respons as a ldns_pkt
* \param[in] qbin the ldns_buffer to be send
* \param[in] qbin the ldns_buffer to be send
* \param[in] to the ip addr to send to
* \param[in] tolen length of the ip addr
* \param[in] timeout the timeout value for the network
* \param[out] answersize size of the packet
* \param[out] result packet with the answer
* \return status
*/
ldns_status ldns_tcp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout, size_t *answersize);
/**
* Sends ptk to the nameserver at the resolver object. Returns the data
* as a ldns_pkt
*
* \param[out] pkt packet received from the nameserver
* \param[in] r the resolver to use
* \param[in] query_pkt the query to send
* \return status
*/
ldns_status ldns_send(ldns_pkt **pkt, ldns_resolver *r, const ldns_pkt *query_pkt);
/**
* Sends and ldns_buffer (presumably containing a packet to the nameserver at the resolver object. Returns the data
* as a ldns_pkt
*
* \param[out] pkt packet received from the nameserver
* \param[in] r the resolver to use
* \param[in] qb the buffer to send
* \param[in] tsig_mac the tsig MAC to authenticate the response with (NULL to do no TSIG authentication)
* \return status
*/
ldns_status ldns_send_buffer(ldns_pkt **pkt, ldns_resolver *r, ldns_buffer *qb, ldns_rdf *tsig_mac);
/**
* Create a tcp socket to the specified address
* \param[in] to ip and family
* \param[in] tolen length of to
* \param[in] timeout timeout for the connect attempt
* \return a socket descriptor
*/
int ldns_tcp_connect(const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout);
/**
* Create a udp socket to the specified address
* \param[in] to ip and family
* \param[in] timeout *unused*, was timeout for the socket
* \return a socket descriptor
*/
int ldns_udp_connect(const struct sockaddr_storage *to, struct timeval timeout);
/**
* send a query via tcp to a server. Don't want for the answer
*
* \param[in] qbin the buffer to send
* \param[in] sockfd the socket to use
* \param[in] to which ip to send it
* \param[in] tolen socketlen
* \return number of bytes sent
*/
ssize_t ldns_tcp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to, socklen_t tolen);
/**
* send a query via udp to a server. Don;t want for the answer
*
* \param[in] qbin the buffer to send
* \param[in] sockfd the socket to use
* \param[in] to which ip to send it
* \param[in] tolen socketlen
* \return number of bytes sent
*/
ssize_t ldns_udp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to, socklen_t tolen);
/**
* Gives back a raw packet from the wire and reads the header data from the given
* socket. Allocates the data (of size size) itself, so don't forget to free
*
* \param[in] sockfd the socket to read from
* \param[out] size the number of bytes that are read
* \param[in] timeout the time allowed between packets.
* \return the data read
*/
uint8_t *ldns_tcp_read_wire_timeout(int sockfd, size_t *size, struct timeval timeout);
/**
* This routine may block. Use ldns_tcp_read_wire_timeout, it checks timeouts.
* Gives back a raw packet from the wire and reads the header data from the given
* socket. Allocates the data (of size size) itself, so don't forget to free
*
* \param[in] sockfd the socket to read from
* \param[out] size the number of bytes that are read
* \return the data read
*/
uint8_t *ldns_tcp_read_wire(int sockfd, size_t *size);
/**
* Gives back a raw packet from the wire and reads the header data from the given
* socket. Allocates the data (of size size) itself, so don't forget to free
*
* \param[in] sockfd the socket to read from
* \param[in] fr the address of the client (if applicable)
* \param[in] *frlen the lenght of the client's addr (if applicable)
* \param[out] size the number of bytes that are read
* \return the data read
*/
uint8_t *ldns_udp_read_wire(int sockfd, size_t *size, struct sockaddr_storage *fr, socklen_t *frlen);
/**
* returns the native sockaddr representation from the rdf.
* \param[in] rd the ldns_rdf to operate on
* \param[in] port what port to use. 0 means; use default (53)
* \param[out] size what is the size of the sockaddr_storage
* \return struct sockaddr* the address in the format so other
* functions can use it (sendto)
*/
struct sockaddr_storage * ldns_rdf2native_sockaddr_storage(const ldns_rdf *rd, uint16_t port, size_t *size);
/**
* returns an rdf with the sockaddr info. works for ip4 and ip6
* \param[in] sock the struct sockaddr_storage to convert
* \param[in] port what port was used. When NULL this is not set
* \return ldns_rdf* wth the address
*/
ldns_rdf * ldns_sockaddr_storage2rdf(struct sockaddr_storage *sock, uint16_t *port);
/**
* Prepares the resolver for an axfr query
* The query is sent and the answers can be read with ldns_axfr_next
* \param[in] resolver the resolver to use
* \param[in] domain the domain to exfr
* \param[in] c the class to use
* \return ldns_status the status of the transfer
*/
ldns_status ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class c);
#ifdef __cplusplus
}
#endif
#endif /* LDNS_NET_H */

855
contrib/ldns/ldns/packet.h Normal file
View file

@ -0,0 +1,855 @@
/*
* packet.h
*
* DNS packet definitions
*
* a Net::DNS like library for C
*
* (c) NLnet Labs, 2005-2006
*
* See the file LICENSE for the license
*/
/**
* \file
*
* Contains the definition of ldns_pkt and its parts, as well
* as functions to manipulate those.
*/
#ifndef LDNS_PACKET_H
#define LDNS_PACKET_H
#define LDNS_MAX_PACKETLEN 65535
/* allow flags to be given to mk_query */
#define LDNS_QR 1 /* QueRy - query flag */
#define LDNS_AA 2 /* Authoritative Answer - server flag */
#define LDNS_TC 4 /* TrunCated - server flag */
#define LDNS_RD 8 /* Recursion Desired - query flag */
#define LDNS_CD 16 /* Checking Disabled - query flag */
#define LDNS_RA 32 /* Recursion Available - server flag */
#define LDNS_AD 64 /* Authenticated Data - server flag */
#include <ldns/error.h>
#include <ldns/common.h>
#include <ldns/rr.h>
#include <sys/time.h>
#ifdef __cplusplus
extern "C" {
#endif
/* opcodes for pkt's */
enum ldns_enum_pkt_opcode {
LDNS_PACKET_QUERY = 0,
LDNS_PACKET_IQUERY = 1,
LDNS_PACKET_STATUS = 2, /* there is no 3?? DNS is weird */
LDNS_PACKET_NOTIFY = 4,
LDNS_PACKET_UPDATE = 5
};
typedef enum ldns_enum_pkt_opcode ldns_pkt_opcode;
/* rcodes for pkts */
enum ldns_enum_pkt_rcode {
LDNS_RCODE_NOERROR = 0,
LDNS_RCODE_FORMERR = 1,
LDNS_RCODE_SERVFAIL = 2,
LDNS_RCODE_NXDOMAIN = 3,
LDNS_RCODE_NOTIMPL = 4,
LDNS_RCODE_REFUSED = 5,
LDNS_RCODE_YXDOMAIN = 6,
LDNS_RCODE_YXRRSET = 7,
LDNS_RCODE_NXRRSET = 8,
LDNS_RCODE_NOTAUTH = 9,
LDNS_RCODE_NOTZONE = 10
};
typedef enum ldns_enum_pkt_rcode ldns_pkt_rcode;
/**
* Header of a dns packet
*
* Contains the information about the packet itself, as specified in RFC1035
<pre>
4.1.1. Header section format
The header contains the following fields:
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ID |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR| Opcode |AA|TC|RD|RA| Z | RCODE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QDCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ANCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| NSCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ARCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
where:
ID A 16 bit identifier assigned by the program that
generates any kind of query. This identifier is copied
the corresponding reply and can be used by the requester
to match up replies to outstanding queries.
QR A one bit field that specifies whether this message is a
query (0), or a response (1).
OPCODE A four bit field that specifies kind of query in this
message. This value is set by the originator of a query
and copied into the response. The values are:
0 a standard query (QUERY)
1 an inverse query (IQUERY)
2 a server status request (STATUS)
3-15 reserved for future use
AA Authoritative Answer - this bit is valid in responses,
and specifies that the responding name server is an
authority for the domain name in question section.
Note that the contents of the answer section may have
multiple owner names because of aliases. The AA bit
corresponds to the name which matches the query name, or
the first owner name in the answer section.
TC TrunCation - specifies that this message was truncated
due to length greater than that permitted on the
transmission channel.
RD Recursion Desired - this bit may be set in a query and
is copied into the response. If RD is set, it directs
the name server to pursue the query recursively.
Recursive query support is optional.
RA Recursion Available - this be is set or cleared in a
response, and denotes whether recursive query support is
available in the name server.
Z Reserved for future use. Must be zero in all queries
and responses.
RCODE Response code - this 4 bit field is set as part of
responses. The values have the following
interpretation:
0 No error condition
1 Format error - The name server was
unable to interpret the query.
2 Server failure - The name server was
unable to process this query due to a
problem with the name server.
3 Name Error - Meaningful only for
responses from an authoritative name
server, this code signifies that the
domain name referenced in the query does
not exist.
4 Not Implemented - The name server does
not support the requested kind of query.
5 Refused - The name server refuses to
perform the specified operation for
policy reasons. For example, a name
server may not wish to provide the
information to the particular requester,
or a name server may not wish to perform
a particular operation (e.g., zone
transfer) for particular data.
6-15 Reserved for future use.
QDCOUNT an unsigned 16 bit integer specifying the number of
entries in the question section.
ANCOUNT an unsigned 16 bit integer specifying the number of
resource records in the answer section.
NSCOUNT an unsigned 16 bit integer specifying the number of name
server resource records in the authority records
section.
ARCOUNT an unsigned 16 bit integer specifying the number of
resource records in the additional records section.
</pre>
*/
struct ldns_struct_hdr
{
/** Id of a packet */
uint16_t _id;
/** Query bit (0=query, 1=answer) */
bool _qr;
/** Authoritative answer */
bool _aa;
/** Packet truncated */
bool _tc;
/** Recursion desired */
bool _rd;
/** Checking disabled */
bool _cd;
/** Recursion available */
bool _ra;
/** Authentic data */
bool _ad;
/** Query type */
ldns_pkt_opcode _opcode; /* XXX 8 bits? */
/** Response code */
uint8_t _rcode;
/** question sec */
uint16_t _qdcount;
/** answer sec */
uint16_t _ancount;
/** auth sec */
uint16_t _nscount;
/** add sec */
uint16_t _arcount;
};
typedef struct ldns_struct_hdr ldns_hdr;
/**
* DNS packet
*
* This structure contains a complete DNS packet (either a query or an answer)
*
* It is the complete representation of what you actually send to a
* nameserver, and what it sends back (assuming you are the client here).
*/
struct ldns_struct_pkt
{
/** Header section */
ldns_hdr *_header;
/* extra items needed in a packet */
/** The size of the wire format of the packet in octets */
ldns_rdf *_answerfrom;
/** Timestamp of the time the packet was sent or created */
struct timeval timestamp;
/** The duration of the query this packet is an answer to */
uint32_t _querytime;
/** The size of the wire format of the packet in octets */
size_t _size;
/** Optional tsig rr */
ldns_rr *_tsig_rr;
/** EDNS0 available buffer size, see RFC2671 */
uint16_t _edns_udp_size;
/** EDNS0 Extended rcode */
uint8_t _edns_extended_rcode;
/** EDNS Version */
uint8_t _edns_version;
/** Reserved EDNS data bits */
uint16_t _edns_z;
/** Arbitrary EDNS rdata */
ldns_rdf *_edns_data;
/** Question section */
ldns_rr_list *_question;
/** Answer section */
ldns_rr_list *_answer;
/** Authority section */
ldns_rr_list *_authority;
/** Additional section */
ldns_rr_list *_additional;
};
typedef struct ldns_struct_pkt ldns_pkt;
/**
* The sections of a packet
*/
enum ldns_enum_pkt_section {
LDNS_SECTION_QUESTION = 0,
LDNS_SECTION_ANSWER = 1,
LDNS_SECTION_AUTHORITY = 2,
LDNS_SECTION_ADDITIONAL = 3,
/** bogus section, if not interested */
LDNS_SECTION_ANY = 4,
/** used to get all non-question rrs from a packet */
LDNS_SECTION_ANY_NOQUESTION = 5
};
typedef enum ldns_enum_pkt_section ldns_pkt_section;
/**
* The different types of packets
*/
enum ldns_enum_pkt_type {
LDNS_PACKET_QUESTION,
LDNS_PACKET_REFERRAL,
LDNS_PACKET_ANSWER,
LDNS_PACKET_NXDOMAIN,
LDNS_PACKET_NODATA,
LDNS_PACKET_UNKNOWN
};
typedef enum ldns_enum_pkt_type ldns_pkt_type;
/* prototypes */
/* read */
/**
* Read the packet id
* \param[in] p the packet
* \return the packet id
*/
uint16_t ldns_pkt_id(const ldns_pkt *p);
/**
* Read the packet's qr bit
* \param[in] p the packet
* \return value of the bit
*/
bool ldns_pkt_qr(const ldns_pkt *p);
/**
* Read the packet's aa bit
* \param[in] p the packet
* \return value of the bit
*/
bool ldns_pkt_aa(const ldns_pkt *p);
/**
* Read the packet's tc bit
* \param[in] p the packet
* \return value of the bit
*/
bool ldns_pkt_tc(const ldns_pkt *p);
/**
* Read the packet's rd bit
* \param[in] p the packet
* \return value of the bit
*/
bool ldns_pkt_rd(const ldns_pkt *p);
/**
* Read the packet's cd bit
* \param[in] p the packet
* \return value of the bit
*/
bool ldns_pkt_cd(const ldns_pkt *p);
/**
* Read the packet's ra bit
* \param[in] p the packet
* \return value of the bit
*/
bool ldns_pkt_ra(const ldns_pkt *p);
/**
* Read the packet's ad bit
* \param[in] p the packet
* \return value of the bit
*/
bool ldns_pkt_ad(const ldns_pkt *p);
/**
* Read the packet's code
* \param[in] p the packet
* \return the opcode
*/
ldns_pkt_opcode ldns_pkt_get_opcode(const ldns_pkt *p);
/**
* Return the packet's respons code
* \param[in] p the packet
* \return the respons code
*/
ldns_pkt_rcode ldns_pkt_get_rcode(const ldns_pkt *p);
/**
* Return the packet's qd count
* \param[in] p the packet
* \return the qd count
*/
uint16_t ldns_pkt_qdcount(const ldns_pkt *p);
/**
* Return the packet's an count
* \param[in] p the packet
* \return the an count
*/
uint16_t ldns_pkt_ancount(const ldns_pkt *p);
/**
* Return the packet's ns count
* \param[in] p the packet
* \return the ns count
*/
uint16_t ldns_pkt_nscount(const ldns_pkt *p);
/**
* Return the packet's ar count
* \param[in] p the packet
* \return the ar count
*/
uint16_t ldns_pkt_arcount(const ldns_pkt *p);
/**
* Return the packet's answerfrom
* \param[in] p packet
* \return the name of the server
*/
ldns_rdf *ldns_pkt_answerfrom(const ldns_pkt *p);
/**
* Return the packet's timestamp
* \param[in] p the packet
* \return the timestamp
*/
struct timeval ldns_pkt_timestamp(const ldns_pkt *p);
/**
* Return the packet's querytime
* \param[in] p the packet
* \return the querytime
*/
uint32_t ldns_pkt_querytime(const ldns_pkt *p);
/**
* Return the packet's size in bytes
* \param[in] p the packet
* \return the size
*/
size_t ldns_pkt_size(const ldns_pkt *p);
/**
* Return the packet's tsig pseudo rr's
* \param[in] p the packet
* \return the tsig rr
*/
ldns_rr *ldns_pkt_tsig(const ldns_pkt *p);
/**
* Return the packet's question section
* \param[in] p the packet
* \return the section
*/
ldns_rr_list *ldns_pkt_question(const ldns_pkt *p);
/**
* Return the packet's answer section
* \param[in] p the packet
* \return the section
*/
ldns_rr_list *ldns_pkt_answer(const ldns_pkt *p);
/**
* Return the packet's authority section
* \param[in] p the packet
* \return the section
*/
ldns_rr_list *ldns_pkt_authority(const ldns_pkt *p);
/**
* Return the packet's additional section
* \param[in] p the packet
* \return the section
*/
ldns_rr_list *ldns_pkt_additional(const ldns_pkt *p);
/**
* Return the packet's question, answer, authority and additional sections
* concatenated, in a new rr_list clone.
* \param[in] p the packet
* \return the rrs
*/
ldns_rr_list *ldns_pkt_all(const ldns_pkt *p);
/**
* Return the packet's answer, authority and additional sections concatenated,
* in a new rr_list clone. Like ldns_pkt_all but without the questions.
* \param[in] p the packet
* \return the rrs except the question rrs
*/
ldns_rr_list *ldns_pkt_all_noquestion(const ldns_pkt *p);
/**
* return all the rr_list's in the packet. Clone the lists, instead
* of returning pointers.
* \param[in] p the packet to look in
* \param[in] s what section(s) to return
* \return ldns_rr_list with the rr's or NULL if none were found
*/
ldns_rr_list *ldns_pkt_get_section_clone(const ldns_pkt *p, ldns_pkt_section s);
/**
* return all the rr with a specific name from a packet. Optionally
* specify from which section in the packet
* \param[in] p the packet
* \param[in] r the name
* \param[in] s the packet's section
* \return a list with the rr's or NULL if none were found
*/
ldns_rr_list *ldns_pkt_rr_list_by_name(ldns_pkt *p, ldns_rdf *r, ldns_pkt_section s);
/**
* return all the rr with a specific type from a packet. Optionally
* specify from which section in the packet
* \param[in] p the packet
* \param[in] t the type
* \param[in] s the packet's section
* \return a list with the rr's or NULL if none were found
*/
ldns_rr_list *ldns_pkt_rr_list_by_type(const ldns_pkt *p, ldns_rr_type t, ldns_pkt_section s);
/**
* return all the rr with a specific type and type from a packet. Optionally
* specify from which section in the packet
* \param[in] packet the packet
* \param[in] ownername the name
* \param[in] type the type
* \param[in] sec the packet's section
* \return a list with the rr's or NULL if none were found
*/
ldns_rr_list *ldns_pkt_rr_list_by_name_and_type(const ldns_pkt *packet, const ldns_rdf *ownername, ldns_rr_type type, ldns_pkt_section sec);
/**
* check to see if an rr exist in the packet
* \param[in] pkt the packet to examine
* \param[in] sec in which section to look
* \param[in] rr the rr to look for
*/
bool ldns_pkt_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr);
/**
* sets the flags in a packet.
* \param[in] pkt the packet to operate on
* \param[in] flags ORed values: LDNS_QR| LDNS_AR for instance
* \return true on success otherwise false
*/
bool ldns_pkt_set_flags(ldns_pkt *pkt, uint16_t flags);
/**
* Set the packet's id
* \param[in] p the packet
* \param[in] id the id to set
*/
void ldns_pkt_set_id(ldns_pkt *p, uint16_t id);
/**
* Set the packet's id to a random value
* \param[in] p the packet
*/
void ldns_pkt_set_random_id(ldns_pkt *p);
/**
* Set the packet's qr bit
* \param[in] p the packet
* \param[in] b the value to set (boolean)
*/
void ldns_pkt_set_qr(ldns_pkt *p, bool b);
/**
* Set the packet's aa bit
* \param[in] p the packet
* \param[in] b the value to set (boolean)
*/
void ldns_pkt_set_aa(ldns_pkt *p, bool b);
/**
* Set the packet's tc bit
* \param[in] p the packet
* \param[in] b the value to set (boolean)
*/
void ldns_pkt_set_tc(ldns_pkt *p, bool b);
/**
* Set the packet's rd bit
* \param[in] p the packet
* \param[in] b the value to set (boolean)
*/
void ldns_pkt_set_rd(ldns_pkt *p, bool b);
/**
* Set the packet's cd bit
* \param[in] p the packet
* \param[in] b the value to set (boolean)
*/
void ldns_pkt_set_cd(ldns_pkt *p, bool b);
/**
* Set the packet's ra bit
* \param[in] p the packet
* \param[in] b the value to set (boolean)
*/
void ldns_pkt_set_ra(ldns_pkt *p, bool b);
/**
* Set the packet's ad bit
* \param[in] p the packet
* \param[in] b the value to set (boolean)
*/
void ldns_pkt_set_ad(ldns_pkt *p, bool b);
/**
* Set the packet's opcode
* \param[in] p the packet
* \param[in] c the opcode
*/
void ldns_pkt_set_opcode(ldns_pkt *p, ldns_pkt_opcode c);
/**
* Set the packet's respons code
* \param[in] p the packet
* \param[in] c the rcode
*/
void ldns_pkt_set_rcode(ldns_pkt *p, uint8_t c);
/**
* Set the packet's qd count
* \param[in] p the packet
* \param[in] c the count
*/
void ldns_pkt_set_qdcount(ldns_pkt *p, uint16_t c);
/**
* Set the packet's an count
* \param[in] p the packet
* \param[in] c the count
*/
void ldns_pkt_set_ancount(ldns_pkt *p, uint16_t c);
/**
* Set the packet's ns count
* \param[in] p the packet
* \param[in] c the count
*/
void ldns_pkt_set_nscount(ldns_pkt *p, uint16_t c);
/**
* Set the packet's arcount
* \param[in] p the packet
* \param[in] c the count
*/
void ldns_pkt_set_arcount(ldns_pkt *p, uint16_t c);
/**
* Set the packet's answering server
* \param[in] p the packet
* \param[in] r the address
*/
void ldns_pkt_set_answerfrom(ldns_pkt *p, ldns_rdf *r);
/**
* Set the packet's query time
* \param[in] p the packet
* \param[in] t the querytime in msec
*/
void ldns_pkt_set_querytime(ldns_pkt *p, uint32_t t);
/**
* Set the packet's size
* \param[in] p the packet
* \param[in] s the size
*/
void ldns_pkt_set_size(ldns_pkt *p, size_t s);
/**
* Set the packet's timestamp
* \param[in] p the packet
* \param[in] timeval the timestamp
*/
void ldns_pkt_set_timestamp(ldns_pkt *p, struct timeval timeval);
/**
* Set a packet's section count to x
* \param[in] p the packet
* \param[in] s the section
* \param[in] x the section count
*/
void ldns_pkt_set_section_count(ldns_pkt *p, ldns_pkt_section s, uint16_t x);
/**
* Set the packet's tsig rr
* \param[in] p the packet
* \param[in] t the tsig rr
*/
void ldns_pkt_set_tsig(ldns_pkt *p, ldns_rr *t);
/**
* looks inside the packet to determine
* what kind of packet it is, AUTH, NXDOMAIN, REFERRAL, etc.
* \param[in] p the packet to examine
* \return the type of packet
*/
ldns_pkt_type ldns_pkt_reply_type(ldns_pkt *p);
/**
* return the packet's edns udp size
* \param[in] packet the packet
* \return the size
*/
uint16_t ldns_pkt_edns_udp_size(const ldns_pkt *packet);
/**
* return the packet's edns extended rcode
* \param[in] packet the packet
* \return the rcode
*/
uint8_t ldns_pkt_edns_extended_rcode(const ldns_pkt *packet);
/**
* return the packet's edns version
* \param[in] packet the packet
* \return the version
*/
uint8_t ldns_pkt_edns_version(const ldns_pkt *packet);
/**
* return the packet's edns z value
* \param[in] packet the packet
* \return the z value
*/
uint16_t ldns_pkt_edns_z(const ldns_pkt *packet);
/**
* return the packet's edns data
* \param[in] packet the packet
* \return the data
*/
ldns_rdf *ldns_pkt_edns_data(const ldns_pkt *packet);
/**
* return the packet's edns do bit
* \param[in] packet the packet
* \return the bit's value
*/
bool ldns_pkt_edns_do(const ldns_pkt *packet);
/**
* Set the packet's edns do bit
* \param[in] packet the packet
* \param[in] value the bit's new value
*/
void ldns_pkt_set_edns_do(ldns_pkt *packet, bool value);
/**
* returns true if this packet needs and EDNS rr to be sent.
* At the moment the only reason is an expected packet
* size larger than 512 bytes, but for instance dnssec would
* be a good reason too.
*
* \param[in] packet the packet to check
* \return true if packet needs edns rr
*/
bool ldns_pkt_edns(const ldns_pkt *packet);
/**
* Set the packet's edns udp size
* \param[in] packet the packet
* \param[in] s the size
*/
void ldns_pkt_set_edns_udp_size(ldns_pkt *packet, uint16_t s);
/**
* Set the packet's edns extended rcode
* \param[in] packet the packet
* \param[in] c the code
*/
void ldns_pkt_set_edns_extended_rcode(ldns_pkt *packet, uint8_t c);
/**
* Set the packet's edns version
* \param[in] packet the packet
* \param[in] v the version
*/
void ldns_pkt_set_edns_version(ldns_pkt *packet, uint8_t v);
/**
* Set the packet's edns z value
* \param[in] packet the packet
* \param[in] z the value
*/
void ldns_pkt_set_edns_z(ldns_pkt *packet, uint16_t z);
/**
* Set the packet's edns data
* \param[in] packet the packet
* \param[in] data the data
*/
void ldns_pkt_set_edns_data(ldns_pkt *packet, ldns_rdf *data);
/**
* allocates and initializes a ldns_pkt structure.
* \return pointer to the new packet
*/
ldns_pkt *ldns_pkt_new(void);
/**
* frees the packet structure and all data that it contains.
* \param[in] packet The packet structure to free
* \return void
*/
void ldns_pkt_free(ldns_pkt *packet);
/**
* creates a query packet for the given name, type, class.
* \param[out] p the packet to be returned
* \param[in] rr_name the name to query for (as string)
* \param[in] rr_type the type to query for
* \param[in] rr_class the class to query for
* \param[in] flags packet flags
* \return LDNS_STATUS_OK or a ldns_status mesg with the error
*/
ldns_status ldns_pkt_query_new_frm_str(ldns_pkt **p, const char *rr_name, ldns_rr_type rr_type, ldns_rr_class rr_class , uint16_t flags);
/**
* creates a packet with a query in it for the given name, type and class.
* \param[in] rr_name the name to query for
* \param[in] rr_type the type to query for
* \param[in] rr_class the class to query for
* \param[in] flags packet flags
* \return ldns_pkt* a pointer to the new pkt
*/
ldns_pkt *ldns_pkt_query_new(ldns_rdf *rr_name, ldns_rr_type rr_type, ldns_rr_class rr_class, uint16_t flags);
/**
* clones the given packet, creating a fully allocated copy
*
* \param[in] pkt the packet to clone
* \return ldns_pkt* pointer to the new packet
*/
ldns_pkt *ldns_pkt_clone(ldns_pkt *pkt);
/**
* directly set the additional section
* \param[in] p packet to operate on
* \param[in] rr rrlist to set
*/
void ldns_pkt_set_additional(ldns_pkt *p, ldns_rr_list *rr);
/**
* directly set the answer section
* \param[in] p packet to operate on
* \param[in] rr rrlist to set
*/
void ldns_pkt_set_answer(ldns_pkt *p, ldns_rr_list *rr);
/**
* directly set the question section
* \param[in] p packet to operate on
* \param[in] rr rrlist to set
*/
void ldns_pkt_set_question(ldns_pkt *p, ldns_rr_list *rr);
/**
* directly set the auhority section
* \param[in] p packet to operate on
* \param[in] rr rrlist to set
*/
void ldns_pkt_set_authority(ldns_pkt *p, ldns_rr_list *rr);
/**
* push an rr on a packet
* \param[in] packet packet to operate on
* \param[in] section where to put it
* \param[in] rr rr to push
* \return a boolean which is true when the rr was added
*/
bool ldns_pkt_push_rr(ldns_pkt *packet, ldns_pkt_section section, ldns_rr *rr);
/**
* push an rr on a packet, provided the RR is not there.
* \param[in] pkt packet to operate on
* \param[in] sec where to put it
* \param[in] rr rr to push
* \return a boolean which is true when the rr was added
*/
bool ldns_pkt_safe_push_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr);
/**
* push a rr_list on a packet
* \param[in] packet packet to operate on
* \param[in] section where to put it
* \param[in] list the rr_list to push
* \return a boolean which is true when the rr was added
*/
bool ldns_pkt_push_rr_list(ldns_pkt *packet, ldns_pkt_section section, ldns_rr_list *list);
/**
* push an rr_list to a packet, provided the RRs are not already there.
* \param[in] pkt packet to operate on
* \param[in] sec where to put it
* \param[in] list the rr_list to push
* \return a boolean which is true when the rr was added
*/
bool ldns_pkt_safe_push_rr_list(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr_list *list);
/**
* check if a packet is empty
* \param[in] p packet
* \return true: empty, false: not empty
*/
bool ldns_pkt_empty(ldns_pkt *p);
#ifdef __cplusplus
}
#endif
#endif /* LDNS_PACKET_H */

167
contrib/ldns/ldns/parse.h Normal file
View file

@ -0,0 +1,167 @@
/*
* parse.h
*
* a Net::DNS like library for C
* LibDNS Team @ NLnet Labs
* (c) NLnet Labs, 2005-2006
* See the file LICENSE for the license
*/
#ifndef LDNS_PARSE_H
#define LDNS_PARSE_H
#include <ldns/common.h>
#include <ldns/buffer.h>
#ifdef __cplusplus
extern "C" {
#endif
#define LDNS_PARSE_SKIP_SPACE "\f\n\r\v"
#define LDNS_PARSE_NORMAL " \f\n\r\t\v"
#define LDNS_PARSE_NO_NL " \t"
#define LDNS_MAX_LINELEN 10230
#define LDNS_MAX_KEYWORDLEN 32
/**
* \file
*
* Contains some low-level parsing functions, mostly used in the _frm_str
* family of functions.
*/
/**
* different type of directives in zone files
* We now deal with $TTL, $ORIGIN and $INCLUDE.
* The latter is not implemented in ldns (yet)
*/
enum ldns_enum_directive
{
LDNS_DIR_TTL,
LDNS_DIR_ORIGIN,
LDNS_DIR_INCLUDE
};
typedef enum ldns_enum_directive ldns_directive;
/**
* returns a token/char from the stream F.
* This function deals with ( and ) in the stream,
* and ignores them when encountered
* \param[in] *f the file to read from
* \param[out] *token the read token is put here
* \param[in] *delim chars at which the parsing should stop
* \param[in] *limit how much to read. If 0 the builtin maximum is used
* \return 0 on error of EOF of the stream F. Otherwise return the length of what is read
*/
ssize_t ldns_fget_token(FILE *f, char *token, const char *delim, size_t limit);
/**
* returns a token/char from the stream F.
* This function deals with ( and ) in the stream,
* and ignores when it finds them.
* \param[in] *f the file to read from
* \param[out] *token the token is put here
* \param[in] *delim chars at which the parsing should stop
* \param[in] *limit how much to read. If 0 use builtin maximum
* \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
* \return 0 on error of EOF of F otherwise return the length of what is read
*/
ssize_t ldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *line_nr);
/**
* returns a token/char from the buffer b.
* This function deals with ( and ) in the buffer,
* and ignores when it finds them.
* \param[in] *b the buffer to read from
* \param[out] *token the token is put here
* \param[in] *delim chars at which the parsing should stop
* \param[in] *limit how much to read. If 0 the builtin maximum is used
* \returns 0 on error of EOF of b. Otherwise return the length of what is read
*/
ssize_t ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit);
/*
* searches for keyword and delim in a file. Gives everything back
* after the keyword + k_del until we hit d_del
* \param[in] f file pointer to read from
* \param[in] keyword keyword to look for
* \param[in] k_del keyword delimeter
* \param[out] data the data found
* \param[in] d_del the data delimeter
* \param[in] data_limit maximum size the the data buffer
* \return the number of character read
*/
ssize_t ldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del, char *data, const char *d_del, size_t data_limit);
/*
* searches for keyword and delim. Gives everything back
* after the keyword + k_del until we hit d_del
* \param[in] f file pointer to read from
* \param[in] keyword keyword to look for
* \param[in] k_del keyword delimeter
* \param[out] data the data found
* \param[in] d_del the data delimeter
* \param[in] data_limit maximum size the the data buffer
* \param[in] line_nr pointer to an integer containing the current line number (for
debugging purposes)
* \return the number of character read
*/
ssize_t ldns_fget_keyword_data_l(FILE *f, const char *keyword, const char *k_del, char *data, const char *d_del, size_t data_limit, int *line_nr);
/*
* searches for keyword and delim in a buffer. Gives everything back
* after the keyword + k_del until we hit d_del
* \param[in] b buffer pointer to read from
* \param[in] keyword keyword to look for
* \param[in] k_del keyword delimeter
* \param[out] data the data found
* \param[in] d_del the data delimeter
* \param[in] data_limit maximum size the the data buffer
* \return the number of character read
*/
ssize_t ldns_bget_keyword_data(ldns_buffer *b, const char *keyword, const char *k_del, char *data, const char *d_del, size_t data_limit);
/**
* returns the next character from a buffer. Advances the position pointer with 1.
* When end of buffer is reached returns EOF. This is the buffer's equivalent
* for getc().
* \param[in] *buffer buffer to read from
* \return EOF on failure otherwise return the character
*/
int ldns_bgetc(ldns_buffer *buffer);
/**
* skips all of the characters in the given string in the buffer, moving
* the position to the first character that is not in *s.
* \param[in] *buffer buffer to use
* \param[in] *s characters to skip
* \return void
*/
void ldns_bskipcs(ldns_buffer *buffer, const char *s);
/**
* skips all of the characters in the given string in the fp, moving
* the position to the first character that is not in *s.
* \param[in] *fp file to use
* \param[in] *s characters to skip
* \return void
*/
void ldns_fskipcs(FILE *fp, const char *s);
/**
* skips all of the characters in the given string in the fp, moving
* the position to the first character that is not in *s.
* \param[in] *fp file to use
* \param[in] *s characters to skip
* \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
* \return void
*/
void ldns_fskipcs_l(FILE *fp, const char *s, int *line_nr);
#ifdef __cplusplus
}
#endif
#endif /* LDNS_PARSE_H */

230
contrib/ldns/ldns/rbtree.h Normal file
View file

@ -0,0 +1,230 @@
/*
* rbtree.h -- generic red-black tree
*
* Copyright (c) 2001-2008, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* 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 NLNET LABS 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 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.
*
*/
/**
* \file
* Red black tree. Implementation taken from NSD 3.0.5, adjusted for use
* in unbound (memory allocation, logging and so on).
*/
#ifndef LDNS_RBTREE_H_
#define LDNS_RBTREE_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* This structure must be the first member of the data structure in
* the rbtree. This allows easy casting between an rbnode_t and the
* user data (poor man's inheritance).
* Or you can use the data pointer member to get to your data item.
*/
typedef struct ldns_rbnode_t ldns_rbnode_t;
/**
* The rbnode_t struct definition.
*/
struct ldns_rbnode_t {
/** parent in rbtree, RBTREE_NULL for root */
ldns_rbnode_t *parent;
/** left node (smaller items) */
ldns_rbnode_t *left;
/** right node (larger items) */
ldns_rbnode_t *right;
/** pointer to sorting key */
const void *key;
/** pointer to data */
const void *data;
/** colour of this node */
uint8_t color;
};
/** The nullpointer, points to empty node */
#define LDNS_RBTREE_NULL &ldns_rbtree_null_node
/** the global empty node */
extern ldns_rbnode_t ldns_rbtree_null_node;
/** An entire red black tree */
typedef struct ldns_rbtree_t ldns_rbtree_t;
/** definition for tree struct */
struct ldns_rbtree_t {
/** The root of the red-black tree */
ldns_rbnode_t *root;
/** The number of the nodes in the tree */
size_t count;
/**
* Key compare function. <0,0,>0 like strcmp.
* Return 0 on two NULL ptrs.
*/
int (*cmp) (const void *, const void *);
};
/**
* Create new tree (malloced) with given key compare function.
* @param cmpf: compare function (like strcmp) takes pointers to two keys.
* @return: new tree, empty.
*/
ldns_rbtree_t *ldns_rbtree_create(int (*cmpf)(const void *, const void *));
/**
* Free the complete tree (but not its keys)
* @param rbtree The tree to free
*/
void ldns_rbtree_free(ldns_rbtree_t *rbtree);
/**
* Init a new tree (malloced by caller) with given key compare function.
* @param rbtree: uninitialised memory for new tree, returned empty.
* @param cmpf: compare function (like strcmp) takes pointers to two keys.
*/
void ldns_rbtree_init(ldns_rbtree_t *rbtree, int (*cmpf)(const void *, const void *));
/**
* Insert data into the tree.
* @param rbtree: tree to insert to.
* @param data: element to insert.
* @return: data ptr or NULL if key already present.
*/
ldns_rbnode_t *ldns_rbtree_insert(ldns_rbtree_t *rbtree, ldns_rbnode_t *data);
/**
* Insert data into the tree (reversed arguments, for use as callback)
* \param[in] data element to insert
* \param[out] rbtree tree to insert in to
* \return data ptr or NULL if key is already present
*/
void ldns_rbtree_insert_vref(ldns_rbnode_t *data, void *rbtree);
/**
* Delete element from tree.
* @param rbtree: tree to delete from.
* @param key: key of item to delete.
* @return: node that is now unlinked from the tree. User to delete it.
* returns 0 if node not present
*/
ldns_rbnode_t *ldns_rbtree_delete(ldns_rbtree_t *rbtree, const void *key);
/**
* Find key in tree. Returns NULL if not found.
* @param rbtree: tree to find in.
* @param key: key that must match.
* @return: node that fits or NULL.
*/
ldns_rbnode_t *ldns_rbtree_search(ldns_rbtree_t *rbtree, const void *key);
/**
* Find, but match does not have to be exact.
* @param rbtree: tree to find in.
* @param key: key to find position of.
* @param result: set to the exact node if present, otherwise to element that
* precedes the position of key in the tree. NULL if no smaller element.
* @return: true if exact match in result. Else result points to <= element,
* or NULL if key is smaller than the smallest key.
*/
int ldns_rbtree_find_less_equal(ldns_rbtree_t *rbtree, const void *key,
ldns_rbnode_t **result);
/**
* Returns first (smallest) node in the tree
* @param rbtree: tree
* @return: smallest element or NULL if tree empty.
*/
ldns_rbnode_t *ldns_rbtree_first(ldns_rbtree_t *rbtree);
/**
* Returns last (largest) node in the tree
* @param rbtree: tree
* @return: largest element or NULL if tree empty.
*/
ldns_rbnode_t *ldns_rbtree_last(ldns_rbtree_t *rbtree);
/**
* Returns next larger node in the tree
* @param rbtree: tree
* @return: next larger element or NULL if no larger in tree.
*/
ldns_rbnode_t *ldns_rbtree_next(ldns_rbnode_t *rbtree);
/**
* Returns previous smaller node in the tree
* @param rbtree: tree
* @return: previous smaller element or NULL if no previous in tree.
*/
ldns_rbnode_t *ldns_rbtree_previous(ldns_rbnode_t *rbtree);
/**
* split off 'elements' number of elements from the start
* of the name tree and return a new tree containing those
* elements
*/
ldns_rbtree_t *ldns_rbtree_split(ldns_rbtree_t *tree, size_t elements);
/**
* add all node from the second tree to the first (removing them from the
* second), and fix up nsec(3)s if present
*/
void ldns_rbtree_join(ldns_rbtree_t *tree1, ldns_rbtree_t *tree2);
/**
* Call with node=variable of struct* with rbnode_t as first element.
* with type is the type of a pointer to that struct.
*/
#define LDNS_RBTREE_FOR(node, type, rbtree) \
for(node=(type)ldns_rbtree_first(rbtree); \
(ldns_rbnode_t*)node != LDNS_RBTREE_NULL; \
node = (type)ldns_rbtree_next((ldns_rbnode_t*)node))
/**
* Call function for all elements in the redblack tree, such that
* leaf elements are called before parent elements. So that all
* elements can be safely free()d.
* Note that your function must not remove the nodes from the tree.
* Since that may trigger rebalances of the rbtree.
* @param tree: the tree
* @param func: function called with element and user arg.
* The function must not alter the rbtree.
* @param arg: user argument.
*/
void ldns_traverse_postorder(ldns_rbtree_t* tree,
void (*func)(ldns_rbnode_t*, void*), void* arg);
#ifdef __cplusplus
}
#endif
#endif /* UTIL_RBTREE_H_ */

385
contrib/ldns/ldns/rdata.h Normal file
View file

@ -0,0 +1,385 @@
/*
* rdata.h
*
* rdata definitions
*
* a Net::DNS like library for C
*
* (c) NLnet Labs, 2005-2006
*
* See the file LICENSE for the license
*/
/**
* \file
*
* Defines ldns_rdf and functions to manipulate those.
*/
#ifndef LDNS_RDATA_H
#define LDNS_RDATA_H
#include <ldns/common.h>
#include <ldns/error.h>
#ifdef __cplusplus
extern "C" {
#endif
#define LDNS_MAX_RDFLEN 8192
#define LDNS_RDF_SIZE_BYTE 1
#define LDNS_RDF_SIZE_WORD 2
#define LDNS_RDF_SIZE_DOUBLEWORD 4
#define LDNS_RDF_SIZE_6BYTES 6
#define LDNS_RDF_SIZE_16BYTES 16
#define LDNS_NSEC3_VARS_OPTOUT_MASK 0x01
/**
* The different types of RDATA fields.
*/
enum ldns_enum_rdf_type
{
/** none */
LDNS_RDF_TYPE_NONE,
/** domain name */
LDNS_RDF_TYPE_DNAME,
/** 8 bits */
LDNS_RDF_TYPE_INT8,
/** 16 bits */
LDNS_RDF_TYPE_INT16,
/** 32 bits */
LDNS_RDF_TYPE_INT32,
/** A record */
LDNS_RDF_TYPE_A,
/** AAAA record */
LDNS_RDF_TYPE_AAAA,
/** txt string */
LDNS_RDF_TYPE_STR,
/** apl data */
LDNS_RDF_TYPE_APL,
/** b32 string */
LDNS_RDF_TYPE_B32_EXT,
/** b64 string */
LDNS_RDF_TYPE_B64,
/** hex string */
LDNS_RDF_TYPE_HEX,
/** nsec type codes */
LDNS_RDF_TYPE_NSEC,
/** a RR type */
LDNS_RDF_TYPE_TYPE,
/** a class */
LDNS_RDF_TYPE_CLASS,
/** certificate algorithm */
LDNS_RDF_TYPE_CERT_ALG,
/** a key algorithm */
LDNS_RDF_TYPE_ALG,
/** unknown types */
LDNS_RDF_TYPE_UNKNOWN,
/** time (32 bits) */
LDNS_RDF_TYPE_TIME,
/** period */
LDNS_RDF_TYPE_PERIOD,
/** tsig time 48 bits */
LDNS_RDF_TYPE_TSIGTIME,
LDNS_RDF_TYPE_TSIG,
/** variable length any type rdata where the length
is specified by the first 2 bytes */
LDNS_RDF_TYPE_INT16_DATA,
/** protocol and port bitmaps */
LDNS_RDF_TYPE_SERVICE,
/** location data */
LDNS_RDF_TYPE_LOC,
/** well known services */
LDNS_RDF_TYPE_WKS,
/** NSAP */
LDNS_RDF_TYPE_NSAP,
/** ATMA */
LDNS_RDF_TYPE_ATMA,
/** IPSECKEY */
LDNS_RDF_TYPE_IPSECKEY,
/** nsec3 hash salt */
LDNS_RDF_TYPE_NSEC3_SALT,
/** nsec3 base32 string (with length byte on wire */
LDNS_RDF_TYPE_NSEC3_NEXT_OWNER
};
typedef enum ldns_enum_rdf_type ldns_rdf_type;
/**
* algorithms used in CERT rrs
*/
enum ldns_enum_cert_algorithm
{
LDNS_CERT_PKIX = 1,
LDNS_CERT_SPKI = 2,
LDNS_CERT_PGP = 3,
LDNS_CERT_IPKIX = 4,
LDNS_CERT_ISPKI = 5,
LDNS_CERT_IPGP = 6,
LDNS_CERT_ACPKIX = 7,
LDNS_CERT_IACPKIX = 8,
LDNS_CERT_URI = 253,
LDNS_CERT_OID = 254
};
typedef enum ldns_enum_cert_algorithm ldns_cert_algorithm;
/**
* Resource record data field.
*
* The data is a network ordered array of bytes, which size is specified by
* the (16-bit) size field. To correctly parse it, use the type
* specified in the (16-bit) type field with a value from \ref ldns_rdf_type.
*/
struct ldns_struct_rdf
{
/** The size of the data (in octets) */
size_t _size;
/** The type of the data */
ldns_rdf_type _type;
/** Pointer to the data (raw octets) */
void *_data;
};
typedef struct ldns_struct_rdf ldns_rdf;
/* prototypes */
/* write access functions */
/**
* sets the size of the rdf.
* \param[in] *rd the rdf to operate on
* \param[in] size the new size
* \return void
*/
void ldns_rdf_set_size(ldns_rdf *rd, size_t size);
/**
* sets the size of the rdf.
* \param[in] *rd the rdf to operate on
* \param[in] type the new type
* \return void
*/
void ldns_rdf_set_type(ldns_rdf *rd, ldns_rdf_type type);
/**
* sets the size of the rdf.
* \param[in] *rd the rdf to operate on
* \param[in] *data pointer to the new data
* \return void
*/
void ldns_rdf_set_data(ldns_rdf *rd, void *data);
/* read access */
/**
* returns the size of the rdf.
* \param[in] *rd the rdf to read from
* \return uint16_t with the size
*/
size_t ldns_rdf_size(const ldns_rdf *rd);
/**
* returns the type of the rdf. We need to insert _get_
* here to prevent conflict the the rdf_type TYPE.
* \param[in] *rd the rdf to read from
* \return ldns_rdf_type with the type
*/
ldns_rdf_type ldns_rdf_get_type(const ldns_rdf *rd);
/**
* returns the data of the rdf.
* \param[in] *rd the rdf to read from
* \return uint8_t* pointer to the rdf's data
*/
uint8_t *ldns_rdf_data(const ldns_rdf *rd);
/* creator functions */
/**
* allocates a new rdf structure and fills it.
* This function DOES NOT copy the contents from
* the buffer, unlinke ldns_rdf_new_frm_data()
* \param[in] type type of the rdf
* \param[in] size size of the buffer
* \param[in] data pointer to the buffer to be copied
* \return the new rdf structure or NULL on failure
*/
ldns_rdf *ldns_rdf_new(ldns_rdf_type type, size_t size, void *data);
/**
* allocates a new rdf structure and fills it.
* This function _does_ copy the contents from
* the buffer, unlinke ldns_rdf_new()
* \param[in] type type of the rdf
* \param[in] size size of the buffer
* \param[in] data pointer to the buffer to be copied
* \return the new rdf structure or NULL on failure
*/
ldns_rdf *ldns_rdf_new_frm_data(ldns_rdf_type type, size_t size, const void *data);
/**
* creates a new rdf from a string.
* \param[in] type type to use
* \param[in] str string to use
* \return ldns_rdf* or NULL in case of an error
*/
ldns_rdf *ldns_rdf_new_frm_str(ldns_rdf_type type, const char *str);
/**
* creates a new rdf from a file containing a string.
* \param[out] r the new rdf
* \param[in] type type to use
* \param[in] fp the file pointer to use
* \return LDNS_STATUS_OK or the error
*/
ldns_status ldns_rdf_new_frm_fp(ldns_rdf **r, ldns_rdf_type type, FILE *fp);
/**
* creates a new rdf from a file containing a string.
* \param[out] r the new rdf
* \param[in] type type to use
* \param[in] fp the file pointer to use
* \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
* \return LDNS_STATUS_OK or the error
*/
ldns_status ldns_rdf_new_frm_fp_l(ldns_rdf **r, ldns_rdf_type type, FILE *fp, int *line_nr);
/* destroy functions */
/**
* frees a rdf structure, leaving the
* data pointer intact.
* \param[in] rd the pointer to be freed
* \return void
*/
void ldns_rdf_free(ldns_rdf *rd);
/**
* frees a rdf structure _and_ frees the
* data. rdf should be created with _new_frm_data
* \param[in] rd the rdf structure to be freed
* \return void
*/
void ldns_rdf_deep_free(ldns_rdf *rd);
/* conversion functions */
/**
* returns the rdf containing the native uint8_t repr.
* \param[in] type the ldns_rdf type to use
* \param[in] value the uint8_t to use
* \return ldns_rdf* with the converted value
*/
ldns_rdf *ldns_native2rdf_int8(ldns_rdf_type type, uint8_t value);
/**
* returns the rdf containing the native uint16_t representation.
* \param[in] type the ldns_rdf type to use
* \param[in] value the uint16_t to use
* \return ldns_rdf* with the converted value
*/
ldns_rdf *ldns_native2rdf_int16(ldns_rdf_type type, uint16_t value);
/**
* returns an rdf that contains the given int32 value.
*
* Because multiple rdf types can contain an int32, the
* type must be specified
* \param[in] type the ldns_rdf type to use
* \param[in] value the uint32_t to use
* \return ldns_rdf* with the converted value
*/
ldns_rdf *ldns_native2rdf_int32(ldns_rdf_type type, uint32_t value);
/**
* returns an int16_data rdf that contains the data in the
* given array, preceded by an int16 specifying the length.
*
* The memory is copied, and an LDNS_RDF_TYPE_INT16DATA is returned
* \param[in] size the size of the data
* \param[in] *data pointer to the actual data
* \return ldns_rd* the rdf with the data
*/
ldns_rdf *ldns_native2rdf_int16_data(size_t size, uint8_t *data);
/**
* reverses an rdf, only actually useful for AAAA and A records.
* The returned rdf has the type LDNS_RDF_TYPE_DNAME!
* \param[in] *rd rdf to be reversed
* \return the reversed rdf (a newly created rdf)
*/
ldns_rdf *ldns_rdf_address_reverse(ldns_rdf *rd);
/**
* returns the native uint8_t representation from the rdf.
* \param[in] rd the ldns_rdf to operate on
* \return uint8_t the value extracted
*/
uint8_t ldns_rdf2native_int8(const ldns_rdf *rd);
/**
* returns the native uint16_t representation from the rdf.
* \param[in] rd the ldns_rdf to operate on
* \return uint16_t the value extracted
*/
uint16_t ldns_rdf2native_int16(const ldns_rdf *rd);
/**
* returns the native uint32_t representation from the rdf.
* \param[in] rd the ldns_rdf to operate on
* \return uint32_t the value extracted
*/
uint32_t ldns_rdf2native_int32(const ldns_rdf *rd);
/**
* returns the native time_t representation from the rdf.
* \param[in] rd the ldns_rdf to operate on
* \return time_t the value extracted (32 bits currently)
*/
time_t ldns_rdf2native_time_t(const ldns_rdf *rd);
/**
* converts a ttl value (like 5d2h) to a long.
* \param[in] nptr the start of the string
* \param[out] endptr points to the last char in case of error
* \return the convert duration value
*/
uint32_t ldns_str2period(const char *nptr, const char **endptr);
/**
* removes \\DDD, \\[space] and other escapes from the input.
* See RFC 1035, section 5.1.
* \param[in] word what to check
* \param[in] length the string
* \return ldns_status mesg
*/
ldns_status ldns_octet(char *word, size_t *length);
/**
* clones a rdf structure. The data is copied.
* \param[in] rd rdf to be copied
* \return a new rdf structure
*/
ldns_rdf *ldns_rdf_clone(const ldns_rdf *rd);
/**
* compares two rdf's on their wire formats.
* (To order dnames according to rfc4034, use ldns_dname_compare)
* \param[in] rd1 the first one
* \param[in] rd2 the second one
* \return 0 if equal
* \return -1 if rd1 comes before rd2
* \return +1 if rd2 comes before rd1
*/
int ldns_rdf_compare(const ldns_rdf *rd1, const ldns_rdf *rd2);
#ifdef __cplusplus
}
#endif
#endif /* LDNS_RDATA_H */

View file

@ -0,0 +1,721 @@
/*
* resolver.h
*
* DNS Resolver definitions
*
* a Net::DNS like library for C
*
* (c) NLnet Labs, 2005-2006
*
* See the file LICENSE for the license
*/
/**
* \file
*
* Defines the ldns_resolver structure, a stub resolver that can send queries and parse answers.
*
*/
#ifndef LDNS_RESOLVER_H
#define LDNS_RESOLVER_H
#include <ldns/error.h>
#include <ldns/common.h>
#include <ldns/rr.h>
#include <ldns/tsig.h>
#include <ldns/rdata.h>
#include <ldns/packet.h>
#include <sys/time.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Default location of the resolv.conf file */
#define LDNS_RESOLV_CONF "/etc/resolv.conf"
/** Default location of the hosts file */
#define LDNS_RESOLV_HOSTS "/etc/hosts"
#define LDNS_RESOLV_KEYWORD -1
#define LDNS_RESOLV_DEFDOMAIN 0
#define LDNS_RESOLV_NAMESERVER 1
#define LDNS_RESOLV_SEARCH 2
#define LDNS_RESOLV_SORTLIST 3
#define LDNS_RESOLV_OPTIONS 4
#define LDNS_RESOLV_ANCHOR 5
#define LDNS_RESOLV_KEYWORDS 6
#define LDNS_RESOLV_INETANY 0
#define LDNS_RESOLV_INET 1
#define LDNS_RESOLV_INET6 2
#define LDNS_RESOLV_RTT_INF 0 /* infinity */
#define LDNS_RESOLV_RTT_MIN 1 /* reachable */
/**
* DNS stub resolver structure
*/
struct ldns_struct_resolver
{
/** Port to send queries to */
uint16_t _port;
/** Array of nameservers to query (IP addresses or dnames) */
ldns_rdf **_nameservers;
/** Number of nameservers in \c _nameservers */
size_t _nameserver_count; /* how many do we have */
/** Round trip time; 0 -> infinity. Unit: ms? */
size_t *_rtt;
/** Wether or not to be recursive */
bool _recursive;
/** Print debug information */
bool _debug;
/** Default domain to add to non fully qualified domain names */
ldns_rdf *_domain;
/** Searchlist array, add the names in this array if a query cannot be found */
ldns_rdf **_searchlist;
/** Number of entries in the searchlist array */
size_t _searchlist_count;
/** Number of times to retry before giving up */
uint8_t _retry;
/** Time to wait before retrying */
uint8_t _retrans;
/** Use new fallback mechanism (try EDNS, then do TCP) */
bool _fallback;
/** Whether to do DNSSEC */
bool _dnssec;
/** Whether to set the CD bit on DNSSEC requests */
bool _dnssec_cd;
/** Optional trust anchors for complete DNSSEC validation */
ldns_rr_list * _dnssec_anchors;
/** Whether to use tcp or udp (tcp if the value is true)*/
bool _usevc;
/** Whether to ignore the tc bit */
bool _igntc;
/** Whether to use ip6, 0->does not matter, 1 is IPv4, 2 is IPv6 */
uint8_t _ip6;
/** If true append the default domain */
bool _defnames;
/** If true apply the search list */
bool _dnsrch;
/** Timeout for socket connections */
struct timeval _timeout;
/** Only try the first nameserver, and return with an error directly if it fails */
bool _fail;
/** Randomly choose a nameserver */
bool _random;
/** Keep some things to make AXFR possible */
int _socket;
/** Count the number of LDNS_RR_TYPE_SOA RRs we have seen so far
* (the second one signifies the end of the AXFR)
*/
int _axfr_soa_count;
/* when axfring we get complete packets from the server
but we want to give the caller 1 rr at a time, so
keep the current pkt */
/** Packet currently handled when doing part of an AXFR */
ldns_pkt *_cur_axfr_pkt;
/** Counter for within the AXFR packets */
uint16_t _axfr_i;
/* EDNS0 available buffer size */
uint16_t _edns_udp_size;
/* Optional tsig key for signing queries,
outgoing messages are signed if and only if both are set
*/
/** Name of the key to use with TSIG, if _tsig_keyname and _tsig_keydata both contain values, outgoing messages are automatically signed with TSIG. */
char *_tsig_keyname;
/** Secret key data to use with TSIG, if _tsig_keyname and _tsig_keydata both contain values, outgoing messages are automatically signed with TSIG. */
char *_tsig_keydata;
/** TSIG signing algorithm */
char *_tsig_algorithm;
};
typedef struct ldns_struct_resolver ldns_resolver;
/* prototypes */
/* read access functions */
/**
* Get the port the resolver should use
* \param[in] r the resolver
* \return the port number
*/
uint16_t ldns_resolver_port(const ldns_resolver *r);
/**
* Is the resolver set to recurse
* \param[in] r the resolver
* \return true if so, otherwise false
*/
bool ldns_resolver_recursive(const ldns_resolver *r);
/**
* Get the debug status of the resolver
* \param[in] r the resolver
* \return true if so, otherwise false
*/
bool ldns_resolver_debug(const ldns_resolver *r);
/**
* Get the number of retries
* \param[in] r the resolver
* \return the number of retries
*/
uint8_t ldns_resolver_retry(const ldns_resolver *r);
/**
* Get the retransmit interval
* \param[in] r the resolver
* \return the retransmit interval
*/
uint8_t ldns_resolver_retrans(const ldns_resolver *r);
/**
* Get the truncation fallback status
* \param[in] r the resolver
* \return whether the truncation fallback mechanism is used
*/
bool ldns_resolver_fallback(const ldns_resolver *r);
/**
* Does the resolver use ip6 or ip4
* \param[in] r the resolver
* \return 0: both, 1: ip4, 2:ip6
*/
uint8_t ldns_resolver_ip6(const ldns_resolver *r);
/**
* Get the resolver's udp size
* \param[in] r the resolver
* \return the udp mesg size
*/
uint16_t ldns_resolver_edns_udp_size(const ldns_resolver *r);
/**
* Does the resolver use tcp or udp
* \param[in] r the resolver
* \return true: tcp, false: udp
*/
bool ldns_resolver_usevc(const ldns_resolver *r);
/**
* Does the resolver only try the first nameserver
* \param[in] r the resolver
* \return true: yes, fail, false: no, try the others
*/
bool ldns_resolver_fail(const ldns_resolver *r);
/**
* Does the resolver apply default domain name
* \param[in] r the resolver
* \return true: yes, false: no
*/
bool ldns_resolver_defnames(const ldns_resolver *r);
/**
* Does the resolver apply search list
* \param[in] r the resolver
* \return true: yes, false: no
*/
bool ldns_resolver_dnsrch(const ldns_resolver *r);
/**
* Does the resolver do DNSSEC
* \param[in] r the resolver
* \return true: yes, false: no
*/
bool ldns_resolver_dnssec(const ldns_resolver *r);
/**
* Does the resolver set the CD bit
* \param[in] r the resolver
* \return true: yes, false: no
*/
bool ldns_resolver_dnssec_cd(const ldns_resolver *r);
/**
* Get the resolver's DNSSEC anchors
* \param[in] r the resolver
* \return an rr_list containg trusted DNSSEC anchors
*/
ldns_rr_list * ldns_resolver_dnssec_anchors(const ldns_resolver *r);
/**
* Does the resolver ignore the TC bit (truncated)
* \param[in] r the resolver
* \return true: yes, false: no
*/
bool ldns_resolver_igntc(const ldns_resolver *r);
/**
* Does the resolver randomize the nameserver before usage
* \param[in] r the resolver
* \return true: yes, false: no
*/
bool ldns_resolver_random(const ldns_resolver *r);
/**
* How many nameserver are configured in the resolver
* \param[in] r the resolver
* \return number of nameservers
*/
size_t ldns_resolver_nameserver_count(const ldns_resolver *r);
/**
* What is the default dname to add to relative queries
* \param[in] r the resolver
* \return the dname which is added
*/
ldns_rdf *ldns_resolver_domain(const ldns_resolver *r);
/**
* What is the timeout on socket connections
* \param[in] r the resolver
* \return the timeout as struct timeval
*/
struct timeval ldns_resolver_timeout(const ldns_resolver *r);
/**
* What is the searchlist as used by the resolver
* \param[in] r the resolver
* \return a ldns_rdf pointer to a list of the addresses
*/
ldns_rdf** ldns_resolver_searchlist(const ldns_resolver *r);
/**
* Return the configured nameserver ip address
* \param[in] r the resolver
* \return a ldns_rdf pointer to a list of the addresses
*/
ldns_rdf** ldns_resolver_nameservers(const ldns_resolver *r);
/**
* Return the used round trip times for the nameservers
* \param[in] r the resolver
* \return a size_t* pointer to the list.
* yet)
*/
size_t * ldns_resolver_rtt(const ldns_resolver *r);
/**
* Return the used round trip time for a specific nameserver
* \param[in] r the resolver
* \param[in] pos the index to the nameserver
* \return the rrt, 0: infinite, >0: undefined (as of * yet)
*/
size_t ldns_resolver_nameserver_rtt(const ldns_resolver *r, size_t pos);
/**
* Return the tsig keyname as used by the nameserver
* \param[in] r the resolver
* \return the name used.
*/
char *ldns_resolver_tsig_keyname(const ldns_resolver *r);
/**
* Return the tsig algorithm as used by the nameserver
* \param[in] r the resolver
* \return the algorithm used.
*/
char *ldns_resolver_tsig_algorithm(const ldns_resolver *r);
/**
* Return the tsig keydata as used by the nameserver
* \param[in] r the resolver
* \return the keydata used.
*/
char *ldns_resolver_tsig_keydata(const ldns_resolver *r);
/**
* pop the last nameserver from the resolver.
* \param[in] r the resolver
* \return the popped address or NULL if empty
*/
ldns_rdf* ldns_resolver_pop_nameserver(ldns_resolver *r);
/**
* Return the resolver's searchlist count
* \param[in] r the resolver
* \return the searchlist count
*/
size_t ldns_resolver_searchlist_count(const ldns_resolver *r);
/* write access function */
/**
* Set the port the resolver should use
* \param[in] r the resolver
* \param[in] p the port number
*/
void ldns_resolver_set_port(ldns_resolver *r, uint16_t p);
/**
* Set the resolver recursion
* \param[in] r the resolver
* \param[in] b true: set to recurse, false: unset
*/
void ldns_resolver_set_recursive(ldns_resolver *r, bool b);
/**
* Set the resolver debugging
* \param[in] r the resolver
* \param[in] b true: debug on: false debug off
*/
void ldns_resolver_set_debug(ldns_resolver *r, bool b);
/**
* Incremental the resolver's nameserver count.
* \param[in] r the resolver
*/
void ldns_resolver_incr_nameserver_count(ldns_resolver *r);
/**
* Decrement the resolver's nameserver count.
* \param[in] r the resolver
*/
void ldns_resolver_dec_nameserver_count(ldns_resolver *r);
/**
* Set the resolver's nameserver count directly.
* \param[in] r the resolver
* \param[in] c the nameserver count
*/
void ldns_resolver_set_nameserver_count(ldns_resolver *r, size_t c);
/**
* Set the resolver's nameserver count directly by using an rdf list
* \param[in] r the resolver
* \param[in] rd the resolver addresses
*/
void ldns_resolver_set_nameservers(ldns_resolver *r, ldns_rdf **rd);
/**
* Set the resolver's default domain. This gets appended when no
* absolute name is given
* \param[in] r the resolver
* \param[in] rd the name to append
*/
void ldns_resolver_set_domain(ldns_resolver *r, ldns_rdf *rd);
/**
* Set the resolver's socket time out when talking to remote hosts
* \param[in] r the resolver
* \param[in] timeout the timeout to use
*/
void ldns_resolver_set_timeout(ldns_resolver *r, struct timeval timeout);
/**
* Push a new rd to the resolver's searchlist
* \param[in] r the resolver
* \param[in] rd to push
*/
void ldns_resolver_push_searchlist(ldns_resolver *r, ldns_rdf *rd);
/**
* Whether the resolver uses the name set with _set_domain
* \param[in] r the resolver
* \param[in] b true: use the defaults, false: don't use them
*/
void ldns_resolver_set_defnames(ldns_resolver *r, bool b);
/**
* Whether the resolver uses a virtual circuit (TCP)
* \param[in] r the resolver
* \param[in] b true: use TCP, false: don't use TCP
*/
void ldns_resolver_set_usevc(ldns_resolver *r, bool b);
/**
* Whether the resolver uses the searchlist
* \param[in] r the resolver
* \param[in] b true: use the list, false: don't use the list
*/
void ldns_resolver_set_dnsrch(ldns_resolver *r, bool b);
/**
* Whether the resolver uses DNSSEC
* \param[in] r the resolver
* \param[in] b true: use DNSSEC, false: don't use DNSSEC
*/
void ldns_resolver_set_dnssec(ldns_resolver *r, bool b);
/**
* Whether the resolver uses the checking disable bit
* \param[in] r the resolver
* \param[in] b true: enable , false: don't use TCP
*/
void ldns_resolver_set_dnssec_cd(ldns_resolver *r, bool b);
/**
* Set the resolver's DNSSEC anchor list directly. RRs should be of type DS or DNSKEY.
* \param[in] r the resolver
* \param[in] l the list of RRs to use as trust anchors
*/
void ldns_resolver_set_dnssec_anchors(ldns_resolver *r, ldns_rr_list * l);
/**
* Push a new trust anchor to the resolver. It must be a DS or DNSKEY rr
* \param[in] r the resolver.
* \param[in] rr the RR to add as a trust anchor.
* \return a status
*/
ldns_status ldns_resolver_push_dnssec_anchor(ldns_resolver *r, ldns_rr *rr);
/**
* Set the resolver retrans timeout (in seconds)
* \param[in] r the resolver
* \param[in] re the retransmission interval in seconds
*/
void ldns_resolver_set_retrans(ldns_resolver *r, uint8_t re);
/**
* Set whether the resolvers truncation fallback mechanism is used
* when ldns_resolver_query() is called.
* \param[in] r the resolver
* \param[in] fallback whether to use the fallback mechanism
*/
void ldns_resolver_set_fallback(ldns_resolver *r, bool fallback);
/**
* Set the resolver retry interval (in seconds)
* \param[in] r the resolver
* \param[in] re the retry interval
*/
void ldns_resolver_set_retry(ldns_resolver *r, uint8_t re);
/**
* Whether the resolver uses ip6
* \param[in] r the resolver
* \param[in] i 0: no pref, 1: ip4, 2: ip6
*/
void ldns_resolver_set_ip6(ldns_resolver *r, uint8_t i);
/**
* Whether or not to fail after one failed query
* \param[in] r the resolver
* \param[in] b true: yes fail, false: continue with next nameserver
*/
void ldns_resolver_set_fail(ldns_resolver *r, bool b);
/**
* Whether or not to ignore the TC bit
* \param[in] r the resolver
* \param[in] b true: yes ignore, false: don't ignore
*/
void ldns_resolver_set_igntc(ldns_resolver *r, bool b);
/**
* Set maximum udp size
* \param[in] r the resolver
* \param[in] s the udp max size
*/
void ldns_resolver_set_edns_udp_size(ldns_resolver *r, uint16_t s);
/**
* Set the tsig key name
* \param[in] r the resolver
* \param[in] tsig_keyname the tsig key name
*/
void ldns_resolver_set_tsig_keyname(ldns_resolver *r, char *tsig_keyname);
/**
* Set the tsig algorithm
* \param[in] r the resolver
* \param[in] tsig_algorithm the tsig algorithm
*/
void ldns_resolver_set_tsig_algorithm(ldns_resolver *r, char *tsig_algorithm);
/**
* Set the tsig key data
* \param[in] r the resolver
* \param[in] tsig_keydata the key data
*/
void ldns_resolver_set_tsig_keydata(ldns_resolver *r, char *tsig_keydata);
/**
* Set round trip time for all nameservers. Note this currently
* differentiates between: unreachable and reachable.
* \param[in] r the resolver
* \param[in] rtt a list with the times
*/
void ldns_resolver_set_rtt(ldns_resolver *r, size_t *rtt);
/**
* Set round trip time for a specific nameserver. Note this
* currently differentiates between: unreachable and reachable.
* \param[in] r the resolver
* \param[in] pos the nameserver position
* \param[in] value the rtt
*/
void ldns_resolver_set_nameserver_rtt(ldns_resolver *r, size_t pos, size_t value);
/**
* Should the nameserver list be randomized before each use
* \param[in] r the resolver
* \param[in] b: true: randomize, false: don't
*/
void ldns_resolver_set_random(ldns_resolver *r, bool b);
/**
* Push a new nameserver to the resolver. It must be an IP
* address v4 or v6.
* \param[in] r the resolver
* \param[in] n the ip address
* \return ldns_status a status
*/
ldns_status ldns_resolver_push_nameserver(ldns_resolver *r, ldns_rdf *n);
/**
* Push a new nameserver to the resolver. It must be an
* A or AAAA RR record type
* \param[in] r the resolver
* \param[in] rr the resource record
* \return ldns_status a status
*/
ldns_status ldns_resolver_push_nameserver_rr(ldns_resolver *r, ldns_rr *rr);
/**
* Push a new nameserver rr_list to the resolver.
* \param[in] r the resolver
* \param[in] rrlist the rr_list to push
* \return ldns_status a status
*/
ldns_status ldns_resolver_push_nameserver_rr_list(ldns_resolver *r, ldns_rr_list *rrlist);
/**
* Send the query for using the resolver and take the search list into account
* The search algorithm is as follows:
* If the name is absolute, try it as-is, otherwise apply the search list
* \param[in] *r operate using this resolver
* \param[in] *rdf query for this name
* \param[in] t query for this type (may be 0, defaults to A)
* \param[in] c query for this class (may be 0, default to IN)
* \param[in] flags the query flags
* \return ldns_pkt* a packet with the reply from the nameserver
*/
ldns_pkt* ldns_resolver_search(const ldns_resolver *r, const ldns_rdf *rdf, ldns_rr_type t, ldns_rr_class c, uint16_t flags);
/**
* Form a query packet from a resolver and name/type/class combo
* \param[out] **q a pointer to a ldns_pkt pointer (initialized by this function)
* \param[in] *r operate using this resolver
* \param[in] *name query for this name
* \param[in] t query for this type (may be 0, defaults to A)
* \param[in] c query for this class (may be 0, default to IN)
* \param[in] f the query flags
* \return ldns_pkt* a packet with the reply from the nameserver
*/
ldns_status ldns_resolver_prepare_query_pkt(ldns_pkt **q, ldns_resolver *r, const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t f);
/**
* Send the query for name as-is
* \param[out] **answer a pointer to a ldns_pkt pointer (initialized by this function)
* \param[in] *r operate using this resolver
* \param[in] *name query for this name
* \param[in] t query for this type (may be 0, defaults to A)
* \param[in] c query for this class (may be 0, default to IN)
* \param[in] flags the query flags
* \return ldns_pkt* a packet with the reply from the nameserver
*/
ldns_status ldns_resolver_send(ldns_pkt **answer, ldns_resolver *r, const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t flags);
/**
* Send the given packet to a nameserver
* \param[out] **answer a pointer to a ldns_pkt pointer (initialized by this function)
* \param[in] *r operate using this resolver
* \param[in] *query_pkt query
*/
ldns_status ldns_resolver_send_pkt(ldns_pkt **answer, ldns_resolver *r, ldns_pkt *query_pkt);
/**
* Send a query to a nameserver
* \param[in] *r operate using this resolver
* \param[in] *name query for this name
* \param[in] *t query for this type (may be 0, defaults to A)
* \param[in] *c query for this class (may be 0, default to IN)
* \param[in] flags the query flags
* \return ldns_pkt* a packet with the reply from the nameserver
* if _defnames is true the default domain will be added
*/
ldns_pkt* ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t flags);
/**
* Create a new resolver structure
* \return ldns_resolver* pointer to new strcture
*/
ldns_resolver* ldns_resolver_new(void);
/**
* Create a resolver structure from a file like /etc/resolv.conf
* \param[out] r the new resolver
* \param[in] fp file pointer to create new resolver from
* if NULL use /etc/resolv.conf
* \return LDNS_STATUS_OK or the error
*/
ldns_status ldns_resolver_new_frm_fp(ldns_resolver **r, FILE *fp);
/**
* Create a resolver structure from a file like /etc/resolv.conf
* \param[out] r the new resolver
* \param[in] fp file pointer to create new resolver from
* if NULL use /etc/resolv.conf
* \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
* \return LDNS_STATUS_OK or the error
*/
ldns_status ldns_resolver_new_frm_fp_l(ldns_resolver **r, FILE *fp, int *line_nr);
/**
* Configure a resolver by means of a resolv.conf file
* The file may be NULL in which case there will be
* looked the RESOLV_CONF (defaults to /etc/resolv.conf
* \param[out] r the new resolver
* \param[in] filename the filename to use
* \return LDNS_STATUS_OK or the error
*/
ldns_status ldns_resolver_new_frm_file(ldns_resolver **r, const char *filename);
/**
* Frees the allocated space for this resolver. Only frees the resolver pionter! You should probably be using _deep_free.
* \param res resolver to free
*/
void ldns_resolver_free(ldns_resolver *res);
/**
* Frees the allocated space for this resolver and all it's data
* \param res resolver to free
*/
void ldns_resolver_deep_free(ldns_resolver *res);
/**
* Get the next stream of RRs in a AXFR
* \param[in] resolver the resolver to use. First ldns_axfr_start() must be
* called
* \return ldns_rr the next RR from the AXFR stream
* After you get this returned RR (not NULL: on error), then check if
* ldns_axfr_complete() is true to see if the zone transfer has completed.
*/
ldns_rr* ldns_axfr_next(ldns_resolver *resolver);
/**
* Returns true if the axfr transfer has completed (i.e. 2 SOA RRs and no errors were encountered
* \param[in] resolver the resolver that is used
* \return bool true if axfr transfer was completed without error
*/
bool ldns_axfr_complete(const ldns_resolver *resolver);
/**
* Returns a pointer to the last ldns_pkt that was sent by the server in the AXFR transfer
* uasable for instance to get the error code on failure
* \param[in] res the resolver that was used in the axfr transfer
* \return ldns_pkt the last packet sent
*/
ldns_pkt *ldns_axfr_last_pkt(const ldns_resolver *res);
/**
* Randomize the nameserver list in the resolver
* \param[in] r the resolver
*/
void ldns_resolver_nameservers_randomize(ldns_resolver *r);
/**
* Returns true if at least one of the provided keys is a trust anchor
* \param[in] r the current resolver
* \param[in] keys the keyset to check
* \param[out] trusted_keys the subset of trusted keys in the 'keys' rrset
* \return true if at least one of the provided keys is a configured trust anchor
*/
bool ldns_resolver_trusted_key(const ldns_resolver *r, ldns_rr_list * keys, ldns_rr_list * trusted_keys);
#ifdef __cplusplus
}
#endif
#endif /* LDNS_RESOLVER_H */

887
contrib/ldns/ldns/rr.h Normal file
View file

@ -0,0 +1,887 @@
/*
* rr.h - resource record definitions
*
* a Net::DNS like library for C
*
* (c) NLnet Labs, 2005-2006
*
* See the file LICENSE for the license
*/
/**
* \file
*
* Contains the definition of ldns_rr and functions to manipulate those.
*/
#ifndef LDNS_RR_H
#define LDNS_RR_H
#include <ldns/common.h>
#include <ldns/rdata.h>
#include <ldns/buffer.h>
#include <ldns/error.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Maximum length of a dname label */
#define LDNS_MAX_LABELLEN 63
/** Maximum length of a complete dname */
#define LDNS_MAX_DOMAINLEN 255
/** Maximum number of pointers in 1 dname */
#define LDNS_MAX_POINTERS 65535
/** The bytes TTL, CLASS and length use up in an rr */
#define LDNS_RR_OVERHEAD 10
/* The first fields are 'common' and can be referenced instantly */
#define LDNS_RDATA_FIELD_DESCRIPTORS_COMMON 52
/**
* The different RR classes.
*/
enum ldns_enum_rr_class
{
/** the Internet */
LDNS_RR_CLASS_IN = 1,
/** Chaos class */
LDNS_RR_CLASS_CH = 3,
/** Hesiod (Dyer 87) */
LDNS_RR_CLASS_HS = 4,
/** None class, dynamic update */
LDNS_RR_CLASS_NONE = 254,
/** Any class */
LDNS_RR_CLASS_ANY = 255,
LDNS_RR_CLASS_FIRST = 0,
LDNS_RR_CLASS_LAST = 65535,
LDNS_RR_CLASS_COUNT = LDNS_RR_CLASS_LAST - LDNS_RR_CLASS_FIRST + 1
};
typedef enum ldns_enum_rr_class ldns_rr_class;
/**
* Used to specify whether compression is allowed.
*/
enum ldns_enum_rr_compress
{
/** compression is allowed */
LDNS_RR_COMPRESS,
LDNS_RR_NO_COMPRESS
};
typedef enum ldns_enum_rr_compress ldns_rr_compress;
/**
* The different RR types.
*/
enum ldns_enum_rr_type
{
/** a host address */
LDNS_RR_TYPE_A = 1,
/** an authoritative name server */
LDNS_RR_TYPE_NS = 2,
/** a mail destination (Obsolete - use MX) */
LDNS_RR_TYPE_MD = 3,
/** a mail forwarder (Obsolete - use MX) */
LDNS_RR_TYPE_MF = 4,
/** the canonical name for an alias */
LDNS_RR_TYPE_CNAME = 5,
/** marks the start of a zone of authority */
LDNS_RR_TYPE_SOA = 6,
/** a mailbox domain name (EXPERIMENTAL) */
LDNS_RR_TYPE_MB = 7,
/** a mail group member (EXPERIMENTAL) */
LDNS_RR_TYPE_MG = 8,
/** a mail rename domain name (EXPERIMENTAL) */
LDNS_RR_TYPE_MR = 9,
/** a null RR (EXPERIMENTAL) */
LDNS_RR_TYPE_NULL = 10,
/** a well known service description */
LDNS_RR_TYPE_WKS = 11,
/** a domain name pointer */
LDNS_RR_TYPE_PTR = 12,
/** host information */
LDNS_RR_TYPE_HINFO = 13,
/** mailbox or mail list information */
LDNS_RR_TYPE_MINFO = 14,
/** mail exchange */
LDNS_RR_TYPE_MX = 15,
/** text strings */
LDNS_RR_TYPE_TXT = 16,
/** RFC1183 */
LDNS_RR_TYPE_RP = 17,
/** RFC1183 */
LDNS_RR_TYPE_AFSDB = 18,
/** RFC1183 */
LDNS_RR_TYPE_X25 = 19,
/** RFC1183 */
LDNS_RR_TYPE_ISDN = 20,
/** RFC1183 */
LDNS_RR_TYPE_RT = 21,
/** RFC1706 */
LDNS_RR_TYPE_NSAP = 22,
/** RFC1348 */
LDNS_RR_TYPE_NSAP_PTR = 23,
/** 2535typecode */
LDNS_RR_TYPE_SIG = 24,
/** 2535typecode */
LDNS_RR_TYPE_KEY = 25,
/** RFC2163 */
LDNS_RR_TYPE_PX = 26,
/** RFC1712 */
LDNS_RR_TYPE_GPOS = 27,
/** ipv6 address */
LDNS_RR_TYPE_AAAA = 28,
/** LOC record RFC1876 */
LDNS_RR_TYPE_LOC = 29,
/** 2535typecode */
LDNS_RR_TYPE_NXT = 30,
/** draft-ietf-nimrod-dns-01.txt */
LDNS_RR_TYPE_EID = 31,
/** draft-ietf-nimrod-dns-01.txt */
LDNS_RR_TYPE_NIMLOC = 32,
/** SRV record RFC2782 */
LDNS_RR_TYPE_SRV = 33,
/** http://www.jhsoft.com/rfc/af-saa-0069.000.rtf */
LDNS_RR_TYPE_ATMA = 34,
/** RFC2915 */
LDNS_RR_TYPE_NAPTR = 35,
/** RFC2230 */
LDNS_RR_TYPE_KX = 36,
/** RFC2538 */
LDNS_RR_TYPE_CERT = 37,
/** RFC2874 */
LDNS_RR_TYPE_A6 = 38,
/** RFC2672 */
LDNS_RR_TYPE_DNAME = 39,
/** dnsind-kitchen-sink-02.txt */
LDNS_RR_TYPE_SINK = 40,
/** Pseudo OPT record... */
LDNS_RR_TYPE_OPT = 41,
/** RFC3123 */
LDNS_RR_TYPE_APL = 42,
/** draft-ietf-dnsext-delegation */
LDNS_RR_TYPE_DS = 43,
/** SSH Key Fingerprint */
LDNS_RR_TYPE_SSHFP = 44, /* RFC 4255 */
/** IPsec Key */
LDNS_RR_TYPE_IPSECKEY = 45, /* RFC 4025 */
/** DNSSEC */
LDNS_RR_TYPE_RRSIG = 46, /* RFC 4034 */
LDNS_RR_TYPE_NSEC = 47, /* RFC 4034 */
LDNS_RR_TYPE_DNSKEY = 48, /* RFC 4034 */
LDNS_RR_TYPE_DHCID = 49, /* RFC 4701 */
/* NSEC3 */
LDNS_RR_TYPE_NSEC3 = 50, /* RFC 5155 */
LDNS_RR_TYPE_NSEC3PARAM = 51, /* RFC 5155 */
LDNS_RR_TYPE_NSEC3PARAMS = 51,
/** draft-ietf-dnsop-trust-history */
LDNS_RR_TYPE_TALINK = 58,
LDNS_RR_TYPE_SPF = 99,
LDNS_RR_TYPE_UINFO = 100,
LDNS_RR_TYPE_UID = 101,
LDNS_RR_TYPE_GID = 102,
LDNS_RR_TYPE_UNSPEC = 103,
LDNS_RR_TYPE_TSIG = 250,
LDNS_RR_TYPE_IXFR = 251,
LDNS_RR_TYPE_AXFR = 252,
/** A request for mailbox-related records (MB, MG or MR) */
LDNS_RR_TYPE_MAILB = 253,
/** A request for mail agent RRs (Obsolete - see MX) */
LDNS_RR_TYPE_MAILA = 254,
/** any type (wildcard) */
LDNS_RR_TYPE_ANY = 255,
/* RFC 4431, 5074, DNSSEC Lookaside Validation */
LDNS_RR_TYPE_DLV = 32769,
/* type codes from nsec3 experimental phase
LDNS_RR_TYPE_NSEC3 = 65324,
LDNS_RR_TYPE_NSEC3PARAMS = 65325, */
LDNS_RR_TYPE_FIRST = 0,
LDNS_RR_TYPE_LAST = 65535,
LDNS_RR_TYPE_COUNT = LDNS_RR_TYPE_LAST - LDNS_RR_TYPE_FIRST + 1
};
typedef enum ldns_enum_rr_type ldns_rr_type;
/**
* Resource Record
*
* This is the basic DNS element that contains actual data
*
* From RFC1035:
* <pre>
3.2.1. Format
All RRs have the same top level format shown below:
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ /
/ NAME /
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TYPE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| CLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TTL |
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| RDLENGTH |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
/ RDATA /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
where:
NAME an owner name, i.e., the name of the node to which this
resource record pertains.
TYPE two octets containing one of the RR TYPE codes.
CLASS two octets containing one of the RR CLASS codes.
TTL a 32 bit signed integer that specifies the time interval
that the resource record may be cached before the source
of the information should again be consulted. Zero
values are interpreted to mean that the RR can only be
used for the transaction in progress, and should not be
cached. For example, SOA records are always distributed
with a zero TTL to prohibit caching. Zero values can
also be used for extremely volatile data.
RDLENGTH an unsigned 16 bit integer that specifies the length in
octets of the RDATA field.
RDATA a variable length string of octets that describes the
resource. The format of this information varies
according to the TYPE and CLASS of the resource record.
* </pre>
*
* The actual amount and type of rdata fields depend on the RR type of the
* RR, and can be found by using \ref ldns_rr_descriptor functions.
*/
struct ldns_struct_rr
{
/** Owner name, uncompressed */
ldns_rdf *_owner;
/** Time to live */
uint32_t _ttl;
/** Number of data fields */
size_t _rd_count;
/** the type of the RR. A, MX etc. */
ldns_rr_type _rr_type;
/** Class of the resource record. */
ldns_rr_class _rr_class;
/* everything in the rdata is in network order */
/** The array of rdata's */
ldns_rdf **_rdata_fields;
/** question rr [it would be nicer if thous is after _rd_count]
ABI change: Fix this in next major release
*/
bool _rr_question;
};
typedef struct ldns_struct_rr ldns_rr;
/**
* List or Set of Resource Records
*
* Contains a list of rr's <br>
* No official RFC-like checks are made
*/
struct ldns_struct_rr_list
{
size_t _rr_count;
size_t _rr_capacity;
ldns_rr **_rrs;
};
typedef struct ldns_struct_rr_list ldns_rr_list;
/**
* Contains all information about resource record types.
*
* This structure contains, for all rr types, the rdata fields that are defined.
*/
struct ldns_struct_rr_descriptor
{
/** Type of the RR that is described here */
ldns_rr_type _type;
/** Textual name of the RR type. */
const char *_name;
/** Minimum number of rdata fields in the RRs of this type. */
uint8_t _minimum;
/** Maximum number of rdata fields in the RRs of this type. */
uint8_t _maximum;
/** Wireformat specification for the rr, i.e. the types of rdata fields in their respective order. */
const ldns_rdf_type *_wireformat;
/** Special rdf types */
ldns_rdf_type _variable;
/** Specifies whether compression can be used for dnames in this RR type. */
ldns_rr_compress _compress;
/** The number of DNAMEs in the _wireformat string, for parsing. */
uint8_t _dname_count;
};
typedef struct ldns_struct_rr_descriptor ldns_rr_descriptor;
/**
* creates a new rr structure.
* \return ldns_rr *
*/
ldns_rr* ldns_rr_new(void);
/**
* creates a new rr structure, based on the given type.
* alloc enough space to hold all the rdf's
*/
ldns_rr* ldns_rr_new_frm_type(ldns_rr_type t);
/**
* frees an RR structure
* \param[in] *rr the RR to be freed
* \return void
*/
void ldns_rr_free(ldns_rr *rr);
/**
* creates an rr from a string.
* The string should be a fully filled-in rr, like
* ownername &lt;space&gt; TTL &lt;space&gt; CLASS &lt;space&gt;
* TYPE &lt;space&gt; RDATA.
* \param[out] n the rr to return
* \param[in] str the string to convert
* \param[in] default_ttl default ttl value for the rr.
* If 0 DEF_TTL will be used
* \param[in] origin when the owner is relative add this.
* The caller must ldns_rdf_deep_free it.
* \param[out] prev the previous ownername. if this value is not NULL,
* the function overwrites this with the ownername found in this
* string. The caller must then ldns_rdf_deep_free it.
* \return a status msg describing an error or LDNS_STATUS_OK
*/
ldns_status ldns_rr_new_frm_str(ldns_rr **n, const char *str,
uint32_t default_ttl, ldns_rdf *origin,
ldns_rdf **prev);
/**
* creates an rr for the question section from a string, i.e.
* without RDATA fields
* Origin and previous RR functionality are the same as in
* ldns_rr_new_frm_str()
* \param[out] n the rr to return
* \param[in] str the string to convert
* \param[in] origin when the owner is relative add this.
* The caller must ldns_rdf_deep_free it.
* \param prev the previous ownername. the function overwrite this with
* the current found ownername. The caller must ldns_rdf_deep_free it.
* \return a status msg describing an error or LDNS_STATUS_OK
*/
ldns_status ldns_rr_new_question_frm_str(ldns_rr **n, const char *str,
ldns_rdf *origin, ldns_rdf **prev);
/**
* creates a new rr from a file containing a string.
* \param[out] rr the new rr
* \param[in] fp the file pointer to use
* \param[in] default_ttl pointer to a default ttl for the rr. If NULL DEF_TTL will be used
* the pointer will be updated if the file contains a $TTL directive
* \param[in] origin when the owner is relative add this
* the pointer will be updated if the file contains a $ORIGIN directive
* The caller must ldns_rdf_deep_free it.
* \param[in] prev when the owner is whitespaces use this as the * ownername
* the pointer will be updated after the call
* The caller must ldns_rdf_deep_free it.
* \return a ldns_status with an error or LDNS_STATUS_OK
*/
ldns_status ldns_rr_new_frm_fp(ldns_rr **rr, FILE *fp, uint32_t *default_ttl, ldns_rdf **origin, ldns_rdf **prev);
/**
* creates a new rr from a file containing a string.
* \param[out] rr the new rr
* \param[in] fp the file pointer to use
* \param[in] default_ttl a default ttl for the rr. If NULL DEF_TTL will be used
* the pointer will be updated if the file contains a $TTL directive
* \param[in] origin when the owner is relative add this
* the pointer will be updated if the file contains a $ORIGIN directive
* The caller must ldns_rdf_deep_free it.
* \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
* \param[in] prev when the owner is whitespaces use this as the * ownername
* the pointer will be updated after the call
* The caller must ldns_rdf_deep_free it.
* \return a ldns_status with an error or LDNS_STATUS_OK
*/
ldns_status ldns_rr_new_frm_fp_l(ldns_rr **rr, FILE *fp, uint32_t *default_ttl, ldns_rdf **origin, ldns_rdf **prev, int *line_nr);
/**
* sets the owner in the rr structure.
* \param[in] *rr rr to operate on
* \param[in] *owner set to this owner
* \return void
*/
void ldns_rr_set_owner(ldns_rr *rr, ldns_rdf *owner);
/**
* sets the question flag in the rr structure.
* \param[in] *rr rr to operate on
* \param[in] question question flag
* \return void
*/
void ldns_rr_set_question(ldns_rr *rr, bool question);
/**
* sets the ttl in the rr structure.
* \param[in] *rr rr to operate on
* \param[in] ttl set to this ttl
* \return void
*/
void ldns_rr_set_ttl(ldns_rr *rr, uint32_t ttl);
/**
* sets the rd_count in the rr.
* \param[in] *rr rr to operate on
* \param[in] count set to this count
* \return void
*/
void ldns_rr_set_rd_count(ldns_rr *rr, size_t count);
/**
* sets the type in the rr.
* \param[in] *rr rr to operate on
* \param[in] rr_type set to this type
* \return void
*/
void ldns_rr_set_type(ldns_rr *rr, ldns_rr_type rr_type);
/**
* sets the class in the rr.
* \param[in] *rr rr to operate on
* \param[in] rr_class set to this class
* \return void
*/
void ldns_rr_set_class(ldns_rr *rr, ldns_rr_class rr_class);
/**
* sets a rdf member, it will be set on the
* position given. The old value is returned, like pop.
* \param[in] *rr the rr to operate on
* \param[in] *f the rdf to set
* \param[in] position the position the set the rdf
* \return the old value in the rr, NULL on failyre
*/
ldns_rdf* ldns_rr_set_rdf(ldns_rr *rr, const ldns_rdf *f, size_t position);
/**
* sets rd_field member, it will be
* placed in the next available spot.
* \param[in] *rr rr to operate on
* \param[in] *f the data field member to set
* \return bool
*/
bool ldns_rr_push_rdf(ldns_rr *rr, const ldns_rdf *f);
/**
* removes a rd_field member, it will be
* popped from the last position.
* \param[in] *rr rr to operate on
* \return rdf which was popped (null if nothing)
*/
ldns_rdf* ldns_rr_pop_rdf(ldns_rr *rr);
/**
* returns the rdata field member counter.
* \param[in] *rr rr to operate on
* \param[in] nr the number of the rdf to return
* \return ldns_rdf *
*/
ldns_rdf* ldns_rr_rdf(const ldns_rr *rr, size_t nr);
/**
* returns the owner name of an rr structure.
* \param[in] *rr rr to operate on
* \return ldns_rdf *
*/
ldns_rdf* ldns_rr_owner(const ldns_rr *rr);
/**
* returns the question flag of an rr structure.
* \param[in] *rr rr to operate on
* \return bool true if question
*/
bool ldns_rr_is_question(const ldns_rr *rr);
/**
* returns the ttl of an rr structure.
* \param[in] *rr the rr to read from
* \return the ttl of the rr
*/
uint32_t ldns_rr_ttl(const ldns_rr *rr);
/**
* returns the rd_count of an rr structure.
* \param[in] *rr the rr to read from
* \return the rd count of the rr
*/
size_t ldns_rr_rd_count(const ldns_rr *rr);
/**
* returns the type of the rr.
* \param[in] *rr the rr to read from
* \return the type of the rr
*/
ldns_rr_type ldns_rr_get_type(const ldns_rr *rr);
/**
* returns the class of the rr.
* \param[in] *rr the rr to read from
* \return the class of the rr
*/
ldns_rr_class ldns_rr_get_class(const ldns_rr *rr);
/* rr_lists */
/**
* returns the number of rr's in an rr_list.
* \param[in] rr_list the rr_list to read from
* \return the number of rr's
*/
size_t ldns_rr_list_rr_count(const ldns_rr_list *rr_list);
/**
* sets the number of rr's in an rr_list.
* \param[in] rr_list the rr_list to set the count on
* \param[in] count the number of rr in this list
* \return void
*/
void ldns_rr_list_set_rr_count(ldns_rr_list *rr_list, size_t count);
/**
* set a rr on a specific index in a ldns_rr_list
* \param[in] rr_list the rr_list to use
* \param[in] r the rr to set
* \param[in] count index into the rr_list
* \return the old rr which was stored in the rr_list, or
* NULL is the index was too large
* set a specific rr */
ldns_rr * ldns_rr_list_set_rr(ldns_rr_list *rr_list, const ldns_rr *r, size_t count);
/**
* returns a specific rr of an rrlist.
* \param[in] rr_list the rr_list to read from
* \param[in] nr return this rr
* \return the rr at position nr
*/
ldns_rr* ldns_rr_list_rr(const ldns_rr_list *rr_list, size_t nr);
/**
* creates a new rr_list structure.
* \return a new rr_list structure
*/
ldns_rr_list* ldns_rr_list_new(void);
/**
* frees an rr_list structure.
* \param[in] rr_list the list to free
*/
void ldns_rr_list_free(ldns_rr_list *rr_list);
/**
* frees an rr_list structure and all rrs contained therein.
* \param[in] rr_list the list to free
*/
void ldns_rr_list_deep_free(ldns_rr_list *rr_list);
/**
* concatenates two ldns_rr_lists together. This modifies
* *left (to extend it and add the pointers from *right).
* \param[in] left the leftside
* \param[in] right the rightside
* \return a left with right concatenated to it
*/
bool ldns_rr_list_cat(ldns_rr_list *left, ldns_rr_list *right);
/**
* concatenates two ldns_rr_lists together, but makes clones of the rr's
* (instead of pointer copying).
* \param[in] left the leftside
* \param[in] right the rightside
* \return a new rr_list with leftside/rightside concatenated
*/
ldns_rr_list* ldns_rr_list_cat_clone(ldns_rr_list *left, ldns_rr_list *right);
/**
* pushes an rr to an rrlist.
* \param[in] rr_list the rr_list to push to
* \param[in] rr the rr to push
* \return false on error, otherwise true
*/
bool ldns_rr_list_push_rr(ldns_rr_list *rr_list, const ldns_rr *rr);
/**
* pushes an rr_list to an rrlist.
* \param[in] rr_list the rr_list to push to
* \param[in] push_list the rr_list to push
* \return false on error, otherwise true
*/
bool ldns_rr_list_push_rr_list(ldns_rr_list *rr_list, const ldns_rr_list *push_list);
/**
* pops the last rr from an rrlist.
* \param[in] rr_list the rr_list to pop from
* \return NULL if nothing to pop. Otherwise the popped RR
*/
ldns_rr* ldns_rr_list_pop_rr(ldns_rr_list *rr_list);
/**
* pops an rr_list of size s from an rrlist.
* \param[in] rr_list the rr_list to pop from
* \param[in] size the number of rr's to pop
* \return NULL if nothing to pop. Otherwise the popped rr_list
*/
ldns_rr_list* ldns_rr_list_pop_rr_list(ldns_rr_list *rr_list, size_t size);
/**
* returns true if the given rr is one of the rrs in the
* list, or if it is equal to one
* \param[in] rr_list the rr_list to check
* \param[in] rr the rr to check
* \return true if rr_list contains rr, false otherwise
*/
bool ldns_rr_list_contains_rr(const ldns_rr_list *rr_list, ldns_rr *rr);
/**
* checks if an rr_list is a rrset.
* \param[in] rr_list the rr_list to check
* \return true if it is an rrset otherwise false
*/
bool ldns_is_rrset(ldns_rr_list *rr_list);
/**
* pushes an rr to an rrset (which really are rr_list's).
* \param[in] *rr_list the rrset to push the rr to
* \param[in] *rr the rr to push
* \return true if the push succeeded otherwise false
*/
bool ldns_rr_set_push_rr(ldns_rr_list *rr_list, ldns_rr *rr);
/**
* pops the last rr from an rrset. This function is there only
* for the symmetry.
* \param[in] rr_list the rr_list to pop from
* \return NULL if nothing to pop. Otherwise the popped RR
*
*/
ldns_rr* ldns_rr_set_pop_rr(ldns_rr_list *rr_list);
/**
* pops the first rrset from the list,
* the list must be sorted, so that all rr's from each rrset
* are next to each other
*/
ldns_rr_list *ldns_rr_list_pop_rrset(ldns_rr_list *rr_list);
/**
* retrieves a rrtype by looking up its name.
* \param[in] name a string with the name
* \return the type which corresponds with the name
*/
ldns_rr_type ldns_get_rr_type_by_name(const char *name);
/**
* retrieves a class by looking up its name.
* \param[in] name string with the name
* \return the cass which corresponds with the name
*/
ldns_rr_class ldns_get_rr_class_by_name(const char *name);
/**
* clones a rr and all its data
* \param[in] rr the rr to clone
* \return the new rr or NULL on failure
*/
ldns_rr* ldns_rr_clone(const ldns_rr *rr);
/**
* clones an rrlist.
* \param[in] rrlist the rrlist to clone
* \return the cloned rr list
*/
ldns_rr_list* ldns_rr_list_clone(const ldns_rr_list *rrlist);
/**
* sorts an rr_list (canonical wire format). the sorting is done inband.
* \param[in] unsorted the rr_list to be sorted
* \return void
*/
void ldns_rr_list_sort(ldns_rr_list *unsorted);
/**
* compares two rrs. The TTL is not looked at.
* \param[in] rr1 the first one
* \param[in] rr2 the second one
* \return 0 if equal
* -1 if rr1 comes before rr2
* +1 if rr2 comes before rr1
*/
int ldns_rr_compare(const ldns_rr *rr1, const ldns_rr *rr2);
/**
* compares two rrs, up to the rdata.
* \param[in] rr1 the first one
* \param[in] rr2 the second one
* \return 0 if equal
* -1 if rr1 comes before rr2
* +1 if rr2 comes before rr1
*/
int ldns_rr_compare_no_rdata(const ldns_rr *rr1, const ldns_rr *rr2);
/**
* compares the wireformat of two rrs, contained in the given buffers.
* \param[in] rr1_buf the first one
* \param[in] rr2_buf the second one
* \return 0 if equal
* -1 if rr1_buf comes before rr2_buf
* +1 if rr2_buf comes before rr1_buf
*/
int ldns_rr_compare_wire(ldns_buffer *rr1_buf, ldns_buffer *rr2_buf);
/**
* returns true of the given rr's are equal.
* Also returns true if one record is a DS that represents the
* same DNSKEY record as the other record
* \param[in] rr1 the first rr
* \param[in] rr2 the second rr
* \return true if equal otherwise false
*/
bool ldns_rr_compare_ds(const ldns_rr *rr1, const ldns_rr *rr2);
/**
* compares two rr listss.
* \param[in] rrl1 the first one
* \param[in] rrl2 the second one
* \return 0 if equal
* -1 if rrl1 comes before rrl2
* +1 if rrl2 comes before rrl1
*/
int ldns_rr_list_compare(const ldns_rr_list *rrl1, const ldns_rr_list *rrl2);
/**
* calculates the uncompressed size of an RR.
* \param[in] r the rr to operate on
* \return size of the rr
*/
size_t ldns_rr_uncompressed_size(const ldns_rr *r);
/**
* converts each dname in a rr to its canonical form.
* \param[in] rr the rr to work on
* \return void
*/
void ldns_rr2canonical(ldns_rr *rr);
/**
* converts each dname in each rr in a rr_list to its canonical form.
* \param[in] rr_list the rr_list to work on
* \return void
*/
void ldns_rr_list2canonical(ldns_rr_list *rr_list);
/**
* counts the number of labels of the ownername.
* \param[in] rr count the labels of this rr
* \return the number of labels
*/
uint8_t ldns_rr_label_count(ldns_rr *rr);
/**
* returns the resource record descriptor for the given rr type.
*
* \param[in] type the type value of the rr type
*\return the ldns_rr_descriptor for this type
*/
const ldns_rr_descriptor *ldns_rr_descript(uint16_t type);
/**
* returns the minimum number of rdata fields of the rr type this descriptor describes.
*
* \param[in] descriptor for an rr type
* \return the minimum number of rdata fields
*/
size_t ldns_rr_descriptor_minimum(const ldns_rr_descriptor *descriptor);
/**
* returns the maximum number of rdata fields of the rr type this descriptor describes.
*
* \param[in] descriptor for an rr type
* \return the maximum number of rdata fields
*/
size_t ldns_rr_descriptor_maximum(const ldns_rr_descriptor *descriptor);
/**
* returns the rdf type for the given rdata field number of the rr type for the given descriptor.
*
* \param[in] descriptor for an rr type
* \param[in] field the field number
* \return the rdf type for the field
*/
ldns_rdf_type ldns_rr_descriptor_field_type(const ldns_rr_descriptor *descriptor, size_t field);
/**
* Return the rr_list which matches the rdf at position field. Think
* type-covered stuff for RRSIG
*
* \param[in] l the rr_list to look in
* \param[in] r the rdf to use for the comparison
* \param[in] pos at which position can we find the rdf
*
* \return a new rr list with only the RRs that match
*
*/
ldns_rr_list *ldns_rr_list_subtype_by_rdf(ldns_rr_list *l, ldns_rdf *r, size_t pos);
/**
* convert an rdf of type LDNS_RDF_TYPE_TYPE to an actual
* LDNS_RR_TYPE. This is usefull in the case when inspecting
* the rrtype covered field of an RRSIG.
* \param[in] rd the rdf to look at
* \return a ldns_rr_type with equivalent LDNS_RR_TYPE
*
*/
ldns_rr_type ldns_rdf2rr_type(const ldns_rdf *rd);
/**
* Returns the type of the first element of the RR
* If there are no elements present, 0 is returned
*
* \param[in] rr_list The rr list
* \return rr_type of the first element, or 0 if the list is empty
*/
ldns_rr_type
ldns_rr_list_type(const ldns_rr_list *rr_list);
/**
* Returns the owner domain name rdf of the first element of the RR
* If there are no elements present, NULL is returned
*
* \param[in] rr_list The rr list
* \return dname of the first element, or NULL if the list is empty
*/
ldns_rdf *
ldns_rr_list_owner(const ldns_rr_list *rr_list);
#ifdef __cplusplus
}
#endif
#endif /* LDNS_RR_H */

View file

@ -0,0 +1,363 @@
/*
* rr_functions.h
*
* the .h file with defs for the per rr
* functions
*
* a Net::DNS like library for C
*
* (c) NLnet Labs, 2005-2006
*
* See the file LICENSE for the license
*/
#ifndef LDNS_RR_FUNCTIONS_H
#define LDNS_RR_FUNCTIONS_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* \file
*
* Defines some extra convenience functions for ldns_rr structures
*/
/* A / AAAA */
/**
* returns the address of a LDNS_RR_TYPE_A rr
* \param[in] r the resource record
* \return a ldns_rdf* with the address or NULL on failure
*/
ldns_rdf* ldns_rr_a_address(const ldns_rr *r);
/**
* sets the address of a LDNS_RR_TYPE_A rr
* \param[in] r the rr to use
* \param[in] f the address to set
* \return true on success, false otherwise
*/
bool ldns_rr_a_set_address(ldns_rr *r, ldns_rdf *f);
/* NS */
/**
* returns the name of a LDNS_RR_TYPE_NS rr
* \param[in] r the resource record
* \return a ldns_rdf* with the name or NULL on failure
*/
ldns_rdf* ldns_rr_ns_nsdname(const ldns_rr *r);
/* MX */
/**
* returns the mx pref. of a LDNS_RR_TYPE_MX rr
* \param[in] r the resource record
* \return a ldns_rdf* with the preference or NULL on failure
*/
ldns_rdf* ldns_rr_mx_preference(const ldns_rr *r);
/**
* returns the mx host of a LDNS_RR_TYPE_MX rr
* \param[in] r the resource record
* \return a ldns_rdf* with the name of the MX host or NULL on failure
*/
ldns_rdf* ldns_rr_mx_exchange(const ldns_rr *r);
/* RRSIG */
/**
* returns the type covered of a LDNS_RR_TYPE_RRSIG rr
* \param[in] r the resource record
* \return a ldns_rdf* with the type covered or NULL on failure
*/
ldns_rdf* ldns_rr_rrsig_typecovered(const ldns_rr *r);
/**
* sets the typecovered of a LDNS_RR_TYPE_RRSIG rr
* \param[in] r the rr to use
* \param[in] f the typecovered to set
* \return true on success, false otherwise
*/
bool ldns_rr_rrsig_set_typecovered(ldns_rr *r, ldns_rdf *f);
/**
* returns the algorithm of a LDNS_RR_TYPE_RRSIG RR
* \param[in] r the resource record
* \return a ldns_rdf* with the algorithm or NULL on failure
*/
ldns_rdf* ldns_rr_rrsig_algorithm(const ldns_rr *r);
/**
* sets the algorithm of a LDNS_RR_TYPE_RRSIG rr
* \param[in] r the rr to use
* \param[in] f the algorithm to set
* \return true on success, false otherwise
*/
bool ldns_rr_rrsig_set_algorithm(ldns_rr *r, ldns_rdf *f);
/**
* returns the number of labels of a LDNS_RR_TYPE_RRSIG RR
* \param[in] r the resource record
* \return a ldns_rdf* with the number of labels or NULL on failure
*/
ldns_rdf *ldns_rr_rrsig_labels(const ldns_rr *r);
/**
* sets the number of labels of a LDNS_RR_TYPE_RRSIG rr
* \param[in] r the rr to use
* \param[in] f the number of labels to set
* \return true on success, false otherwise
*/
bool ldns_rr_rrsig_set_labels(ldns_rr *r, ldns_rdf *f);
/**
* returns the original TTL of a LDNS_RR_TYPE_RRSIG RR
* \param[in] r the resource record
* \return a ldns_rdf* with the original TTL or NULL on failure
*/
ldns_rdf* ldns_rr_rrsig_origttl(const ldns_rr *r);
/**
* sets the original TTL of a LDNS_RR_TYPE_RRSIG rr
* \param[in] r the rr to use
* \param[in] f the original TTL to set
* \return true on success, false otherwise
*/
bool ldns_rr_rrsig_set_origttl(ldns_rr *r, ldns_rdf *f);
/**
* returns the expiration time of a LDNS_RR_TYPE_RRSIG RR
* \param[in] r the resource record
* \return a ldns_rdf* with the expiration time or NULL on failure
*/
ldns_rdf* ldns_rr_rrsig_expiration(const ldns_rr *r);
/**
* sets the expireation date of a LDNS_RR_TYPE_RRSIG rr
* \param[in] r the rr to use
* \param[in] f the expireation date to set
* \return true on success, false otherwise
*/
bool ldns_rr_rrsig_set_expiration(ldns_rr *r, ldns_rdf *f);
/**
* returns the inception time of a LDNS_RR_TYPE_RRSIG RR
* \param[in] r the resource record
* \return a ldns_rdf* with the inception time or NULL on failure
*/
ldns_rdf* ldns_rr_rrsig_inception(const ldns_rr *r);
/**
* sets the inception date of a LDNS_RR_TYPE_RRSIG rr
* \param[in] r the rr to use
* \param[in] f the inception date to set
* \return true on success, false otherwise
*/
bool ldns_rr_rrsig_set_inception(ldns_rr *r, ldns_rdf *f);
/**
* returns the keytag of a LDNS_RR_TYPE_RRSIG RR
* \param[in] r the resource record
* \return a ldns_rdf* with the keytag or NULL on failure
*/
ldns_rdf* ldns_rr_rrsig_keytag(const ldns_rr *r);
/**
* sets the keytag of a LDNS_RR_TYPE_RRSIG rr
* \param[in] r the rr to use
* \param[in] f the keytag to set
* \return true on success, false otherwise
*/
bool ldns_rr_rrsig_set_keytag(ldns_rr *r, ldns_rdf *f);
/**
* returns the signers name of a LDNS_RR_TYPE_RRSIG RR
* \param[in] r the resource record
* \return a ldns_rdf* with the signers name or NULL on failure
*/
ldns_rdf* ldns_rr_rrsig_signame(const ldns_rr *r);
/**
* sets the signers name of a LDNS_RR_TYPE_RRSIG rr
* \param[in] r the rr to use
* \param[in] f the signers name to set
* \return true on success, false otherwise
*/
bool ldns_rr_rrsig_set_signame(ldns_rr *r, ldns_rdf *f);
/**
* returns the signature data of a LDNS_RR_TYPE_RRSIG RR
* \param[in] r the resource record
* \return a ldns_rdf* with the signature data or NULL on failure
*/
ldns_rdf* ldns_rr_rrsig_sig(const ldns_rr *r);
/**
* sets the signature data of a LDNS_RR_TYPE_RRSIG rr
* \param[in] r the rr to use
* \param[in] f the signature data to set
* \return true on success, false otherwise
*/
bool ldns_rr_rrsig_set_sig(ldns_rr *r, ldns_rdf *f);
/* DNSKEY */
/**
* returns the flags of a LDNS_RR_TYPE_DNSKEY rr
* \param[in] r the resource record
* \return a ldns_rdf* with the flags or NULL on failure
*/
ldns_rdf* ldns_rr_dnskey_flags(const ldns_rr *r);
/**
* sets the flags of a LDNS_RR_TYPE_DNSKEY rr
* \param[in] r the rr to use
* \param[in] f the flags to set
* \return true on success, false otherwise
*/
bool ldns_rr_dnskey_set_flags(ldns_rr *r, ldns_rdf *f);
/**
* returns the protocol of a LDNS_RR_TYPE_DNSKEY rr
* \param[in] r the resource record
* \return a ldns_rdf* with the protocol or NULL on failure
*/
ldns_rdf* ldns_rr_dnskey_protocol(const ldns_rr *r);
/**
* sets the protocol of a LDNS_RR_TYPE_DNSKEY rr
* \param[in] r the rr to use
* \param[in] f the protocol to set
* \return true on success, false otherwise
*/
bool ldns_rr_dnskey_set_protocol(ldns_rr *r, ldns_rdf *f);
/**
* returns the algorithm of a LDNS_RR_TYPE_DNSKEY rr
* \param[in] r the resource record
* \return a ldns_rdf* with the algorithm or NULL on failure
*/
ldns_rdf* ldns_rr_dnskey_algorithm(const ldns_rr *r);
/**
* sets the algorithm of a LDNS_RR_TYPE_DNSKEY rr
* \param[in] r the rr to use
* \param[in] f the algorithm to set
* \return true on success, false otherwise
*/
bool ldns_rr_dnskey_set_algorithm(ldns_rr *r, ldns_rdf *f);
/**
* returns the key data of a LDNS_RR_TYPE_DNSKEY rr
* \param[in] r the resource record
* \return a ldns_rdf* with the key data or NULL on failure
*/
ldns_rdf* ldns_rr_dnskey_key(const ldns_rr *r);
/**
* sets the key data of a LDNS_RR_TYPE_DNSKEY rr
* \param[in] r the rr to use
* \param[in] f the key data to set
* \return true on success, false otherwise
*/
bool ldns_rr_dnskey_set_key(ldns_rr *r, ldns_rdf *f);
/**
* get the length of the keydata in bits
* \param[in] keydata the raw key data
* \param[in] len the length of the keydata
* \param[in] alg the cryptographic algorithm this is a key for
* \return the keysize in bits, or 0 on error
*/
size_t ldns_rr_dnskey_key_size_raw(const unsigned char *keydata,
const size_t len,
const ldns_algorithm alg);
/**
* get the length of the keydata in bits
* \param[in] key the key rr to use
* \return the keysize in bits
*/
size_t ldns_rr_dnskey_key_size(const ldns_rr *key);
/**
* The type of function to be passed to ldns_rr_soa_increment_func,
* ldns_rr_soa_increment_func_data or ldns_rr_soa_increment_int.
* The function will be called with as the first argument the current serial
* number of the SOA RR to be updated, and as the second argument a value
* given when calling ldns_rr_soa_increment_func_data or
* ldns_rr_soa_increment_int. With ldns_rr_soa_increment_int the pointer
* value holds the integer value passed to ldns_rr_soa_increment_int,
* and it should be cast to intptr_t to be used as an integer by the
* serial modifying function.
*/
typedef uint32_t (*ldns_soa_serial_increment_func_t)(uint32_t, void*);
/**
* Function to be used with dns_rr_soa_increment_func_int, to set the soa
* serial number.
* \param[in] unused the (unused) current serial number.
* \param[in] data the serial number to be set.
*/
uint32_t ldns_soa_serial_identity(uint32_t unused, void *data);
/**
* Function to be used with dns_rr_soa_increment_func, to increment the soa
* serial number with one.
* \param[in] s the current serial number.
* \param[in] unused unused.
*/
uint32_t ldns_soa_serial_increment(uint32_t s, void *unused);
/**
* Function to be used with dns_rr_soa_increment_func_int, to increment the soa
* serial number with a certain amount.
* \param[in] s the current serial number.
* \param[in] data the amount to add to the current serial number.
*/
uint32_t ldns_soa_serial_increment_by(uint32_t s, void *data);
/**
* Function to be used with ldns_rr_soa_increment_func or
* ldns_rr_soa_increment_func_int to set the soa serial to the number of
* seconds since unix epoch (1-1-1970 00:00).
* When data is given (i.e. the function is called via
* ldns_rr_soa_increment_func_int), it is used as the current time.
* When the resulting serial number is smaller than the current serial number,
* the current serial number is increased by one.
* \param[in] s the current serial number.
* \param[in] data the time in seconds since 1-1-1970 00:00
*/
uint32_t ldns_soa_serial_unixtime(uint32_t s, void *data);
/**
* Function to be used with ldns_rr_soa_increment_func or
* ldns_rr_soa_increment_func_int to set the soa serial to the current date
* succeeded by a two digit iteration (datecounter).
* When data is given (i.e. the function is called via
* ldns_rr_soa_increment_func_int), it is used as the current time.
* When the resulting serial number is smaller than the current serial number,
* the current serial number is increased by one.
* \param[in] s the current serial number.
* \param[in] data the time in seconds since 1-1-1970 00:00
*/
uint32_t ldns_soa_serial_datecounter(uint32_t s, void *data);
/**
* Increment the serial number of the given SOA by one.
* \param[in] soa The soa rr to be incremented
*/
void ldns_rr_soa_increment(
ldns_rr *soa);
/**
* Increment the serial number of the given SOA with the given function.
* Included functions to be used here are: ldns_rr_soa_increment,
* ldns_soa_serial_unixtime and ldns_soa_serial_datecounter.
* \param[in] soa The soa rr to be incremented
* \param[in] f the function to use to increment the soa rr.
*/
void ldns_rr_soa_increment_func(
ldns_rr *soa, ldns_soa_serial_increment_func_t f);
/**
* Increment the serial number of the given SOA with the given function
* passing it the given data argument.
* \param[in] soa The soa rr to be incremented
* \param[in] f the function to use to increment the soa rr.
* \param[in] data this argument will be passed to f as the second argument.
*/
void ldns_rr_soa_increment_func_data(
ldns_rr *soa, ldns_soa_serial_increment_func_t f, void *data);
/**
* Increment the serial number of the given SOA with the given function
* using data as an argument for the function.
* Included functions to be used here are: ldns_soa_serial_identity,
* ldns_rr_soa_increment_by, ldns_soa_serial_unixtime and
* ldns_soa_serial_datecounter.
* \param[in] soa The soa rr to be incremented
* \param[in] f the function to use to increment the soa rr.
* \param[in] data this argument will be passed to f as the second argument
* (by casting it to void*).
*/
void ldns_rr_soa_increment_func_int(
ldns_rr *soa, ldns_soa_serial_increment_func_t f, int data);
#ifdef __cplusplus
}
#endif
#endif /* LDNS_RR_FUNCTIONS_H */

38
contrib/ldns/ldns/sha1.h Normal file
View file

@ -0,0 +1,38 @@
#ifndef LDNS_SHA1_H
#define LDNS_SHA1_H
#ifdef __cplusplus
extern "C" {
#endif
#define LDNS_SHA1_BLOCK_LENGTH 64
#define LDNS_SHA1_DIGEST_LENGTH 20
typedef struct {
uint32_t state[5];
uint64_t count;
unsigned char buffer[LDNS_SHA1_BLOCK_LENGTH];
} ldns_sha1_ctx;
void ldns_sha1_init(ldns_sha1_ctx * context);
void ldns_sha1_transform(uint32_t state[5], const unsigned char buffer[LDNS_SHA1_BLOCK_LENGTH]);
void ldns_sha1_update(ldns_sha1_ctx *context, const unsigned char *data, unsigned int len);
void ldns_sha1_final(unsigned char digest[LDNS_SHA1_DIGEST_LENGTH], ldns_sha1_ctx *context);
/**
* Convenience function to digest a fixed block of data at once.
*
* \param[in] data the data to digest
* \param[in] data_len the length of data in bytes
* \param[out] digest the length of data in bytes
* This pointer MUST have LDNS_SHA1_DIGEST_LENGTH bytes
* available
* \return the SHA1 digest of the given data
*/
unsigned char *ldns_sha1(unsigned char *data, unsigned int data_len, unsigned char *digest);
#ifdef __cplusplus
}
#endif
#endif /* LDNS_SHA1_H */

149
contrib/ldns/ldns/sha2.h Normal file
View file

@ -0,0 +1,149 @@
/*
* FILE: sha2.h
* AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/
*
* Copyright (c) 2000-2001, Aaron D. Gifford
* All rights reserved.
*
* Modified by Jelte Jansen to fit in ldns, and not clash with any
* system-defined SHA code.
* Changes:
* - Renamed (external) functions and constants to fit ldns style
* - Removed uintXX vs. u_intXX smartness, since ldns needs uintXX
* anyway
* - BYTE ORDER check replaced by simple ifdef as defined or not by
* configure.ac
* - Removed _End and _Data functions
* - Added ldns_shaX(data, len, digest) functions
*
* 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 copyright holder nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 AUTHOR OR CONTRIBUTOR(S) 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.
*
* $Id: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $
*/
#ifndef __LDNS_SHA2_H__
#define __LDNS_SHA2_H__
#ifdef __cplusplus
extern "C" {
#endif
/*
* Import u_intXX_t size_t type definitions from system headers. You
* may need to change this, or define these things yourself in this
* file.
*/
#include <sys/types.h>
#if LDNS_BUILD_CONFIG_HAVE_INTTYPES_H
#include <inttypes.h>
#endif /* LDNS_BUILD_CONFIG_HAVE_INTTYPES_H */
/*** SHA-256/384/512 Various Length Definitions ***********************/
#define LDNS_SHA256_BLOCK_LENGTH 64
#define LDNS_SHA256_DIGEST_LENGTH 32
#define LDNS_SHA256_DIGEST_STRING_LENGTH (LDNS_SHA256_DIGEST_LENGTH * 2 + 1)
#define LDNS_SHA384_BLOCK_LENGTH 128
#define LDNS_SHA384_DIGEST_LENGTH 48
#define LDNS_SHA384_DIGEST_STRING_LENGTH (LDNS_SHA384_DIGEST_LENGTH * 2 + 1)
#define LDNS_SHA512_BLOCK_LENGTH 128
#define LDNS_SHA512_DIGEST_LENGTH 64
#define LDNS_SHA512_DIGEST_STRING_LENGTH (LDNS_SHA512_DIGEST_LENGTH * 2 + 1)
/*** SHA-256/384/512 Context Structures *******************************/
typedef struct _ldns_sha256_CTX {
uint32_t state[8];
uint64_t bitcount;
uint8_t buffer[LDNS_SHA256_BLOCK_LENGTH];
} ldns_sha256_CTX;
typedef struct _ldns_sha512_CTX {
uint64_t state[8];
uint64_t bitcount[2];
uint8_t buffer[LDNS_SHA512_BLOCK_LENGTH];
} ldns_sha512_CTX;
typedef ldns_sha512_CTX ldns_sha384_CTX;
/*** SHA-256/384/512 Function Prototypes ******************************/
void ldns_sha256_init(ldns_sha256_CTX *);
void ldns_sha256_update(ldns_sha256_CTX*, const uint8_t*, size_t);
void ldns_sha256_final(uint8_t[LDNS_SHA256_DIGEST_LENGTH], ldns_sha256_CTX*);
void ldns_sha384_init(ldns_sha384_CTX*);
void ldns_sha384_update(ldns_sha384_CTX*, const uint8_t*, size_t);
void ldns_sha384_final(uint8_t[LDNS_SHA384_DIGEST_LENGTH], ldns_sha384_CTX*);
void ldns_sha512_init(ldns_sha512_CTX*);
void ldns_sha512_update(ldns_sha512_CTX*, const uint8_t*, size_t);
void ldns_sha512_final(uint8_t[LDNS_SHA512_DIGEST_LENGTH], ldns_sha512_CTX*);
/**
* Convenience function to digest a fixed block of data at once.
*
* \param[in] data the data to digest
* \param[in] data_len the length of data in bytes
* \param[out] digest the length of data in bytes
* This pointer MUST have LDNS_SHA256_DIGEST_LENGTH bytes
* available
* \return the SHA1 digest of the given data
*/
unsigned char *ldns_sha256(unsigned char *data, unsigned int data_len, unsigned char *digest);
/**
* Convenience function to digest a fixed block of data at once.
*
* \param[in] data the data to digest
* \param[in] data_len the length of data in bytes
* \param[out] digest the length of data in bytes
* This pointer MUST have LDNS_SHA384_DIGEST_LENGTH bytes
* available
* \return the SHA1 digest of the given data
*/
unsigned char *ldns_sha384(unsigned char *data, unsigned int data_len, unsigned char *digest);
/**
* Convenience function to digest a fixed block of data at once.
*
* \param[in] data the data to digest
* \param[in] data_len the length of data in bytes
* \param[out] digest the length of data in bytes
* This pointer MUST have LDNS_SHA512_DIGEST_LENGTH bytes
* available
* \return the SHA1 digest of the given data
*/
unsigned char *ldns_sha512(unsigned char *data, unsigned int data_len, unsigned char *digest);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __LDNS_SHA2_H__ */

View file

@ -0,0 +1,251 @@
/**
* str2host.h - conversion from str to the host fmt
*
* a Net::DNS like library for C
*
* (c) NLnet Labs, 2005-2006
*
* See the file LICENSE for the license
*/
#ifndef LDNS_2HOST_H
#define LDNS_2HOST_H
#include <ldns/common.h>
#include <ldns/error.h>
#include <ldns/rr.h>
#include <ldns/rdata.h>
#include <ldns/packet.h>
#include <ldns/buffer.h>
#include <ctype.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \file
*
* Defines functions to convert dns data in presentation format or text files
* to internal structures.
*/
/**
* convert a byte into wireformat
* \param[in] rd the rdf where to put the data
* \param[in] bytestr the string to be converted
* \return ldns_status
*/
ldns_status ldns_str2rdf_int8(ldns_rdf **rd, const char *bytestr);
/**
* convert a string to a int16 in wireformat
* \param[in] rd the rdf where to put the data
* \param[in] shortstr the string to be converted
* \return ldns_status
*/
ldns_status ldns_str2rdf_int16(ldns_rdf **rd, const char *shortstr);
/**
* convert a strings into a 4 byte int in wireformat
* \param[in] rd the rdf where to put the data
* \param[in] longstr the string to be converted
* \return ldns_status
*/
ldns_status ldns_str2rdf_int32(ldns_rdf **rd, const char *longstr);
/**
* convert a time string to a time value in wireformat
* \param[in] rd the rdf where to put the data
* \param[in] time the string to be converted
* \return ldns_status
*/
ldns_status ldns_str2rdf_time(ldns_rdf **rd, const char *time);
/* convert string with NSEC3 salt to wireformat)
* \param[in] rd the rdf where to put the data
* \param[in] str the string to be converted
* return ldns_status
*/
ldns_status ldns_str2rdf_nsec3_salt(ldns_rdf **rd, const char *nsec3_salt);
/* convert a time period (think TTL's) to wireformat)
* \param[in] rd the rdf where to put the data
* \param[in] str the string to be converted
* return ldns_status
*/
ldns_status ldns_str2rdf_period(ldns_rdf **rd, const char *str);
/**
* convert str with an A record into wireformat
* \param[in] rd the rdf where to put the data
* \param[in] str the string to be converted
* \return ldns_status
*/
ldns_status ldns_str2rdf_a(ldns_rdf **rd, const char *str);
/**
* convert the str with an AAAA record into wireformat
* \param[in] rd the rdf where to put the data
* \param[in] str the string to be converted
* \return ldns_status
*/
ldns_status ldns_str2rdf_aaaa(ldns_rdf **rd, const char *str);
/**
* convert a string into wireformat (think txt record)
* \param[in] rd the rdf where to put the data
* \param[in] str the string to be converted (NULL terminated)
* \return ldns_status
*/
ldns_status ldns_str2rdf_str(ldns_rdf **rd, const char *str);
/**
* convert str with the apl record into wireformat
* \param[in] rd the rdf where to put the data
* \param[in] str the string to be converted
* \return ldns_status
*/
ldns_status ldns_str2rdf_apl(ldns_rdf **rd, const char *str);
/**
* convert the string with the b64 data into wireformat
* \param[in] rd the rdf where to put the data
* \param[in] str the string to be converted
* \return ldns_status
*/
ldns_status ldns_str2rdf_b64(ldns_rdf **rd, const char *str);
/**
* convert the string with the b32 ext hex data into wireformat
* \param[in] rd the rdf where to put the data
* \param[in] str the string to be converted
* \return ldns_status
*/
ldns_status ldns_str2rdf_b32_ext(ldns_rdf **rd, const char *str);
/**
* convert a hex value into wireformat
* \param[in] rd the rdf where to put the data
* \param[in] str the string to be converted
* \return ldns_status
*/
ldns_status ldns_str2rdf_hex(ldns_rdf **rd, const char *str);
/**
* convert string with nsec into wireformat
* \param[in] rd the rdf where to put the data
* \param[in] str the string to be converted
* \return ldns_status
*/
ldns_status ldns_str2rdf_nsec(ldns_rdf **rd, const char *str);
/**
* convert a rrtype into wireformat
* \param[in] rd the rdf where to put the data
* \param[in] str the string to be converted
* \return ldns_status
*/
ldns_status ldns_str2rdf_type(ldns_rdf **rd, const char *str);
/**
* convert string with a classname into wireformat
* \param[in] rd the rdf where to put the data
* \param[in] str the string to be converted
* \return ldns_status
*/
ldns_status ldns_str2rdf_class(ldns_rdf **rd, const char *str);
/**
* convert an certificate algorithm value into wireformat
* \param[in] rd the rdf where to put the data
* \param[in] str the string to be converted
* \return ldns_status
*/
ldns_status ldns_str2rdf_cert_alg(ldns_rdf **rd, const char *str);
/**
* convert and algorithm value into wireformat
* \param[in] rd the rdf where to put the data
* \param[in] str the string to be converted
* \return ldns_status
*/
ldns_status ldns_str2rdf_alg(ldns_rdf **rd, const char *str);
/**
* convert a string with a unknown RR into wireformat
* \param[in] rd the rdf where to put the data
* \param[in] str the string to be converted
* \return ldns_status
*/
ldns_status ldns_str2rdf_unknown(ldns_rdf **rd, const char *str);
/**
* convert string with a tsig? RR into wireformat
* \param[in] rd the rdf where to put the data
* \param[in] str the string to be converted
* \return ldns_status
*/
ldns_status ldns_str2rdf_tsig(ldns_rdf **rd, const char *str);
/**
* convert string with a protocol service into wireformat
* \param[in] rd the rdf where to put the data
* \param[in] str the string to be converted
* \return ldns_status
*/
ldns_status ldns_str2rdf_service(ldns_rdf **rd, const char *str);
/**
* convert a string with a LOC RR into wireformat
* \param[in] rd the rdf where to put the data
* \param[in] str the string to be converted
* \return ldns_status
*/
ldns_status ldns_str2rdf_loc(ldns_rdf **rd, const char *str);
/**
* convert string with a WKS RR into wireformat
* \param[in] rd the rdf where to put the data
* \param[in] str the string to be converted
* \return ldns_status
*/
ldns_status ldns_str2rdf_wks(ldns_rdf **rd, const char *str);
/**
* convert a str with a NSAP RR into wireformat
* \param[in] rd the rdf where to put the data
* \param[in] str the string to be converted
* \return ldns_status
*/
ldns_status ldns_str2rdf_nsap(ldns_rdf **rd, const char *str);
/**
* convert a str with a ATMA RR into wireformat
* \param[in] rd the rdf where to put the data
* \param[in] str the string to be converted
* \return ldns_status
*/
ldns_status ldns_str2rdf_atma(ldns_rdf **rd, const char *str);
/**
* convert a str with a IPSECKEY RR into wireformat
* \param[in] rd the rdf where to put the data
* \param[in] str the string to be converted
* \return ldns_status
*/
ldns_status ldns_str2rdf_ipseckey(ldns_rdf **rd, const char *str);
/**
* convert a dname string into wireformat
* \param[in] rd the rdf where to put the data
* \param[in] str the string to be converted
* \return ldns_status
*/
ldns_status ldns_str2rdf_dname(ldns_rdf **rd, const char *str);
#ifdef __cplusplus
}
#endif
#endif /* LDNS_2HOST_H */

101
contrib/ldns/ldns/tsig.h Normal file
View file

@ -0,0 +1,101 @@
/*
* tsig.h -- defines for TSIG [RFC2845]
*
* Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
*
* See LICENSE for the license.
*/
#ifndef LDNS_TSIG_H
#define LDNS_TSIG_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* \file
*
* Defines functions for TSIG usage
*/
/**
* Contains credentials for TSIG
*/
typedef struct ldns_tsig_credentials_struct
{
char *algorithm;
char *keyname;
char *keydata;
/* XXX More eventually. */
} ldns_tsig_credentials;
char *ldns_tsig_algorithm(ldns_tsig_credentials *);
char *ldns_tsig_keyname(ldns_tsig_credentials *);
char *ldns_tsig_keydata(ldns_tsig_credentials *);
char *ldns_tsig_keyname_clone(ldns_tsig_credentials *);
char *ldns_tsig_keydata_clone(ldns_tsig_credentials *);
/**
* verifies the tsig rr for the given packet and key.
* The wire must be given too because tsig does not sign normalized packets.
* \param[in] pkt the packet to verify
* \param[in] wire needed to verify the mac
* \param[in] wire_size size of wire
* \param[in] key_name the name of the shared key
* \param[in] key_data the key in base 64 format
* \param[in] mac original mac
* \return true if tsig is correct, false if not, or if tsig is not set
*/
bool ldns_pkt_tsig_verify(ldns_pkt *pkt, uint8_t *wire, size_t wire_size, const char *key_name, const char *key_data, ldns_rdf *mac);
/**
* verifies the tsig rr for the given packet and key.
* The wire must be given too because tsig does not sign normalized packets.
* \param[in] pkt the packet to verify
* \param[in] wire needed to verify the mac
* \param[in] wire_size size of wire
* \param[in] key_name the name of the shared key
* \param[in] key_data the key in base 64 format
* \param[in] mac original mac
* \param[in] tsig_timers_only must be zero for the first packet and positive for subsequent packets. If zero, all digest
components are used to verify the _mac. If non-zero, only the TSIG timers are used to verify the mac.
* \return true if tsig is correct, false if not, or if tsig is not set
*/
bool ldns_pkt_tsig_verify_next(ldns_pkt *pkt, uint8_t *wire, size_t wire_size, const char *key_name, const char *key_data, ldns_rdf *mac,
int tsig_timers_only);
/**
* creates a tsig rr for the given packet and key.
* \param[in] pkt the packet to sign
* \param[in] key_name the name of the shared key
* \param[in] key_data the key in base 64 format
* \param[in] fudge seconds of error permitted in time signed
* \param[in] algorithm_name the name of the algorithm used
* \param[in] query_mac is added to the digest if not NULL (so NULL is for signing queries, not NULL is for signing answers)
* \return status (OK if success)
*/
ldns_status ldns_pkt_tsig_sign(ldns_pkt *pkt, const char *key_name, const char *key_data, uint16_t fudge,
const char *algorithm_name, ldns_rdf *query_mac);
/**
* creates a tsig rr for the given packet and key.
* \param[in] pkt the packet to sign
* \param[in] key_name the name of the shared key
* \param[in] key_data the key in base 64 format
* \param[in] fudge seconds of error permitted in time signed
* \param[in] algorithm_name the name of the algorithm used
* \param[in] query_mac is added to the digest if not NULL (so NULL is for signing queries, not NULL is for signing answers)
* \param[in] tsig_timers_only must be zero for the first packet and positive for subsequent packets. If zero, all digest
components are used to create the query_mac. If non-zero, only the TSIG timers are used to create the query_mac.
* \return status (OK if success)
*/
ldns_status ldns_pkt_tsig_sign_next(ldns_pkt *pkt, const char *key_name, const char *key_data, uint16_t fudge,
const char *algorithm_name, ldns_rdf *query_mac, int tsig_timers_only);
#ifdef __cplusplus
}
#endif
#endif /* LDNS_TSIG_H */

115
contrib/ldns/ldns/update.h Normal file
View file

@ -0,0 +1,115 @@
/*
* update.h
*
* Functions for RFC 2136 Dynamic Update
*
* Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
*
* See LICENSE for the license.
*/
/**
* \file
*
* Defines functions to perform UPDATE queries
*/
#ifndef LDNS_UPDATE_H
#define LDNS_UPDATE_H
#include <ldns/resolver.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* create an update packet from zone name, class and the rr lists
* \param[in] zone_rdf name of the zone
* \param[in] clas zone class
* \param[in] pr_rrlist list of Prerequisite Section RRs
* \param[in] up_rrlist list of Updates Section RRs
* \param[in] ad_rrlist list of Additional Data Section RRs (currently unused)
* \return the new packet
*/
ldns_pkt *ldns_update_pkt_new(ldns_rdf *zone_rdf, ldns_rr_class clas, ldns_rr_list *pr_rrlist, ldns_rr_list *up_rrlist, ldns_rr_list *ad_rrlist);
/**
* add tsig credentials to
* a packet from a resolver
* \param[in] p packet to copy to
* \param[in] r resolver to copy from
*
* \return status wether successfull or not
*/
ldns_status ldns_update_pkt_tsig_add(ldns_pkt *p, ldns_resolver *r);
/* access functions */
/**
* Get the zo count
* \param[in] p the packet
* \return the zo count
*/
uint16_t ldns_update_zocount(const ldns_pkt *p);
/**
* Get the zo count
* \param[in] p the packet
* \return the pr count
*/
uint16_t ldns_update_prcount(const ldns_pkt *p);
/**
* Get the zo count
* \param[in] p the packet
* \return the up count
*/
uint16_t ldns_update_upcount(const ldns_pkt *p);
/**
* Get the zo count
* \param[in] p the packet
* \return the ad count
*/
uint16_t ldns_update_ad(const ldns_pkt *p);
/**
* Set the zo count
* \param[in] p the packet
* \param[in] c the zo count to set
*/
void ldns_update_set_zo(ldns_pkt *p, uint16_t c);
/**
* Set the pr count
* \param[in] p the packet
* \param[in] c the pr count to set
*/
void ldns_update_set_prcount(ldns_pkt *p, uint16_t c);
/**
* Set the up count
* \param[in] p the packet
* \param[in] c the up count to set
*/
void ldns_update_set_upcount(ldns_pkt *p, uint16_t c);
/**
* Set the ad count
* \param[in] p the packet
* \param[in] c the ad count to set
*/
void ldns_update_set_adcount(ldns_pkt *p, uint16_t c);
/* soa functions that need to be configured */
/*
* Not sure if we want to keep these like this, therefore
* not documented
*/
ldns_status ldns_update_soa_mname(ldns_rdf *zone, ldns_resolver *r, ldns_rr_class c, ldns_rdf **mname);
/*
* Not sure if we want to keep these like this, therefore
* not documented
*/
ldns_status ldns_update_soa_zone_mname(const char *fqdn, ldns_resolver *r, ldns_rr_class c, ldns_rdf **zone_rdf, ldns_rdf **mname_rdf);
#ifdef __cplusplus
}
#endif
#endif /* LDNS_UPDATE_H */

367
contrib/ldns/ldns/util.h.in Normal file
View file

@ -0,0 +1,367 @@
/*
* util.h
*
* helper function header file
*
* a Net::DNS like library for C
*
* (c) NLnet Labs, 2004
*
* See the file LICENSE for the license
*/
#ifndef _UTIL_H
#define _UTIL_H
@include_inttypes_h@
@include_systypes_h@
@include_unistd_h@
#include <ldns/common.h>
#include <time.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
#define dprintf(X,Y) fprintf(stderr, (X), (Y))
/* #define dprintf(X, Y) */
#define LDNS_VERSION "@PACKAGE_VERSION@"
#define LDNS_REVISION ((@LDNS_VERSION_MAJOR@<<16)|(@LDNS_VERSION_MINOR@<<8)|(@LDNS_VERSION_MICRO@))
/**
* splint static inline workaround
*/
#ifdef S_SPLINT_S
# define INLINE
#else
# ifdef SWIG
# define INLINE static
# else
# define INLINE static inline
# endif
#endif
/**
* Memory management macros
*/
#define LDNS_MALLOC(type) LDNS_XMALLOC(type, 1)
#define LDNS_XMALLOC(type, count) ((type *) malloc((count) * sizeof(type)))
#define LDNS_CALLOC(type, count) ((type *) calloc((count), sizeof(type)))
#define LDNS_REALLOC(ptr, type) LDNS_XREALLOC((ptr), type, 1)
#define LDNS_XREALLOC(ptr, type, count) \
((type *) realloc((ptr), (count) * sizeof(type)))
#define LDNS_FREE(ptr) \
do { free((ptr)); (ptr) = NULL; } while (0)
#define LDNS_DEP printf("DEPRECATED FUNCTION!\n");
/*
* Copy data allowing for unaligned accesses in network byte order
* (big endian).
*/
INLINE uint16_t
ldns_read_uint16(const void *src)
{
#ifdef ALLOW_UNALIGNED_ACCESSES
return ntohs(*(uint16_t *) src);
#else
uint8_t *p = (uint8_t *) src;
return ((uint16_t) p[0] << 8) | (uint16_t) p[1];
#endif
}
INLINE uint32_t
ldns_read_uint32(const void *src)
{
#ifdef ALLOW_UNALIGNED_ACCESSES
return ntohl(*(uint32_t *) src);
#else
uint8_t *p = (uint8_t *) src;
return ( ((uint32_t) p[0] << 24)
| ((uint32_t) p[1] << 16)
| ((uint32_t) p[2] << 8)
| (uint32_t) p[3]);
#endif
}
/*
* Copy data allowing for unaligned accesses in network byte order
* (big endian).
*/
INLINE void
ldns_write_uint16(void *dst, uint16_t data)
{
#ifdef ALLOW_UNALIGNED_ACCESSES
* (uint16_t *) dst = htons(data);
#else
uint8_t *p = (uint8_t *) dst;
p[0] = (uint8_t) ((data >> 8) & 0xff);
p[1] = (uint8_t) (data & 0xff);
#endif
}
INLINE void
ldns_write_uint32(void *dst, uint32_t data)
{
#ifdef ALLOW_UNALIGNED_ACCESSES
* (uint32_t *) dst = htonl(data);
#else
uint8_t *p = (uint8_t *) dst;
p[0] = (uint8_t) ((data >> 24) & 0xff);
p[1] = (uint8_t) ((data >> 16) & 0xff);
p[2] = (uint8_t) ((data >> 8) & 0xff);
p[3] = (uint8_t) (data & 0xff);
#endif
}
/* warning. */
INLINE void
ldns_write_uint64_as_uint48(void *dst, uint64_t data)
{
uint8_t *p = (uint8_t *) dst;
p[0] = (uint8_t) ((data >> 40) & 0xff);
p[1] = (uint8_t) ((data >> 32) & 0xff);
p[2] = (uint8_t) ((data >> 24) & 0xff);
p[3] = (uint8_t) ((data >> 16) & 0xff);
p[4] = (uint8_t) ((data >> 8) & 0xff);
p[5] = (uint8_t) (data & 0xff);
}
/**
* Structure to do a Schwartzian-like transformation, for instance when
* sorting. If you need a transformation on the objects that are sorted,
* you can sue this to store the transformed values, so you do not
* need to do the transformation again for each comparison
*/
struct ldns_schwartzian_compare_struct {
void *original_object;
void *transformed_object;
};
/** A general purpose lookup table
*
* Lookup tables are arrays of (id, name) pairs,
* So you can for instance lookup the RCODE 3, which is "NXDOMAIN",
* and vice versa. The lookup tables themselves are defined wherever needed,
* for instance in \ref host2str.c
*/
struct ldns_struct_lookup_table {
int id;
const char *name;
};
typedef struct ldns_struct_lookup_table ldns_lookup_table;
/**
* Looks up the table entry by name, returns NULL if not found.
* \param[in] table the lookup table to search in
* \param[in] name what to search for
* \return the item found
*/
ldns_lookup_table *ldns_lookup_by_name(ldns_lookup_table table[],
const char *name);
/**
* Looks up the table entry by id, returns NULL if not found.
* \param[in] table the lookup table to search in
* \param[in] id what to search for
* \return the item found
*/
ldns_lookup_table *ldns_lookup_by_id(ldns_lookup_table table[], int id);
/**
* Returns the value of the specified bit
* The bits are counted from left to right, so bit #0 is the
* left most bit.
* \param[in] bits array holding the bits
* \param[in] index to the wanted bit
* \return
*/
int ldns_get_bit(uint8_t bits[], size_t index);
/**
* Returns the value of the specified bit
* The bits are counted from right to left, so bit #0 is the
* right most bit.
* \param[in] bits array holding the bits
* \param[in] index to the wanted bit
* \return 1 or 0 depending no the bit state
*/
int ldns_get_bit_r(uint8_t bits[], size_t index);
/**
* sets the specified bit in the specified byte to
* 1 if value is true, 0 if false
* The bits are counted from right to left, so bit #0 is the
* right most bit.
* \param[in] byte the bit to set the bit in
* \param[in] bit_nr the bit to set (0 <= n <= 7)
* \param[in] value whether to set the bit to 1 or 0
* \return 1 or 0 depending no the bit state
*/
void ldns_set_bit(uint8_t *byte, int bit_nr, bool value);
/**
* Returns the value of a to the power of b
* (or 1 of b < 1)
*/
/*@unused@*/
INLINE long
ldns_power(long a, long b) {
long result = 1;
while (b > 0) {
if (b & 1) {
result *= a;
if (b == 1) {
return result;
}
}
a *= a;
b /= 2;
}
return result;
}
/**
* Returns the int value of the given (hex) digit
* \param[in] ch the hex char to convert
* \return the converted decimal value
*/
int ldns_hexdigit_to_int(char ch);
/**
* Returns the char (hex) representation of the given int
* \param[in] ch the int to convert
* \return the converted hex char
*/
char ldns_int_to_hexdigit(int ch);
/**
* Converts a hex string to binary data
*
* \param[out] data The binary result is placed here.
* At least strlen(str)/2 bytes should be allocated
* \param[in] str The hex string to convert.
* This string should not contain spaces
* \return The number of bytes of converted data, or -1 if one of the arguments * is NULL, or -2 if the string length is not an even number
*/
int
ldns_hexstring_to_data(uint8_t *data, const char *str);
/**
* Show the internal library version
* \return a string with the version in it
*/
const char * ldns_version(void);
/**
* Convert TM to seconds since epoch (midnight, January 1st, 1970).
* Like timegm(3), which is not always available.
* \param[in] tm a struct tm* with the date
* \return the seconds since epoch
*/
time_t mktime_from_utc(const struct tm *tm);
/**
* The function interprets time as the number of seconds since epoch
* with respect to now using serial arithmitics (rfc1982).
* That number of seconds is then converted to broken-out time information.
* This is especially usefull when converting the inception and expiration
* fields of RRSIG records.
*
* \param[in] time number of seconds since epoch (midnight, January 1st, 1970)
* to be intepreted as a serial arithmitics number relative to now.
* \param[in] now number of seconds since epoch (midnight, January 1st, 1970)
* to which the time value is compared to determine the final value.
* \param[out] result the struct with the broken-out time information
* \return result on success or NULL on error
*/
struct tm * ldns_serial_arithmitics_gmtime_r(int32_t time, time_t now, struct tm *result);
/**
* Seed the random function.
* If the file descriptor is specified, the random generator is seeded with
* data from that file. If not, /dev/urandom is used.
*
* applications should call this if they need entropy data within ldns
* If openSSL is available, it is automatically seeded from /dev/urandom
* or /dev/random.
*
* If you need more entropy, or have no openssl available, this function
* MUST be called at the start of the program
*
* If openssl *is* available, this function just adds more entropy
*
* \param[in] fd a file providing entropy data for the seed
* \param[in] size the number of bytes to use as entropy data. If this is 0,
* only the minimal amount is taken (usually 4 bytes)
* \return 0 if seeding succeeds, 1 if it fails
*/
int ldns_init_random(FILE *fd, unsigned int size);
/**
* Get random number.
* \return random number.
*
*/
uint16_t ldns_get_random(void);
/**
* Encode data as BubbleBabble
*
* \param[in] data a pointer to data to be encoded
* \param[in] len size the number of bytes of data
* \return a string of BubbleBabble
*/
char *ldns_bubblebabble(uint8_t *data, size_t len);
#ifndef B32_NTOP
int ldns_b32_ntop(uint8_t const *src, size_t srclength,
char *target, size_t targsize);
int b32_ntop(uint8_t const *src, size_t srclength,
char *target, size_t targsize);
int ldns_b32_ntop_extended_hex(uint8_t const *src, size_t srclength,
char *target, size_t targsize);
int b32_ntop_extended_hex(uint8_t const *src, size_t srclength,
char *target, size_t targsize);
/**
* calculates the size needed to store the result of b32_ntop
*/
/*@unused@*/
INLINE size_t ldns_b32_ntop_calculate_size(size_t srcsize)
{
size_t result = ((((srcsize / 5) * 8) - 2) + 2);
return result;
}
#endif /* !B32_NTOP */
#ifndef B32_PTON
int ldns_b32_pton(char const *src, size_t hashed_owner_str_len, uint8_t *target, size_t targsize);
int b32_pton(char const *src, size_t hashed_owner_str_len, uint8_t *target, size_t targsize);
int ldns_b32_pton_extended_hex(char const *src, size_t hashed_owner_str_len, uint8_t *target, size_t targsize);
int b32_pton_extended_hex(char const *src, size_t hashed_owner_str_len, uint8_t *target, size_t targsize);
/**
* calculates the size needed to store the result of b32_pton
*/
/*@unused@*/
INLINE size_t ldns_b32_pton_calculate_size(size_t srcsize)
{
size_t result = ((((srcsize) / 8) * 5));
return result;
}
#endif /* !B32_PTON */
INLINE time_t ldns_time(time_t *t) { return time(t); }
#ifdef __cplusplus
}
#endif
#endif /* !_UTIL_H */

View file

@ -0,0 +1,197 @@
/*
* wire2host.h - from wire conversion routines
*
* a Net::DNS like library for C
*
* (c) NLnet Labs, 2005-2006
*
* See the file LICENSE for the license
*/
/**
* \file
*
* Contains functions that translate dns data from the wire format (as sent
* by servers and clients) to the internal structures.
*/
#ifndef LDNS_WIRE2HOST_H
#define LDNS_WIRE2HOST_H
#include <ldns/rdata.h>
#include <ldns/common.h>
#include <ldns/error.h>
#include <ldns/rr.h>
#include <ldns/packet.h>
#ifdef __cplusplus
extern "C" {
#endif
/* The length of the header */
#define LDNS_HEADER_SIZE 12
/* First octet of flags */
#define LDNS_RD_MASK 0x01U
#define LDNS_RD_SHIFT 0
#define LDNS_RD_WIRE(wirebuf) (*(wirebuf+2) & LDNS_RD_MASK)
#define LDNS_RD_SET(wirebuf) (*(wirebuf+2) |= LDNS_RD_MASK)
#define LDNS_RD_CLR(wirebuf) (*(wirebuf+2) &= ~LDNS_RD_MASK)
#define LDNS_TC_MASK 0x02U
#define LDNS_TC_SHIFT 1
#define LDNS_TC_WIRE(wirebuf) (*(wirebuf+2) & LDNS_TC_MASK)
#define LDNS_TC_SET(wirebuf) (*(wirebuf+2) |= LDNS_TC_MASK)
#define LDNS_TC_CLR(wirebuf) (*(wirebuf+2) &= ~LDNS_TC_MASK)
#define LDNS_AA_MASK 0x04U
#define LDNS_AA_SHIFT 2
#define LDNS_AA_WIRE(wirebuf) (*(wirebuf+2) & LDNS_AA_MASK)
#define LDNS_AA_SET(wirebuf) (*(wirebuf+2) |= LDNS_AA_MASK)
#define LDNS_AA_CLR(wirebuf) (*(wirebuf+2) &= ~LDNS_AA_MASK)
#define LDNS_OPCODE_MASK 0x78U
#define LDNS_OPCODE_SHIFT 3
#define LDNS_OPCODE_WIRE(wirebuf) ((*(wirebuf+2) & LDNS_OPCODE_MASK) >> LDNS_OPCODE_SHIFT)
#define LDNS_OPCODE_SET(wirebuf, opcode) \
(*(wirebuf+2) = ((*(wirebuf+2)) & ~LDNS_OPCODE_MASK) | ((opcode) << LDNS_OPCODE_SHIFT))
#define LDNS_QR_MASK 0x80U
#define LDNS_QR_SHIFT 7
#define LDNS_QR_WIRE(wirebuf) (*(wirebuf+2) & LDNS_QR_MASK)
#define LDNS_QR_SET(wirebuf) (*(wirebuf+2) |= LDNS_QR_MASK)
#define LDNS_QR_CLR(wirebuf) (*(wirebuf+2) &= ~LDNS_QR_MASK)
/* Second octet of flags */
#define LDNS_RCODE_MASK 0x0fU
#define LDNS_RCODE_SHIFT 0
#define LDNS_RCODE_WIRE(wirebuf) (*(wirebuf+3) & LDNS_RCODE_MASK)
#define LDNS_RCODE_SET(wirebuf, rcode) \
(*(wirebuf+3) = ((*(wirebuf+3)) & ~LDNS_RCODE_MASK) | (rcode))
#define LDNS_CD_MASK 0x10U
#define LDNS_CD_SHIFT 4
#define LDNS_CD_WIRE(wirebuf) (*(wirebuf+3) & LDNS_CD_MASK)
#define LDNS_CD_SET(wirebuf) (*(wirebuf+3) |= LDNS_CD_MASK)
#define LDNS_CD_CLR(wirebuf) (*(wirebuf+3) &= ~LDNS_CD_MASK)
#define LDNS_AD_MASK 0x20U
#define LDNS_AD_SHIFT 5
#define LDNS_AD_WIRE(wirebuf) (*(wirebuf+3) & LDNS_AD_MASK)
#define LDNS_AD_SET(wirebuf) (*(wirebuf+3) |= LDNS_AD_MASK)
#define LDNS_AD_CLR(wirebuf) (*(wirebuf+3) &= ~LDNS_AD_MASK)
#define LDNS_Z_MASK 0x40U
#define LDNS_Z_SHIFT 6
#define LDNS_Z_WIRE(wirebuf) (*(wirebuf+3) & LDNS_Z_MASK)
#define LDNS_Z_SET(wirebuf) (*(wirebuf+3) |= LDNS_Z_MASK)
#define LDNS_Z_CLR(wirebuf) (*(wirebuf+3) &= ~LDNS_Z_MASK)
#define LDNS_RA_MASK 0x80U
#define LDNS_RA_SHIFT 7
#define LDNS_RA_WIRE(wirebuf) (*(wirebuf+3) & LDNS_RA_MASK)
#define LDNS_RA_SET(wirebuf) (*(wirebuf+3) |= LDNS_RA_MASK)
#define LDNS_RA_CLR(wirebuf) (*(wirebuf+3) &= ~LDNS_RA_MASK)
/* Query ID */
#define LDNS_ID_WIRE(wirebuf) (ldns_read_uint16(wirebuf))
#define LDNS_ID_SET(wirebuf, id) (ldns_write_uint16(wirebuf, id))
/* Counter of the question section */
#define LDNS_QDCOUNT_OFF 4
/*
#define QDCOUNT(wirebuf) (ntohs(*(uint16_t *)(wirebuf+QDCOUNT_OFF)))
*/
#define LDNS_QDCOUNT(wirebuf) (ldns_read_uint16(wirebuf+LDNS_QDCOUNT_OFF))
/* Counter of the answer section */
#define LDNS_ANCOUNT_OFF 6
#define LDNS_ANCOUNT(wirebuf) (ldns_read_uint16(wirebuf+LDNS_ANCOUNT_OFF))
/* Counter of the authority section */
#define LDNS_NSCOUNT_OFF 8
#define LDNS_NSCOUNT(wirebuf) (ldns_read_uint16(wirebuf+LDNS_NSCOUNT_OFF))
/* Counter of the additional section */
#define LDNS_ARCOUNT_OFF 10
#define LDNS_ARCOUNT(wirebuf) (ldns_read_uint16(wirebuf+LDNS_ARCOUNT_OFF))
/**
* converts the data on the uint8_t bytearray (in wire format) to a DNS packet.
* This function will initialize and allocate memory space for the packet
* structure.
*
* \param[in] packet pointer to the structure to hold the packet
* \param[in] data pointer to the buffer with the data
* \param[in] len the length of the data buffer (in bytes)
* \return LDNS_STATUS_OK if everything succeeds, error otherwise
*/
ldns_status ldns_wire2pkt(ldns_pkt **packet, const uint8_t *data, size_t len);
/**
* converts the data on the uint8_t bytearray (in wire format) to a DNS packet.
* This function will initialize and allocate memory space for the packet
* structure.
*
* \param[in] packet pointer to the structure to hold the packet
* \param[in] buffer the buffer with the data
* \return LDNS_STATUS_OK if everything succeeds, error otherwise
*/
ldns_status ldns_buffer2pkt_wire(ldns_pkt **packet, ldns_buffer *buffer);
/**
* converts the data on the uint8_t bytearray (in wire format) to a DNS
* dname rdata field. This function will initialize and allocate memory
* space for the dname structure. The length of the wiredata of this rdf
* is added to the *pos value.
*
* \param[in] dname pointer to the structure to hold the rdata value
* \param[in] wire pointer to the buffer with the data
* \param[in] max the length of the data buffer (in bytes)
* \param[in] pos the position of the rdf in the buffer (ie. the number of bytes
* from the start of the buffer)
* \return LDNS_STATUS_OK if everything succeeds, error otherwise
*/
ldns_status ldns_wire2dname(ldns_rdf **dname, const uint8_t *wire, size_t max, size_t *pos);
/**
* converts the data on the uint8_t bytearray (in wire format) to DNS
* rdata fields, and adds them to the list of rdfs of the given rr.
* This function will initialize and allocate memory space for the dname
* structures.
* The length of the wiredata of these rdfs is added to the *pos value.
*
* All rdfs belonging to the RR are read; the rr should have no rdfs
* yet. An error is returned if the format cannot be parsed.
*
* \param[in] rr pointer to the ldns_rr structure to hold the rdata value
* \param[in] wire pointer to the buffer with the data
* \param[in] max the length of the data buffer (in bytes)
* \param[in] pos the position of the rdf in the buffer (ie. the number of bytes
* from the start of the buffer)
* \return LDNS_STATUS_OK if everything succeeds, error otherwise
*/
ldns_status ldns_wire2rdf(ldns_rr *rr, const uint8_t *wire, size_t max, size_t *pos);
/**
* converts the data on the uint8_t bytearray (in wire format) to a DNS
* resource record.
* This function will initialize and allocate memory space for the rr
* structure.
* The length of the wiredata of this rr is added to the *pos value.
*
* \param[in] rr pointer to the structure to hold the rdata value
* \param[in] wire pointer to the buffer with the data
* \param[in] max the length of the data buffer (in bytes)
* \param[in] pos the position of the rr in the buffer (ie. the number of bytes
* from the start of the buffer)
* \param[in] section the section in the packet the rr is meant for
* \return LDNS_STATUS_OK if everything succeeds, error otherwise
*/
ldns_status ldns_wire2rr(ldns_rr **rr, const uint8_t *wire, size_t max, size_t *pos, ldns_pkt_section section);
#ifdef __cplusplus
}
#endif
#endif /* LDNS_WIRE2HOST_H */

176
contrib/ldns/ldns/zone.h Normal file
View file

@ -0,0 +1,176 @@
/**
* zone.h
*
* zone definitions
* - what is it
* - get_glue function
* - search etc
*
* a Net::DNS like library for C
*
* (c) NLnet Labs, 2005-2006
*
* See the file LICENSE for the license
*/
/**
* \file
*
* Defines the ldns_zone structure and functions to manipulate it.
*/
#ifndef LDNS_ZONE_H
#define LDNS_ZONE_H
#include <ldns/common.h>
#include <ldns/rdata.h>
#include <ldns/rr.h>
#include <ldns/error.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* DNS Zone
*
* A list of RR's with some
* extra information which comes from the SOA RR
* Note: nothing has been done to make this efficient (yet).
*/
struct ldns_struct_zone
{
/** the soa defines a zone */
ldns_rr *_soa;
/* basicly a zone is a list of rr's */
ldns_rr_list *_rrs;
/* we could change this to be a b-tree etc etc todo */
};
typedef struct ldns_struct_zone ldns_zone;
/**
* create a new ldns_zone structure
* \return a pointer to a ldns_zone structure
*/
ldns_zone * ldns_zone_new(void);
/**
* Return the soa record of a zone
* \param[in] z the zone to read from
* \return the soa record in the zone
*/
ldns_rr * ldns_zone_soa(const ldns_zone *z);
/**
* Returns the number of resource records in the zone, NOT counting the SOA record
* \param[in] z the zone to read from
* \return the number of rr's in the zone
*/
size_t ldns_zone_rr_count(const ldns_zone *z);
/**
* Set the zone's soa record
* \param[in] z the zone to put the new soa in
* \param[in] soa the soa to set
*/
void ldns_zone_set_soa(ldns_zone *z, ldns_rr *soa);
/**
* Get a list of a zone's content. Note that the SOA
* isn't included in this list. You need to get the
* with ldns_zone_soa.
* \param[in] z the zone to read from
* \return the rrs from this zone
*/
ldns_rr_list * ldns_zone_rrs(const ldns_zone *z);
/**
* Set the zone's contents
* \param[in] z the zone to put the new soa in
* \param[in] rrlist the rrlist to use
*/
void ldns_zone_set_rrs(ldns_zone *z, ldns_rr_list *rrlist);
/**
* push an rrlist to a zone structure. This function use pointer
* copying, so the rr_list structure inside z is modified!
* \param[in] z the zone to add to
* \param[in] list the list to add
* \return a true on succes otherwise falsed
*/
bool ldns_zone_push_rr_list(ldns_zone *z, ldns_rr_list *list);
/**
* push an single rr to a zone structure. This function use pointer
* copying, so the rr_list structure inside z is modified!
* \param[in] z the zone to add to
* \param[in] rr the rr to add
* \return a true on succes otherwise falsed
*/
bool ldns_zone_push_rr(ldns_zone *z, ldns_rr *rr);
/**
* Retrieve all resource records from the zone that are glue
* records. The resulting list does are pointer references
* to the zone's data.
*
* Due to the current zone implementation (as a list of rr's), this
* function is extremely slow. Another (probably better) way to do this
* is to use an ldns_dnssec_zone structure and the
* ldns_dnssec_mark_and_get_glue() function.
*
* \param[in] z the zone to look for glue
* \return the rr_list with the glue
*/
ldns_rr_list *ldns_zone_glue_rr_list(const ldns_zone *z);
/**
* Create a new zone from a file
* \param[out] z the new zone
* \param[in] *fp the filepointer to use
* \param[in] *origin the zones' origin
* \param[in] ttl default ttl to use
* \param[in] c default class to use (IN)
*
* \return ldns_status mesg with an error or LDNS_STATUS_OK
*/
ldns_status ldns_zone_new_frm_fp(ldns_zone **z, FILE *fp, ldns_rdf *origin, uint32_t ttl, ldns_rr_class c);
/**
* Create a new zone from a file, keep track of the line numbering
* \param[out] z the new zone
* \param[in] *fp the filepointer to use
* \param[in] *origin the zones' origin
* \param[in] ttl default ttl to use
* \param[in] c default class to use (IN)
* \param[out] line_nr used for error msg, to get to the line number
*
* \return ldns_status mesg with an error or LDNS_STATUS_OK
*/
ldns_status ldns_zone_new_frm_fp_l(ldns_zone **z, FILE *fp, ldns_rdf *origin, uint32_t ttl, ldns_rr_class c, int *line_nr);
/**
* Frees the allocated memory for the zone, and the rr_list structure in it
* \param[in] zone the zone to free
*/
void ldns_zone_free(ldns_zone *zone);
/**
* Frees the allocated memory for the zone, the soa rr in it,
* and the rr_list structure in it, including the rr's in that. etc.
* \param[in] zone the zone to free
*/
void ldns_zone_deep_free(ldns_zone *zone);
/**
* Sort the rrs in a zone, with the current impl. this is slow
* \param[in] zone the zone to sort
*/
void ldns_zone_sort(ldns_zone *zone);
#ifdef __cplusplus
}
#endif
#endif /* LDNS_ZONE_H */

View file

@ -0,0 +1,786 @@
ldns_algorithm2buffer_str
ldns_algorithms
ldns_axfr_complete
ldns_axfr_last_pkt
ldns_axfr_next
ldns_axfr_start
ldns_bgetc
ldns_bget_keyword_data
ldns_bget_token
ldns_bskipcs
ldns_bubblebabble
ldns_buffer2pkt_wire
ldns_buffer2str
ldns_buffer_copy
ldns_buffer_export
ldns_buffer_free
ldns_buffer_new
ldns_buffer_new_frm_data
ldns_buffer_printf
ldns_buffer_reserve
ldns_buffer_set_capacity
ldns_calc_keytag
ldns_calc_keytag_raw
ldns_cert_algorithm2buffer_str
ldns_cert_algorithms
ldns_convert_dsa_rrsig_asn12rdf
ldns_convert_dsa_rrsig_rdf2asn1
ldns_convert_ecdsa_rrsig_asn12rdf
ldns_convert_ecdsa_rrsig_rdf2asn1
ldns_create_empty_rrsig
ldns_create_nsec
ldns_create_nsec3
ldns_digest_evp
ldns_directive_types
ldns_dname2buffer_wire
ldns_dname2canonical
ldns_dname_cat
ldns_dname_cat_clone
ldns_dname_clone_from
ldns_dname_compare
ldns_dname_interval
ldns_dname_is_subdomain
ldns_dname_is_wildcard
ldns_dname_label
ldns_dname_label_count
ldns_dname_left_chop
ldns_dname_match_wildcard
ldns_dname_new
ldns_dname_new_frm_data
ldns_dname_new_frm_str
ldns_dname_reverse
ldns_dname_str_absolute
ldns_dnssec_build_data_chain
ldns_dnssec_chain_nsec3_list
ldns_dnssec_create_nsec
ldns_dnssec_create_nsec3
ldns_dnssec_create_nsec_bitmap
ldns_dnssec_data_chain_deep_free
ldns_dnssec_data_chain_free
ldns_dnssec_data_chain_new
ldns_dnssec_data_chain_print
ldns_dnssec_data_chain_print_fmt
ldns_dnssec_default_add_to_signatures
ldns_dnssec_default_delete_signatures
ldns_dnssec_default_leave_signatures
ldns_dnssec_default_replace_signatures
ldns_dnssec_derive_trust_tree
ldns_dnssec_derive_trust_tree_dnskey_rrset
ldns_dnssec_derive_trust_tree_dnskey_rrset_time
ldns_dnssec_derive_trust_tree_ds_rrset
ldns_dnssec_derive_trust_tree_ds_rrset_time
ldns_dnssec_derive_trust_tree_normal_rrset
ldns_dnssec_derive_trust_tree_normal_rrset_time
ldns_dnssec_derive_trust_tree_no_sig
ldns_dnssec_derive_trust_tree_no_sig_time
ldns_dnssec_derive_trust_tree_time
ldns_dnssec_get_dnskey_for_rrsig
ldns_dnssec_get_rrsig_for_name_and_type
ldns_dnssec_name_add_rr
ldns_dnssec_name_cmp
ldns_dnssec_name_deep_free
ldns_dnssec_name_find_rrset
ldns_dnssec_name_free
ldns_dnssec_name_is_glue
ldns_dnssec_name_name
ldns_dnssec_name_new
ldns_dnssec_name_new_frm_rr
ldns_dnssec_name_node_next_nonglue
ldns_dnssec_name_print
ldns_dnssec_name_print_fmt
ldns_dnssec_name_set_name
ldns_dnssec_name_set_nsec
ldns_dnssec_nsec3_closest_encloser
ldns_dnssec_pkt_get_rrsigs_for_name_and_type
ldns_dnssec_pkt_get_rrsigs_for_type
ldns_dnssec_pkt_has_rrsigs
ldns_dnssec_remove_signatures
ldns_dnssec_rrs_add_rr
ldns_dnssec_rrs_deep_free
ldns_dnssec_rrsets_add_rr
ldns_dnssec_rrsets_contains_type
ldns_dnssec_rrsets_deep_free
ldns_dnssec_rrsets_free
ldns_dnssec_rrsets_new
ldns_dnssec_rrsets_print
ldns_dnssec_rrsets_print_fmt
ldns_dnssec_rrsets_set_type
ldns_dnssec_rrsets_type
ldns_dnssec_rrs_free
ldns_dnssec_rrs_new
ldns_dnssec_rrs_print
ldns_dnssec_rrs_print_fmt
ldns_dnssec_trust_tree_add_parent
ldns_dnssec_trust_tree_contains_keys
ldns_dnssec_trust_tree_depth
ldns_dnssec_trust_tree_free
ldns_dnssec_trust_tree_new
ldns_dnssec_trust_tree_print
ldns_dnssec_trust_tree_print_fmt
ldns_dnssec_verify_denial
ldns_dnssec_verify_denial_nsec3
ldns_dnssec_verify_denial_nsec3_match
ldns_dnssec_zone_add_empty_nonterminals
ldns_dnssec_zone_add_rr
ldns_dnssec_zone_create_nsec3s
ldns_dnssec_zone_create_nsecs
ldns_dnssec_zone_create_rrsigs
ldns_dnssec_zone_create_rrsigs_flg
ldns_dnssec_zone_deep_free
ldns_dnssec_zone_find_rrset
ldns_dnssec_zone_free
ldns_dnssec_zone_is_nsec3_optout
ldns_dnssec_zone_mark_and_get_glue
ldns_dnssec_zone_mark_glue
ldns_dnssec_zone_names_print
ldns_dnssec_zone_names_print_fmt
ldns_dnssec_zone_new
ldns_dnssec_zone_new_frm_fp
ldns_dnssec_zone_new_frm_fp_l
ldns_dnssec_zone_print
ldns_dnssec_zone_print_fmt
ldns_dnssec_zone_sign
ldns_dnssec_zone_sign_flg
ldns_dnssec_zone_sign_nsec3
ldns_dnssec_zone_sign_nsec3_flg
ldns_dnssec_zone_sign_nsec3_flg_mkmap
ldns_duration2string
ldns_duration2time
ldns_duration_cleanup
ldns_duration_compare
ldns_duration_create
ldns_duration_create_from_string
ldns_ecdsa2pkey_raw
ldns_edns_flags
ldns_error_str
ldns_fetch_valid_domain_keys
ldns_fetch_valid_domain_keys_time
ldns_fget_keyword_data
ldns_fget_keyword_data_l
ldns_fget_token
ldns_fget_token_l
ldns_fskipcs
ldns_fskipcs_l
ldns_getaddrinfo
ldns_get_bit
ldns_get_bit_r
ldns_get_errorstr_by_id
ldns_get_random
ldns_get_rr_class_by_name
ldns_get_rr_list_addr_by_name
ldns_get_rr_list_hosts_frm_file
ldns_get_rr_list_hosts_frm_fp
ldns_get_rr_list_hosts_frm_fp_l
ldns_get_rr_list_name_by_addr
ldns_get_rr_type_by_name
ldns_get_signing_algorithm_by_name
ldns_gost2pkey_raw
ldns_hexdigit_to_int
ldns_hexstring_to_data
ldns_init_random
ldns_int_to_hexdigit
ldns_is_rrset
ldns_key2buffer_str
ldns_key2rr
ldns_key2str
ldns_key_EVP_load_gost_id
ldns_key_EVP_unload_gost
ldns_key_algorithm
ldns_key_algo_supported
ldns_key_buf2dsa
ldns_key_buf2dsa_raw
ldns_key_buf2rsa
ldns_key_buf2rsa_raw
ldns_key_deep_free
ldns_key_dsa_key
ldns_key_evp_key
ldns_key_expiration
ldns_key_external_key
ldns_key_flags
ldns_key_free
ldns_key_get_file_base_name
ldns_key_hmac_key
ldns_key_hmac_size
ldns_key_inception
ldns_key_keytag
ldns_key_list_free
ldns_key_list_key
ldns_key_list_key_count
ldns_key_list_new
ldns_key_list_pop_key
ldns_key_list_push_key
ldns_key_list_set_key_count
ldns_key_list_set_use
ldns_key_new
ldns_key_new_frm_algorithm
ldns_key_new_frm_engine
ldns_key_new_frm_fp
ldns_key_new_frm_fp_dsa
ldns_key_new_frm_fp_dsa_l
ldns_key_new_frm_fp_hmac
ldns_key_new_frm_fp_hmac_l
ldns_key_new_frm_fp_l
ldns_key_new_frm_fp_rsa
ldns_key_new_frm_fp_rsa_l
ldns_key_origttl
ldns_key_print
ldns_key_pubkey_owner
ldns_key_rr2ds
ldns_key_rsa_key
ldns_key_set_algorithm
ldns_key_set_dsa_key
ldns_key_set_evp_key
ldns_key_set_expiration
ldns_key_set_external_key
ldns_key_set_flags
ldns_key_set_hmac_key
ldns_key_set_hmac_size
ldns_key_set_inception
ldns_key_set_keytag
ldns_key_set_origttl
ldns_key_set_pubkey_owner
ldns_key_set_rsa_key
ldns_key_set_use
ldns_key_use
ldns_lookup_by_id
ldns_lookup_by_name
ldns_native2rdf_int16
ldns_native2rdf_int16_data
ldns_native2rdf_int32
ldns_native2rdf_int8
ldns_nsec3_add_param_rdfs
ldns_nsec3_algorithm
ldns_nsec3_bitmap
ldns_nsec3_flags
ldns_nsec3_hash_name
ldns_nsec3_hash_name_frm_nsec3
ldns_nsec3_iterations
ldns_nsec3_next_owner
ldns_nsec3_optout
ldns_nsec3_salt
ldns_nsec3_salt_data
ldns_nsec3_salt_length
ldns_nsec_bitmap_covers_type
ldns_nsec_covers_name
ldns_nsec_get_bitmap
ldns_nsec_type_check
ldns_octet
ldns_opcodes
ldns_output_format_bubblebabble
ldns_output_format_default
ldns_output_format_nocomments
ldns_output_format_onlykeyids
ldns_pkt2buffer_str
ldns_pkt2buffer_str_fmt
ldns_pkt2buffer_wire
ldns_pkt2str
ldns_pkt2str_fmt
ldns_pkt2wire
ldns_pkt_aa
ldns_pkt_ad
ldns_pkt_additional
ldns_pkt_algorithm2str
ldns_pkt_all
ldns_pkt_all_noquestion
ldns_pkt_ancount
ldns_pkt_answer
ldns_pkt_answerfrom
ldns_pkt_arcount
ldns_pkt_authority
ldns_pkt_cd
ldns_pkt_cert_algorithm2str
ldns_pkt_clone
ldns_pkt_edns
ldns_pkt_edns_data
ldns_pkt_edns_do
ldns_pkt_edns_extended_rcode
ldns_pkt_edns_udp_size
ldns_pkt_edns_version
ldns_pkt_edns_z
ldns_pkt_empty
ldns_pkt_free
ldns_pkt_get_opcode
ldns_pkt_get_rcode
ldns_pkt_get_section_clone
ldns_pktheader2buffer_str
ldns_pkt_id
ldns_pkt_new
ldns_pkt_nscount
ldns_pkt_opcode2buffer_str
ldns_pkt_opcode2str
ldns_pkt_print
ldns_pkt_print_fmt
ldns_pkt_push_rr
ldns_pkt_push_rr_list
ldns_pkt_qdcount
ldns_pkt_qr
ldns_pkt_query_new
ldns_pkt_query_new_frm_str
ldns_pkt_querytime
ldns_pkt_question
ldns_pkt_ra
ldns_pkt_rcode2buffer_str
ldns_pkt_rcode2str
ldns_pkt_rd
ldns_pkt_reply_type
ldns_pkt_rr
ldns_pkt_rr_list_by_name
ldns_pkt_rr_list_by_name_and_type
ldns_pkt_rr_list_by_type
ldns_pkt_safe_push_rr
ldns_pkt_safe_push_rr_list
ldns_pkt_set_aa
ldns_pkt_set_ad
ldns_pkt_set_additional
ldns_pkt_set_ancount
ldns_pkt_set_answer
ldns_pkt_set_answerfrom
ldns_pkt_set_arcount
ldns_pkt_set_authority
ldns_pkt_set_cd
ldns_pkt_set_edns_data
ldns_pkt_set_edns_do
ldns_pkt_set_edns_extended_rcode
ldns_pkt_set_edns_udp_size
ldns_pkt_set_edns_version
ldns_pkt_set_edns_z
ldns_pkt_set_flags
ldns_pkt_set_id
ldns_pkt_set_nscount
ldns_pkt_set_opcode
ldns_pkt_set_qdcount
ldns_pkt_set_qr
ldns_pkt_set_querytime
ldns_pkt_set_question
ldns_pkt_set_ra
ldns_pkt_set_random_id
ldns_pkt_set_rcode
ldns_pkt_set_rd
ldns_pkt_set_section_count
ldns_pkt_set_size
ldns_pkt_set_tc
ldns_pkt_set_timestamp
ldns_pkt_set_tsig
ldns_pkt_size
ldns_pkt_tc
ldns_pkt_timestamp
ldns_pkt_tsig
ldns_pkt_tsig_sign
ldns_pkt_tsig_sign_next
ldns_pkt_tsig_verify
ldns_pkt_tsig_verify_next
ldns_pkt_verify
ldns_pkt_verify_time
ldns_print_rr_rdf
ldns_rbtree_create
ldns_rbtree_delete
ldns_rbtree_find_less_equal
ldns_rbtree_first
ldns_rbtree_free
ldns_rbtree_init
ldns_rbtree_insert
ldns_rbtree_insert_vref
ldns_rbtree_join
ldns_rbtree_last
ldns_rbtree_next
ldns_rbtree_null_node
ldns_rbtree_previous
ldns_rbtree_search
ldns_rbtree_split
ldns_rcodes
ldns_rdf2buffer_str
ldns_rdf2buffer_str_a
ldns_rdf2buffer_str_aaaa
ldns_rdf2buffer_str_alg
ldns_rdf2buffer_str_apl
ldns_rdf2buffer_str_atma
ldns_rdf2buffer_str_b32_ext
ldns_rdf2buffer_str_b64
ldns_rdf2buffer_str_cert_alg
ldns_rdf2buffer_str_class
ldns_rdf2buffer_str_dname
ldns_rdf2buffer_str_hex
ldns_rdf2buffer_str_int16
ldns_rdf2buffer_str_int16_data
ldns_rdf2buffer_str_int32
ldns_rdf2buffer_str_int8
ldns_rdf2buffer_str_ipseckey
ldns_rdf2buffer_str_loc
ldns_rdf2buffer_str_nsap
ldns_rdf2buffer_str_nsec
ldns_rdf2buffer_str_nsec3_salt
ldns_rdf2buffer_str_period
ldns_rdf2buffer_str_str
ldns_rdf2buffer_str_time
ldns_rdf2buffer_str_tsig
ldns_rdf2buffer_str_tsigtime
ldns_rdf2buffer_str_type
ldns_rdf2buffer_str_unknown
ldns_rdf2buffer_str_wks
ldns_rdf2buffer_wire
ldns_rdf2buffer_wire_canonical
ldns_rdf2native_int16
ldns_rdf2native_int32
ldns_rdf2native_int8
ldns_rdf2native_sockaddr_storage
ldns_rdf2native_time_t
ldns_rdf2rr_type
ldns_rdf2str
ldns_rdf2wire
ldns_rdf_address_reverse
ldns_rdf_clone
ldns_rdf_compare
ldns_rdf_data
ldns_rdf_deep_free
ldns_rdf_free
ldns_rdf_get_type
ldns_rdf_new
ldns_rdf_new_frm_data
ldns_rdf_new_frm_fp
ldns_rdf_new_frm_fp_l
ldns_rdf_new_frm_str
ldns_rdf_print
ldns_rdf_set_data
ldns_rdf_set_size
ldns_rdf_set_type
ldns_rdf_size
ldns_read_anchor_file
ldns_resolver_debug
ldns_resolver_dec_nameserver_count
ldns_resolver_deep_free
ldns_resolver_defnames
ldns_resolver_dnsrch
ldns_resolver_dnssec
ldns_resolver_dnssec_anchors
ldns_resolver_dnssec_cd
ldns_resolver_domain
ldns_resolver_edns_udp_size
ldns_resolver_fail
ldns_resolver_fallback
ldns_resolver_free
ldns_resolver_igntc
ldns_resolver_incr_nameserver_count
ldns_resolver_ip6
ldns_resolver_nameserver_count
ldns_resolver_nameserver_rtt
ldns_resolver_nameservers
ldns_resolver_nameservers_randomize
ldns_resolver_new
ldns_resolver_new_frm_file
ldns_resolver_new_frm_fp
ldns_resolver_new_frm_fp_l
ldns_resolver_pop_nameserver
ldns_resolver_port
ldns_resolver_prepare_query_pkt
ldns_resolver_print
ldns_resolver_print_fmt
ldns_resolver_push_dnssec_anchor
ldns_resolver_push_nameserver
ldns_resolver_push_nameserver_rr
ldns_resolver_push_nameserver_rr_list
ldns_resolver_push_searchlist
ldns_resolver_query
ldns_resolver_random
ldns_resolver_recursive
ldns_resolver_retrans
ldns_resolver_retry
ldns_resolver_rtt
ldns_resolver_search
ldns_resolver_searchlist
ldns_resolver_searchlist_count
ldns_resolver_send
ldns_resolver_send_pkt
ldns_resolver_set_debug
ldns_resolver_set_defnames
ldns_resolver_set_dnsrch
ldns_resolver_set_dnssec
ldns_resolver_set_dnssec_anchors
ldns_resolver_set_dnssec_cd
ldns_resolver_set_domain
ldns_resolver_set_edns_udp_size
ldns_resolver_set_fail
ldns_resolver_set_fallback
ldns_resolver_set_igntc
ldns_resolver_set_ip6
ldns_resolver_set_nameserver_count
ldns_resolver_set_nameserver_rtt
ldns_resolver_set_nameservers
ldns_resolver_set_port
ldns_resolver_set_random
ldns_resolver_set_recursive
ldns_resolver_set_retrans
ldns_resolver_set_retry
ldns_resolver_set_rtt
ldns_resolver_set_timeout
ldns_resolver_set_tsig_algorithm
ldns_resolver_set_tsig_keydata
ldns_resolver_set_tsig_keyname
ldns_resolver_set_usevc
ldns_resolver_timeout
ldns_resolver_trusted_key
ldns_resolver_tsig_algorithm
ldns_resolver_tsig_keydata
ldns_resolver_tsig_keyname
ldns_resolver_usevc
ldns_rr2buffer_str
ldns_rr2buffer_str_fmt
ldns_rr2buffer_wire
ldns_rr2buffer_wire_canonical
ldns_rr2canonical
ldns_rr2str
ldns_rr2str_fmt
ldns_rr2wire
ldns_rr_a_address
ldns_rr_a_set_address
ldns_rr_class2buffer_str
ldns_rr_class2str
ldns_rr_classes
ldns_rr_clone
ldns_rr_compare
ldns_rr_compare_ds
ldns_rr_compare_no_rdata
ldns_rr_compare_wire
ldns_rr_descript
ldns_rr_descriptor_field_type
ldns_rr_descriptor_maximum
ldns_rr_descriptor_minimum
ldns_rr_dnskey_algorithm
ldns_rr_dnskey_flags
ldns_rr_dnskey_key
ldns_rr_dnskey_key_size
ldns_rr_dnskey_key_size_raw
ldns_rr_dnskey_protocol
ldns_rr_dnskey_set_algorithm
ldns_rr_dnskey_set_flags
ldns_rr_dnskey_set_key
ldns_rr_dnskey_set_protocol
ldns_rr_free
ldns_rr_get_class
ldns_rr_get_type
ldns_rr_is_question
ldns_rr_label_count
ldns_rr_list2buffer_str
ldns_rr_list2buffer_str_fmt
ldns_rr_list2buffer_wire
ldns_rr_list2canonical
ldns_rr_list2str
ldns_rr_list2str_fmt
ldns_rr_list_cat
ldns_rr_list_cat_clone
ldns_rr_list_clone
ldns_rr_list_compare
ldns_rr_list_contains_rr
ldns_rr_list_deep_free
ldns_rr_list_free
ldns_rr_list_new
ldns_rr_list_owner
ldns_rr_list_pop_rr
ldns_rr_list_pop_rr_list
ldns_rr_list_pop_rrset
ldns_rr_list_print
ldns_rr_list_print_fmt
ldns_rr_list_push_rr
ldns_rr_list_push_rr_list
ldns_rr_list_rr
ldns_rr_list_rr_count
ldns_rr_list_set_rr
ldns_rr_list_set_rr_count
ldns_rr_list_sort
ldns_rr_list_sort_nsec3
ldns_rr_list_subtype_by_rdf
ldns_rr_list_type
ldns_rr_mx_exchange
ldns_rr_mx_preference
ldns_rr_new
ldns_rr_new_frm_fp
ldns_rr_new_frm_fp_l
ldns_rr_new_frm_str
ldns_rr_new_frm_type
ldns_rr_new_question_frm_str
ldns_rr_ns_nsdname
ldns_rr_owner
ldns_rr_pop_rdf
ldns_rr_print
ldns_rr_print_fmt
ldns_rr_push_rdf
ldns_rr_rdata2buffer_wire
ldns_rr_rd_count
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_set_algorithm
ldns_rr_rrsig_set_expiration
ldns_rr_rrsig_set_inception
ldns_rr_rrsig_set_keytag
ldns_rr_rrsig_set_labels
ldns_rr_rrsig_set_origttl
ldns_rr_rrsig_set_sig
ldns_rr_rrsig_set_signame
ldns_rr_rrsig_set_typecovered
ldns_rr_rrsig_sig
ldns_rr_rrsig_signame
ldns_rr_rrsig_typecovered
ldns_rr_set_class
ldns_rr_set_owner
ldns_rr_set_pop_rr
ldns_rr_set_push_rr
ldns_rr_set_question
ldns_rr_set_rd_count
ldns_rr_set_rdf
ldns_rr_set_ttl
ldns_rr_set_type
ldns_rrsig2buffer_wire
ldns_rr_soa_increment
ldns_rr_soa_increment_func
ldns_rr_soa_increment_func_data
ldns_rr_soa_increment_func_int
ldns_rr_ttl
ldns_rr_type2buffer_str
ldns_rr_type2str
ldns_rr_uncompressed_size
ldns_send
ldns_send_buffer
ldns_serial_arithmitics_gmtime_r
ldns_set_bit
ldns_sha1
ldns_sha1_final
ldns_sha1_init
ldns_sha1_transform
ldns_sha1_update
ldns_sha256
ldns_sha256_final
ldns_sha256_init
ldns_sha256_update
ldns_sha384
ldns_sha384_final
ldns_sha384_init
ldns_sha384_update
ldns_sha512
ldns_sha512_final
ldns_sha512_init
ldns_sha512_update
ldns_signing_algorithms
ldns_sign_public
ldns_sign_public_buffer
ldns_sign_public_dsa
ldns_sign_public_evp
ldns_sign_public_rsamd5
ldns_sign_public_rsasha1
ldns_soa_serial_datecounter
ldns_soa_serial_identity
ldns_soa_serial_increment
ldns_soa_serial_increment_by
ldns_soa_serial_unixtime
ldns_sockaddr_storage2rdf
ldns_str2period
ldns_str2rdf_a
ldns_str2rdf_aaaa
ldns_str2rdf_alg
ldns_str2rdf_apl
ldns_str2rdf_atma
ldns_str2rdf_b32_ext
ldns_str2rdf_b64
ldns_str2rdf_cert_alg
ldns_str2rdf_class
ldns_str2rdf_dname
ldns_str2rdf_hex
ldns_str2rdf_int16
ldns_str2rdf_int32
ldns_str2rdf_int8
ldns_str2rdf_ipseckey
ldns_str2rdf_loc
ldns_str2rdf_nsap
ldns_str2rdf_nsec
ldns_str2rdf_nsec3_salt
ldns_str2rdf_period
ldns_str2rdf_service
ldns_str2rdf_str
ldns_str2rdf_time
ldns_str2rdf_tsig
ldns_str2rdf_type
ldns_str2rdf_unknown
ldns_str2rdf_wks
ldns_tcp_bgsend
ldns_tcp_connect
ldns_tcp_read_wire
ldns_tcp_read_wire_timeout
ldns_tcp_send
ldns_tcp_send_query
ldns_traverse_postorder
ldns_tsig_algorithm
ldns_tsig_keydata
ldns_tsig_keydata_clone
ldns_tsig_keyname
ldns_tsig_keyname_clone
ldns_udp_bgsend
ldns_udp_connect
ldns_udp_read_wire
ldns_udp_send
ldns_udp_send_query
ldns_update_ad
ldns_update_pkt_new
ldns_update_pkt_tsig_add
ldns_update_prcount
ldns_update_set_adcount
ldns_update_set_prcount
ldns_update_set_upcount
ldns_update_set_zo
ldns_update_soa_mname
ldns_update_soa_zone_mname
ldns_update_upcount
ldns_update_zocount
ldns_validate_domain_dnskey
ldns_validate_domain_dnskey_time
ldns_validate_domain_ds
ldns_validate_domain_ds_time
ldns_verify
ldns_verify_notime
ldns_verify_rrsig
ldns_verify_rrsig_buffers
ldns_verify_rrsig_buffers_raw
ldns_verify_rrsig_dsa
ldns_verify_rrsig_dsa_raw
ldns_verify_rrsig_evp
ldns_verify_rrsig_evp_raw
ldns_verify_rrsig_keylist
ldns_verify_rrsig_keylist_notime
ldns_verify_rrsig_keylist_time
ldns_verify_rrsig_rsamd5
ldns_verify_rrsig_rsamd5_raw
ldns_verify_rrsig_rsasha1
ldns_verify_rrsig_rsasha1_raw
ldns_verify_rrsig_rsasha256_raw
ldns_verify_rrsig_rsasha512_raw
ldns_verify_rrsig_time
ldns_verify_time
ldns_verify_trusted
ldns_verify_trusted_time
ldns_version
ldns_wire2dname
ldns_wire2pkt
ldns_wire2rdf
ldns_wire2rr
ldns_zone_deep_free
ldns_zone_free
ldns_zone_glue_rr_list
ldns_zone_new
ldns_zone_new_frm_fp
ldns_zone_new_frm_fp_l
ldns_zone_print
ldns_zone_print_fmt
ldns_zone_push_rr
ldns_zone_push_rr_list
ldns_zone_rr_count
ldns_zone_rrs
ldns_zone_set_rrs
ldns_zone_set_soa
ldns_zone_sign
ldns_zone_sign_nsec3
ldns_zone_soa
ldns_zone_sort
mktime_from_utc
qsort_rr_compare_nsec3

1684
contrib/ldns/libdns.doxygen Normal file

File diff suppressed because it is too large Load diff

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