- separate ldns into core ldns inside ldns/ subdirectory. No more

--with-ldns is needed and unbound does not rely on libldns.


git-svn-id: file:///svn/unbound/trunk@2998 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2013-10-31 15:09:26 +00:00
parent 1a9e620f8c
commit 29e96e86c9
268 changed files with 13955 additions and 5108 deletions

File diff suppressed because it is too large Load Diff

73
compat/strlcat.c Normal file
View File

@ -0,0 +1,73 @@
/* compat/strlcat.c */
/*-
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 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. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``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.
*/
/* OPENBSD ORIGINAL: lib/libc/string/strlcat.c */
#include "config.h"
#ifndef HAVE_STRLCAT
#include <sys/types.h>
#include <string.h>
/*
* Appends src to string dst of size siz (unlike strncat, siz is the
* full size of dst, not space left). At most siz-1 characters
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
* If retval >= siz, truncation occurred.
*/
size_t
strlcat(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
size_t dlen;
/* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0')
d++;
dlen = d - dst;
n = siz - dlen;
if (n == 0)
return(dlen + strlen(s));
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
return(dlen + (s - src)); /* count does not include NUL */
}
#endif /* !HAVE_STRLCAT */

View File

@ -70,6 +70,12 @@
/* 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 `event_base_free' function. */
#undef HAVE_EVENT_BASE_FREE
@ -166,15 +172,6 @@
/* Define to 1 if you have the `kill' function. */
#undef HAVE_KILL
/* Define to 1 if you have the `ldns_key_EVP_unload_gost' function. */
#undef HAVE_LDNS_KEY_EVP_UNLOAD_GOST
/* Define to 1 if you have the <ldns/ldns.h> header file. */
#undef HAVE_LDNS_LDNS_H
/* Define to 1 if you have the `ldns' library (-lldns). */
#undef HAVE_LIBLDNS
/* Define to 1 if you have the `localtime_r' function. */
#undef HAVE_LOCALTIME_R
@ -310,6 +307,9 @@
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strlcat' function. */
#undef HAVE_STRLCAT
/* Define to 1 if you have the `strlcpy' function. */
#undef HAVE_STRLCPY
@ -475,6 +475,9 @@
/* Shared data */
#undef SHARE_DIR
/* 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
@ -687,6 +690,12 @@
# define NDEBUG
#endif
/** Use small-ldns codebase */
#define USE_SLDNS 1
#ifdef HAVE_SSL
# define LDNS_BUILD_CONFIG_HAVE_SSL 1
#endif
#include <stdio.h>
#include <string.h>
#include <unistd.h>
@ -796,6 +805,12 @@ void *memmove(void *dest, const void *src, size_t n);
#endif
#ifndef HAVE_STRLCAT
#define strlcat strlcat_unbound
size_t strlcat(char *dst, const char *src, size_t siz);
#endif
#ifndef HAVE_STRLCPY
#define strlcpy strlcpy_unbound
size_t strlcpy(char *dst, const char *src, size_t siz);

436
configure vendored
View File

@ -632,7 +632,6 @@ ac_includes_default="\
#endif"
ac_subst_vars='LTLIBOBJS
ldnsdir
ALLTARGET
SOURCEFILE
SOURCEDETERMINE
@ -827,7 +826,6 @@ enable_static_exe
enable_lock_checks
enable_allsymbols
with_libunbound_only
with_ldns
'
ac_precious_vars='build_alias
host_alias
@ -1528,7 +1526,6 @@ Optional Packages:
outgoing port ranges.
--with-libexpat=path specify explicit path for libexpat.
--with-libunbound-only do not build daemon and tool programs
--with-ldns=PATH specify prefix of path of ldns library to use
Some influential environment variables:
CC C compiler command
@ -2036,6 +2033,189 @@ $as_echo "$ac_res" >&6; }
} # ac_fn_c_check_type
# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
# --------------------------------------------
# Tries to find the compile-time value of EXPR in a program that includes
# INCLUDES, setting VAR accordingly. Returns whether the value could be
# computed
ac_fn_c_compute_int ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
if test "$cross_compiling" = yes; then
# Depending upon the size, compute the lo and hi bounds.
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$4
int
main ()
{
static int test_array [1 - 2 * !(($2) >= 0)];
test_array [0] = 0;
return test_array [0];
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_lo=0 ac_mid=0
while :; do
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$4
int
main ()
{
static int test_array [1 - 2 * !(($2) <= $ac_mid)];
test_array [0] = 0;
return test_array [0];
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_hi=$ac_mid; break
else
as_fn_arith $ac_mid + 1 && ac_lo=$as_val
if test $ac_lo -le $ac_mid; then
ac_lo= ac_hi=
break
fi
as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
done
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$4
int
main ()
{
static int test_array [1 - 2 * !(($2) < 0)];
test_array [0] = 0;
return test_array [0];
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_hi=-1 ac_mid=-1
while :; do
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$4
int
main ()
{
static int test_array [1 - 2 * !(($2) >= $ac_mid)];
test_array [0] = 0;
return test_array [0];
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_lo=$ac_mid; break
else
as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
if test $ac_mid -le $ac_hi; then
ac_lo= ac_hi=
break
fi
as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
done
else
ac_lo= ac_hi=
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
# Binary search between lo and hi bounds.
while test "x$ac_lo" != "x$ac_hi"; do
as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$4
int
main ()
{
static int test_array [1 - 2 * !(($2) <= $ac_mid)];
test_array [0] = 0;
return test_array [0];
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_hi=$ac_mid
else
as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
done
case $ac_lo in #((
?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
'') ac_retval=1 ;;
esac
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$4
static long int longval () { return $2; }
static unsigned long int ulongval () { return $2; }
#include <stdio.h>
#include <stdlib.h>
int
main ()
{
FILE *f = fopen ("conftest.val", "w");
if (! f)
return 1;
if (($2) < 0)
{
long int i = longval ();
if (i != ($2))
return 1;
fprintf (f, "%ld", i);
}
else
{
unsigned long int i = ulongval ();
if (i != ($2))
return 1;
fprintf (f, "%lu", i);
}
/* Do not output a trailing newline, as this causes \r\n confusion
on some platforms. */
return ferror (f) || fclose (f) != 0;
;
return 0;
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
echo >>conftest.val; read $3 <conftest.val; ac_retval=0
else
ac_retval=1
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
rm -f conftest.val
fi
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
as_fn_set_status $ac_retval
} # ac_fn_c_compute_int
# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
# ---------------------------------------------
# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
@ -13885,6 +14065,53 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
fi
# The cast to long int works around a bug in the HP C Compiler
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
# This bug is HP SR number 8606223364.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of time_t" >&5
$as_echo_n "checking size of time_t... " >&6; }
if ${ac_cv_sizeof_time_t+:} false; then :
$as_echo_n "(cached) " >&6
else
if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (time_t))" "ac_cv_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
"; then :
else
if test "$ac_cv_type_time_t" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error 77 "cannot compute sizeof (time_t)
See \`config.log' for more details" "$LINENO" 5; }
else
ac_cv_sizeof_time_t=0
fi
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_time_t" >&5
$as_echo "$ac_cv_sizeof_time_t" >&6; }
cat >>confdefs.h <<_ACEOF
#define SIZEOF_TIME_T $ac_cv_sizeof_time_t
_ACEOF
# add option to disable the evil rpath
# Check whether --enable-rpath was given.
@ -17738,7 +17965,7 @@ if test "$ac_res" != no; then :
fi
for ac_func in tzset sigprocmask fcntl getpwnam getrlimit setrlimit setsid sbrk chroot kill sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex
for ac_func in tzset sigprocmask fcntl getpwnam getrlimit setrlimit setsid sbrk chroot kill sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@ -17859,6 +18086,20 @@ esac
fi
ac_fn_c_check_func "$LINENO" "strlcat" "ac_cv_func_strlcat"
if test "x$ac_cv_func_strlcat" = xyes; then :
$as_echo "#define HAVE_STRLCAT 1" >>confdefs.h
else
case " $LIBOBJS " in
*" strlcat.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS strlcat.$ac_objext"
;;
esac
fi
ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy"
if test "x$ac_cv_func_strlcpy" = xyes; then :
$as_echo "#define HAVE_STRLCPY 1" >>confdefs.h
@ -18008,193 +18249,6 @@ fi
# check this after all other compilation checks, since the linking of the lib
# may break checks after this.
# Check whether --with-ldns was given.
if test "${with_ldns+set}" = set; then :
withval=$with_ldns;
if test "$withval" != "yes"; then
if test "$withval" != "/usr" -a "$withval" != ""; then
CPPFLAGS="-I$withval/include $CPPFLAGS"
LDFLAGS="-L$withval/lib $LDFLAGS"
if test "x$enable_rpath" = xyes; then
if echo "$withval/lib" | grep "^/" >/dev/null; then
RUNTIME_PATH="$RUNTIME_PATH -R$withval/lib"
fi
fi
fi
ldnsdir="$withval"
fi
fi
# check if ldns is good enough
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldns_rr_new in -lldns" >&5
$as_echo_n "checking for ldns_rr_new in -lldns... " >&6; }
if ${ac_cv_lib_ldns_ldns_rr_new+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lldns $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char ldns_rr_new ();
int
main ()
{
return ldns_rr_new ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_ldns_ldns_rr_new=yes
else
ac_cv_lib_ldns_ldns_rr_new=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ldns_ldns_rr_new" >&5
$as_echo "$ac_cv_lib_ldns_ldns_rr_new" >&6; }
if test "x$ac_cv_lib_ldns_ldns_rr_new" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBLDNS 1
_ACEOF
LIBS="-lldns $LIBS"
else
as_fn_error $? "No ldns library found, install the ldns library into system lib dir or use --with-ldns=path to other location. The --with-ldns can point to the make-dir of ldns. Install the package ldns or download source http://www.nlnetlabs.nl/projects/ldns" "$LINENO" 5
fi
ac_fn_c_check_func "$LINENO" "ldns_buffer_copy" "ac_cv_func_ldns_buffer_copy"
if test "x$ac_cv_func_ldns_buffer_copy" = xyes; then :
fi
if test $USE_NSS = "no"; then
ac_fn_c_check_func "$LINENO" "ldns_key_buf2rsa_raw" "ac_cv_func_ldns_key_buf2rsa_raw"
if test "x$ac_cv_func_ldns_key_buf2rsa_raw" = xyes; then :
fi
else
ac_cv_func_ldns_key_buf2rsa_raw="yes"
fi
ac_fn_c_check_func "$LINENO" "ldns_get_random" "ac_cv_func_ldns_get_random"
if test "x$ac_cv_func_ldns_get_random" = xyes; then :
fi
ac_fn_c_check_func "$LINENO" "ldns_b32_ntop_extended_hex" "ac_cv_func_ldns_b32_ntop_extended_hex"
if test "x$ac_cv_func_ldns_b32_ntop_extended_hex" = xyes; then :
fi
if test x$use_gost = xyes -a x$USE_NSS = xno; then
ac_fn_c_check_func "$LINENO" "ldns_key_EVP_load_gost_id" "ac_cv_func_ldns_key_EVP_load_gost_id"
if test "x$ac_cv_func_ldns_key_EVP_load_gost_id" = xyes; then :
fi
for ac_func in ldns_key_EVP_unload_gost
do :
ac_fn_c_check_func "$LINENO" "ldns_key_EVP_unload_gost" "ac_cv_func_ldns_key_EVP_unload_gost"
if test "x$ac_cv_func_ldns_key_EVP_unload_gost" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LDNS_KEY_EVP_UNLOAD_GOST 1
_ACEOF
fi
done
else
ac_cv_func_ldns_key_EVP_load_gost_id="yes"
fi
if test x$use_ecdsa = xyes; then
ac_fn_c_check_decl "$LINENO" "LDNS_ECDSAP384SHA384" "ac_cv_have_decl_LDNS_ECDSAP384SHA384" "
$ac_includes_default
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_WS2TCPIP_H
# include <ws2tcpip.h>
#endif
#include <ldns/ldns.h>
"
if test "x$ac_cv_have_decl_LDNS_ECDSAP384SHA384" = xyes; then :
fi
else
ac_cv_have_decl_LDNS_ECDSAP384SHA384="yes"
fi
for ac_header in ldns/ldns.h
do :
ac_fn_c_check_header_compile "$LINENO" "ldns/ldns.h" "ac_cv_header_ldns_ldns_h" "$ac_includes_default
#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
"
if test "x$ac_cv_header_ldns_ldns_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LDNS_LDNS_H 1
_ACEOF
else
as_fn_error $? "No ldns include file found, install the ldns library development files. Install package ldns-dev or ldns-devel or download source http://www.nlnetlabs.nl/projects/ldns" "$LINENO" 5
fi
done
if test $ac_cv_func_ldns_buffer_copy = yes \
-a $ac_cv_func_ldns_key_buf2rsa_raw = yes \
-a $ac_cv_func_ldns_get_random = yes \
-a $ac_cv_header_ldns_ldns_h = yes \
-a $ac_cv_func_ldns_b32_ntop_extended_hex = yes \
-a $ac_cv_func_ldns_key_EVP_load_gost_id = yes \
-a $ac_cv_have_decl_LDNS_ECDSAP384SHA384 = yes; then
:
else
as_fn_error $? "ldns library is not recent, update the ldns library, install it into system lib dir or use --with-ldns=path to other location. The --with-ldns can point to the make-dir of ldns. Package libldns or download source http://www.nlnetlabs.nl/projects/ldns" "$LINENO" 5
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: Stripping extension flags..." >&5
$as_echo "$as_me: Stripping extension flags..." >&6;}

View File

@ -296,6 +296,20 @@ ACX_TYPE_IN_ADDR_T
ACX_TYPE_IN_PORT_T
ACX_CHECK_MEMCMP_SIGNED
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
])
# add option to disable the evil rpath
ACX_ARG_RPATH
AC_SUBST(RUNTIME_PATH)
@ -928,7 +942,7 @@ AC_INCLUDES_DEFAULT
#endif
])
AC_SEARCH_LIBS([setusercontext], [util])
AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam getrlimit setrlimit setsid sbrk chroot kill sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex])
AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam getrlimit setrlimit setsid sbrk chroot kill sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent])
AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])])
AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])])
@ -940,6 +954,7 @@ AC_REPLACE_FUNCS(inet_aton)
AC_REPLACE_FUNCS(inet_pton)
AC_REPLACE_FUNCS(inet_ntop)
AC_REPLACE_FUNCS(snprintf)
AC_REPLACE_FUNCS(strlcat)
AC_REPLACE_FUNCS(strlcpy)
AC_REPLACE_FUNCS(memmove)
AC_REPLACE_FUNCS(gmtime_r)
@ -1025,92 +1040,6 @@ AC_ARG_WITH(libunbound-only, AC_HELP_STRING([--with-libunbound-only],
])
AC_SUBST(ALLTARGET)
# check this after all other compilation checks, since the linking of the lib
# may break checks after this.
AC_ARG_WITH(ldns, AC_HELP_STRING([--with-ldns=PATH],
[specify prefix of path of ldns library to use]),
[
if test "$withval" != "yes"; then
if test "$withval" != "/usr" -a "$withval" != ""; then
CPPFLAGS="-I$withval/include $CPPFLAGS"
LDFLAGS="-L$withval/lib $LDFLAGS"
ACX_RUNTIME_PATH_ADD([$withval/lib])
fi
ldnsdir="$withval"
AC_SUBST(ldnsdir)
fi
])
# check if ldns is good enough
AC_CHECK_LIB(ldns, ldns_rr_new,,[
AC_MSG_ERROR([No ldns library found, install the ldns library into system lib dir or use --with-ldns=path to other location. The --with-ldns can point to the make-dir of ldns. Install the package ldns or download source http://www.nlnetlabs.nl/projects/ldns])
])
AC_CHECK_FUNC(ldns_buffer_copy)
if test $USE_NSS = "no"; then
AC_CHECK_FUNC(ldns_key_buf2rsa_raw)
else
dnl ignore test
ac_cv_func_ldns_key_buf2rsa_raw="yes"
fi
AC_CHECK_FUNC(ldns_get_random)
AC_CHECK_FUNC(ldns_b32_ntop_extended_hex)
if test x$use_gost = xyes -a x$USE_NSS = xno; then
AC_CHECK_FUNC(ldns_key_EVP_load_gost_id)
AC_CHECK_FUNCS([ldns_key_EVP_unload_gost])
else
dnl ignore test
ac_cv_func_ldns_key_EVP_load_gost_id="yes"
fi
if test x$use_ecdsa = xyes; then
AC_CHECK_DECL([LDNS_ECDSAP384SHA384], [], [], [
AC_INCLUDES_DEFAULT
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_WS2TCPIP_H
# include <ws2tcpip.h>
#endif
#include <ldns/ldns.h>
])
else
ac_cv_have_decl_LDNS_ECDSAP384SHA384="yes"
fi
AC_CHECK_HEADERS([ldns/ldns.h],,[
AC_MSG_ERROR([No ldns include file found, install the ldns library development files. Install package ldns-dev or ldns-devel or download source http://www.nlnetlabs.nl/projects/ldns])
], [AC_INCLUDES_DEFAULT
#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
])
if test $ac_cv_func_ldns_buffer_copy = yes \
-a $ac_cv_func_ldns_key_buf2rsa_raw = yes \
-a $ac_cv_func_ldns_get_random = yes \
-a $ac_cv_header_ldns_ldns_h = yes \
-a $ac_cv_func_ldns_b32_ntop_extended_hex = yes \
-a $ac_cv_func_ldns_key_EVP_load_gost_id = yes \
-a $ac_cv_have_decl_LDNS_ECDSAP384SHA384 = yes; then
dnl ldns was found
:
else
AC_MSG_ERROR([ldns library is not recent, update the ldns library, install it into system lib dir or use --with-ldns=path to other location. The --with-ldns can point to the make-dir of ldns. Package libldns or download source http://www.nlnetlabs.nl/projects/ldns])
fi
ACX_STRIP_EXT_FLAGS
LDFLAGS="$LATE_LDFLAGS $LDFLAGS"
@ -1126,6 +1055,12 @@ dnl includes
# define NDEBUG
#endif
/** Use small-ldns codebase */
#define USE_SLDNS 1
#ifdef HAVE_SSL
# define LDNS_BUILD_CONFIG_HAVE_SSL 1
#endif
#include <stdio.h>
#include <string.h>
#include <unistd.h>
@ -1180,6 +1115,7 @@ AHX_CONFIG_INET_PTON(unbound)
AHX_CONFIG_INET_NTOP(unbound)
AHX_CONFIG_INET_ATON(unbound)
AHX_CONFIG_MEMMOVE(unbound)
AHX_CONFIG_STRLCAT(unbound)
AHX_CONFIG_STRLCPY(unbound)
AHX_CONFIG_GMTIME_R(unbound)
AHX_CONFIG_W32_SLEEP

View File

@ -40,7 +40,7 @@
* to text format.
*/
#include "config.h"
#include <ldns/ldns.h>
#include <openssl/ssl.h>
#include "daemon/cachedump.h"
#include "daemon/remote.h"
#include "daemon/worker.h"
@ -56,64 +56,19 @@
#include "iterator/iter_utils.h"
#include "iterator/iter_fwd.h"
#include "iterator/iter_hints.h"
/** convert to ldns rr */
static ldns_rr*
to_rr(struct ub_packed_rrset_key* k, struct packed_rrset_data* d,
time_t now, size_t i, uint16_t type)
{
ldns_rr* rr = ldns_rr_new();
ldns_rdf* rdf;
ldns_status status;
size_t pos;
log_assert(i < d->count + d->rrsig_count);
if(!rr) {
return NULL;
}
ldns_rr_set_type(rr, type);
ldns_rr_set_class(rr, ntohs(k->rk.rrset_class));
if(d->rr_ttl[i] < now)
ldns_rr_set_ttl(rr, 0);
else ldns_rr_set_ttl(rr, d->rr_ttl[i] - now);
pos = 0;
status = ldns_wire2dname(&rdf, k->rk.dname, k->rk.dname_len, &pos);
if(status != LDNS_STATUS_OK) {
/* we drop detailed error in status */
ldns_rr_free(rr);
return NULL;
}
ldns_rr_set_owner(rr, rdf);
pos = 0;
status = ldns_wire2rdf(rr, d->rr_data[i], d->rr_len[i], &pos);
if(status != LDNS_STATUS_OK) {
/* we drop detailed error in status */
ldns_rr_free(rr);
return NULL;
}
return rr;
}
#include "ldns/sbuffer.h"
#include "ldns/wire2str.h"
#include "ldns/str2wire.h"
/** dump one rrset zonefile line */
static int
dump_rrset_line(SSL* ssl, struct ub_packed_rrset_key* k,
struct packed_rrset_data* d, time_t now, size_t i, uint16_t type)
dump_rrset_line(SSL* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i)
{
char* s;
ldns_rr* rr = to_rr(k, d, now, i, type);
if(!rr) {
char s[65535];
if(!packed_rr_to_string(k, i, now, s, sizeof(s))) {
return ssl_printf(ssl, "BADRR\n");
}
s = ldns_rr2str(rr);
ldns_rr_free(rr);
if(!s) {
return ssl_printf(ssl, "BADRR\n");
}
if(!ssl_printf(ssl, "%s", s)) {
free(s);
return 0;
}
free(s);
return 1;
return ssl_printf(ssl, "%s\n", s);
}
/** dump rrset key and data info */
@ -134,16 +89,10 @@ dump_rrset(SSL* ssl, struct ub_packed_rrset_key* k,
(int)d->trust, (int)d->security
))
return 0;
for(i=0; i<d->count; i++) {
if(!dump_rrset_line(ssl, k, d, now, i, ntohs(k->rk.type)))
for(i=0; i<d->count + d->rrsig_count; i++) {
if(!dump_rrset_line(ssl, k, now, i))
return 0;
}
for(i=0; i<d->rrsig_count; i++) {
if(!dump_rrset_line(ssl, k, d, now, i+d->count,
LDNS_RR_TYPE_RRSIG))
return 0;
}
return 1;
}
@ -189,20 +138,10 @@ dump_rrset_cache(SSL* ssl, struct worker* worker)
static int
dump_msg_ref(SSL* ssl, struct ub_packed_rrset_key* k)
{
ldns_rdf* rdf;
ldns_status status;
size_t pos;
char* nm, *tp, *cl;
pos = 0;
status = ldns_wire2dname(&rdf, k->rk.dname, k->rk.dname_len, &pos);
if(status != LDNS_STATUS_OK) {
return ssl_printf(ssl, "BADREF\n");
}
nm = ldns_rdf2str(rdf);
ldns_rdf_deep_free(rdf);
tp = ldns_rr_type2str(ntohs(k->rk.type));
cl = ldns_rr_class2str(ntohs(k->rk.rrset_class));
nm = ldns_wire2str_dname(k->rk.dname, k->rk.dname_len);
tp = ldns_wire2str_type(ntohs(k->rk.type));
cl = ldns_wire2str_class(ntohs(k->rk.rrset_class));
if(!nm || !cl || !tp) {
free(nm);
free(tp);
@ -229,21 +168,12 @@ dump_msg(SSL* ssl, struct query_info* k, struct reply_info* d,
{
size_t i;
char* nm, *tp, *cl;
ldns_rdf* rdf;
ldns_status status;
size_t pos;
if(!k || !d) return 1;
if(d->ttl < now) return 1; /* expired */
pos = 0;
status = ldns_wire2dname(&rdf, k->qname, k->qname_len, &pos);
if(status != LDNS_STATUS_OK) {
return 1; /* skip this entry */
}
nm = ldns_rdf2str(rdf);
ldns_rdf_deep_free(rdf);
tp = ldns_rr_type2str(k->qtype);
cl = ldns_rr_class2str(k->qclass);
nm = ldns_wire2str_dname(k->qname, k->qname_len);
tp = ldns_wire2str_type(k->qtype);
cl = ldns_wire2str_class(k->qclass);
if(!nm || !tp || !cl) {
free(nm);
free(tp);
@ -389,8 +319,9 @@ load_rr(SSL* ssl, ldns_buffer* buf, struct regional* region,
struct ub_packed_rrset_key* rk, struct packed_rrset_data* d,
unsigned int i, int is_rrsig, int* go_on, time_t now)
{
ldns_rr* rr;
ldns_status status;
uint8_t rr[LDNS_RR_BUF_SIZE];
size_t rr_len = sizeof(rr), dname_len = 0;
int status;
/* read the line */
if(!ssl_read_buf(ssl, buf))
@ -399,66 +330,43 @@ load_rr(SSL* ssl, ldns_buffer* buf, struct regional* region,
*go_on = 0;
return 1;
}
status = ldns_rr_new_frm_str(&rr, (char*)ldns_buffer_begin(buf),
LDNS_DEFAULT_TTL, NULL, NULL);
if(status != LDNS_STATUS_OK) {
status = ldns_str2wire_rr_buf((char*)ldns_buffer_begin(buf), rr,
&rr_len, &dname_len, 3600, NULL, 0, NULL, 0);
if(status != 0) {
log_warn("error cannot parse rr: %s: %s",
ldns_get_errorstr_by_id(status),
ldns_get_errorstr_parse(status),
(char*)ldns_buffer_begin(buf));
return 0;
}
if(is_rrsig && ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG) {
if(is_rrsig && ldns_wirerr_get_type(rr, rr_len, dname_len)
!= LDNS_RR_TYPE_RRSIG) {
log_warn("error expected rrsig but got %s",
(char*)ldns_buffer_begin(buf));
return 0;
}
/* convert ldns rr into packed_rr */
d->rr_ttl[i] = ldns_rr_ttl(rr) + now;
d->rr_ttl[i] = (time_t)ldns_wirerr_get_ttl(rr, rr_len, dname_len) + now;
ldns_buffer_clear(buf);
ldns_buffer_skip(buf, 2);
status = ldns_rr_rdata2buffer_wire(buf, rr);
if(status != LDNS_STATUS_OK) {
log_warn("error cannot rr2wire: %s",
ldns_get_errorstr_by_id(status));
ldns_rr_free(rr);
return 0;
}
ldns_buffer_flip(buf);
ldns_buffer_write_u16_at(buf, 0, ldns_buffer_limit(buf) - 2);
d->rr_len[i] = ldns_buffer_limit(buf);
d->rr_len[i] = ldns_wirerr_get_rdatalen(rr, rr_len, dname_len)+2;
d->rr_data[i] = (uint8_t*)regional_alloc_init(region,
ldns_buffer_begin(buf), ldns_buffer_limit(buf));
ldns_wirerr_get_rdatawl(rr, rr_len, dname_len), d->rr_len[i]);
if(!d->rr_data[i]) {
ldns_rr_free(rr);
log_warn("error out of memory");
return 0;
}
/* if first entry, fill the key structure */
if(i==0) {
rk->rk.type = htons(ldns_rr_get_type(rr));
rk->rk.rrset_class = htons(ldns_rr_get_class(rr));
ldns_buffer_clear(buf);
status = ldns_dname2buffer_wire(buf, ldns_rr_owner(rr));
if(status != LDNS_STATUS_OK) {
log_warn("error cannot dname2buffer: %s",
ldns_get_errorstr_by_id(status));
ldns_rr_free(rr);
return 0;
}
ldns_buffer_flip(buf);
rk->rk.dname_len = ldns_buffer_limit(buf);
rk->rk.dname = regional_alloc_init(region,
ldns_buffer_begin(buf), ldns_buffer_limit(buf));
rk->rk.type = htons(ldns_wirerr_get_type(rr, rr_len, dname_len));
rk->rk.rrset_class = htons(ldns_wirerr_get_class(rr, rr_len, dname_len));
rk->rk.dname_len = dname_len;
rk->rk.dname = regional_alloc_init(region, rr, dname_len);
if(!rk->rk.dname) {
log_warn("error out of memory");
ldns_rr_free(rr);
return 0;
}
}
ldns_rr_free(rr);
return 1;
}
@ -618,13 +526,13 @@ load_rrset_cache(SSL* ssl, struct worker* worker)
/** read qinfo from next three words */
static char*
load_qinfo(char* str, struct query_info* qinfo, ldns_buffer* buf,
struct regional* region)
load_qinfo(char* str, struct query_info* qinfo, struct regional* region)
{
/* s is part of the buf */
char* s = str;
ldns_rr* rr;
ldns_status status;
uint8_t rr[LDNS_RR_BUF_SIZE];
size_t rr_len = sizeof(rr), dname_len = 0;
int status;
/* skip three words */
s = strchr(str, ' ');
@ -638,26 +546,17 @@ load_qinfo(char* str, struct query_info* qinfo, ldns_buffer* buf,
s++;
/* parse them */
status = ldns_rr_new_question_frm_str(&rr, str, NULL, NULL);
if(status != LDNS_STATUS_OK) {
status = ldns_str2wire_rr_question_buf(str, rr, &rr_len, &dname_len,
NULL, 0, NULL, 0);
if(status != 0) {
log_warn("error cannot parse: %s %s",
ldns_get_errorstr_by_id(status), str);
ldns_get_errorstr_parse(status), str);
return NULL;
}
qinfo->qtype = ldns_rr_get_type(rr);
qinfo->qclass = ldns_rr_get_class(rr);
ldns_buffer_clear(buf);
status = ldns_dname2buffer_wire(buf, ldns_rr_owner(rr));
ldns_rr_free(rr);
if(status != LDNS_STATUS_OK) {
log_warn("error cannot dname2wire: %s",
ldns_get_errorstr_by_id(status));
return NULL;
}
ldns_buffer_flip(buf);
qinfo->qname_len = ldns_buffer_limit(buf);
qinfo->qname = (uint8_t*)regional_alloc_init(region,
ldns_buffer_begin(buf), ldns_buffer_limit(buf));
qinfo->qtype = ldns_wirerr_get_type(rr, rr_len, dname_len);
qinfo->qclass = ldns_wirerr_get_class(rr, rr_len, dname_len);
qinfo->qname_len = dname_len;
qinfo->qname = (uint8_t*)regional_alloc_init(region, rr, dname_len);
if(!qinfo->qname) {
log_warn("error out of memory");
return NULL;
@ -685,7 +584,7 @@ load_ref(SSL* ssl, ldns_buffer* buf, struct worker* worker,
return 1;
}
s = load_qinfo(s, &qinfo, buf, region);
s = load_qinfo(s, &qinfo, region);
if(!s) {
return 0;
}
@ -731,7 +630,7 @@ load_msg(SSL* ssl, ldns_buffer* buf, struct worker* worker)
return 0;
}
s += 4;
s = load_qinfo(s, &qinf, buf, region);
s = load_qinfo(s, &qinf, region);
if(!s) {
return 0;
}

View File

@ -61,7 +61,6 @@
#include "nss.h"
#endif
#include <ldns/ldns.h>
#include "daemon/daemon.h"
#include "daemon/worker.h"
#include "daemon/remote.h"
@ -80,6 +79,7 @@
#include "util/random.h"
#include "util/tube.h"
#include "util/net_help.h"
#include "ldns/keyraw.h"
#include <signal.h>
/** How many quit requests happened. */

View File

@ -47,7 +47,6 @@
#include <openssl/err.h>
#endif
#include <ctype.h>
#include <ldns/ldns.h>
#include "daemon/remote.h"
#include "daemon/worker.h"
#include "daemon/daemon.h"
@ -75,6 +74,10 @@
#include "iterator/iter_delegpt.h"
#include "services/outbound_list.h"
#include "services/outside_network.h"
#include "ldns/str2wire.h"
#include "ldns/parseutil.h"
#include "ldns/wire2str.h"
#include "ldns/sbuffer.h"
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
@ -912,17 +915,20 @@ do_stats(SSL* ssl, struct daemon_remote* rc, int reset)
static int
parse_arg_name(SSL* ssl, char* str, uint8_t** res, size_t* len, int* labs)
{
ldns_rdf* rdf;
uint8_t nm[LDNS_MAX_DOMAINLEN+1];
size_t nmlen = sizeof(nm);
int status;
*res = NULL;
*len = 0;
*labs = 0;
rdf = ldns_dname_new_frm_str(str);
if(!rdf) {
ssl_printf(ssl, "error cannot parse name %s\n", str);
status = ldns_str2wire_dname_buf(str, nm, &nmlen);
if(status != 0) {
ssl_printf(ssl, "error cannot parse name %s at %d: %s\n", str,
LDNS_WIREPARSE_OFFSET(status),
ldns_get_errorstr_parse(status));
return 0;
}
*res = memdup(ldns_rdf_data(rdf), ldns_rdf_size(rdf));
ldns_rdf_deep_free(rdf);
*res = memdup(nm, nmlen);
if(!*res) {
ssl_printf(ssl, "error out of memory\n");
return 0;
@ -1022,8 +1028,7 @@ do_zone_remove(SSL* ssl, struct worker* worker, char* arg)
static void
do_data_add(SSL* ssl, struct worker* worker, char* arg)
{
if(!local_zones_add_RR(worker->daemon->local_zones, arg,
worker->env.scratch_buffer)) {
if(!local_zones_add_RR(worker->daemon->local_zones, arg)) {
ssl_printf(ssl,"error in syntax or out of memory, %s\n", arg);
return;
}
@ -1388,9 +1393,9 @@ ssl_print_name_dp(SSL* ssl, char* str, uint8_t* nm, uint16_t dclass,
struct delegpt_addr* a;
int f = 0;
if(str) { /* print header for forward, stub */
char* c = ldns_rr_class2str(dclass);
char* c = ldns_wire2str_class(dclass);
dname_str(nm, buf);
if(!ssl_printf(ssl, "%s %s %s: ", buf, c, str)) {
if(!ssl_printf(ssl, "%s %s %s: ", buf, (c?c:"CLASS??"), str)) {
free(c);
return 0;
}
@ -1780,10 +1785,11 @@ get_mesh_status(struct mesh_area* mesh, struct mesh_state* m,
if(m->sub_set.count == 0)
snprintf(buf, len, " (empty_list)");
RBTREE_FOR(sub, struct mesh_state_ref*, &m->sub_set) {
char* t = ldns_rr_type2str(sub->s->s.qinfo.qtype);
char* c = ldns_rr_class2str(sub->s->s.qinfo.qclass);
char* t = ldns_wire2str_type(sub->s->s.qinfo.qtype);
char* c = ldns_wire2str_class(sub->s->s.qinfo.qclass);
dname_str(sub->s->s.qinfo.qname, nm);
snprintf(buf, len, " %s %s %s", t, c, nm);
snprintf(buf, len, " %s %s %s", (t?t:"TYPE??"),
(c?c:"CLASS??"), nm);
l = strlen(buf);
buf += l; len -= l;
free(t);
@ -1812,13 +1818,14 @@ do_dump_requestlist(SSL* ssl, struct worker* worker)
mesh = worker->env.mesh;
if(!mesh) return;
RBTREE_FOR(m, struct mesh_state*, &mesh->all) {
char* t = ldns_rr_type2str(m->s.qinfo.qtype);
char* c = ldns_rr_class2str(m->s.qinfo.qclass);
char* t = ldns_wire2str_type(m->s.qinfo.qtype);
char* c = ldns_wire2str_class(m->s.qinfo.qclass);
dname_str(m->s.qinfo.qname, buf);
get_mesh_age(m, timebuf, sizeof(timebuf), &worker->env);
get_mesh_status(mesh, m, statbuf, sizeof(statbuf));
if(!ssl_printf(ssl, "%3d %4s %2s %s %s %s\n",
num, t, c, buf, timebuf, statbuf)) {
num, (t?t:"TYPE??"), (c?c:"CLASS??"), buf, timebuf,
statbuf)) {
free(t);
free(c);
return;
@ -1978,17 +1985,25 @@ do_list_local_data(SSL* ssl, struct worker* worker)
struct local_zone* z;
struct local_data* d;
struct local_rrset* p;
char* s = (char*)ldns_buffer_begin(worker->env.scratch_buffer);
size_t slen = ldns_buffer_capacity(worker->env.scratch_buffer);
lock_quick_lock(&zones->lock);
RBTREE_FOR(z, struct local_zone*, &zones->ztree) {
lock_rw_rdlock(&z->lock);
RBTREE_FOR(d, struct local_data*, &z->data) {
for(p = d->rrsets; p; p = p->next) {
ldns_rr_list* rr = packed_rrset_to_rr_list(
p->rrset, worker->env.scratch_buffer);
char* str = ldns_rr_list2str(rr);
(void)ssl_printf(ssl, "%s", str);
free(str);
ldns_rr_list_free(rr);
struct packed_rrset_data* d =
(struct packed_rrset_data*)p->rrset->entry.data;
size_t i;
for(i=0; i<d->count + d->rrsig_count; i++) {
if(!packed_rr_to_string(p->rrset, i,
0, s, slen)) {
if(!ssl_printf(ssl, "BADRR\n"))
return;
}
if(!ssl_printf(ssl, "%s\n", s))
return;
}
}
}
lock_rw_unlock(&z->lock);

View File

@ -40,7 +40,6 @@
* numbers. These 'statistics' may be of interest to the operator.
*/
#include "config.h"
#include <ldns/wire2host.h>
#include "daemon/stats.h"
#include "daemon/worker.h"
#include "daemon/daemon.h"
@ -51,6 +50,7 @@
#include "util/timehist.h"
#include "util/net_help.h"
#include "validator/validator.h"
#include "ldns/sbuffer.h"
/** add timers and the values do not overflow or become negative */
static void

View File

@ -43,12 +43,12 @@
#ifndef DAEMON_STATS_H
#define DAEMON_STATS_H
#include "util/timehist.h"
#include <ldns/buffer.h>
struct worker;
struct config_file;
struct comm_point;
struct comm_reply;
struct edns_data;
struct ldns_buffer;
/** number of qtype that is stored for in array */
#define STATS_QTYPE_NUM 256
@ -230,6 +230,6 @@ void server_stats_insquery(struct server_stats* stats, struct comm_point* c,
* @param stats: the stats
* @param buf: buffer with rcode. If buffer is length0: not counted.
*/
void server_stats_insrcode(struct server_stats* stats, ldns_buffer* buf);
void server_stats_insrcode(struct server_stats* stats, struct ldns_buffer* buf);
#endif /* DAEMON_STATS_H */

View File

@ -162,8 +162,8 @@ static void usage()
#endif
printf("Version %s\n", PACKAGE_VERSION);
get_event_sys(&evnm, &evsys, &evmethod);
printf("linked libs: %s %s (it uses %s), ldns %s, %s\n",
evnm, evsys, evmethod, ldns_version(),
printf("linked libs: %s %s (it uses %s), %s\n",
evnm, evsys, evmethod,
#ifdef HAVE_SSL
SSLeay_version(SSLEAY_VERSION)
#elif defined(HAVE_NSS)

View File

@ -40,7 +40,6 @@
* pending requests.
*/
#include "config.h"
#include <ldns/wire2host.h>
#include "util/log.h"
#include "util/net_help.h"
#include "util/random.h"
@ -70,6 +69,7 @@
#include "iterator/iter_hints.h"
#include "validator/autotrust.h"
#include "validator/val_anchor.h"
#include "ldns/sbuffer.h"
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>

View File

@ -3,6 +3,8 @@
interface port 53 can be used at the same time, and one of the
daemons is unbound.
- iana portlist update.
- separate ldns into core ldns inside ldns/ subdirectory. No more
--with-ldns is needed and unbound does not rely on libldns.
22 Oct 2013: Wouter
- Patch from Neel Goyal: Add an API call to set an event base on an

View File

@ -47,6 +47,8 @@
#include "util/data/packed_rrset.h"
#include "util/data/msgreply.h"
#include "util/net_help.h"
#include "ldns/rrdef.h"
#include "ldns/sbuffer.h"
struct delegpt*
delegpt_create(struct regional* region)

View File

@ -40,15 +40,14 @@
* Keep track of forward zones and config settings.
*/
#include "config.h"
#include <ldns/rdata.h>
#include <ldns/dname.h>
#include <ldns/rr.h>
#include "iterator/iter_fwd.h"
#include "iterator/iter_delegpt.h"
#include "util/log.h"
#include "util/config_file.h"
#include "util/net_help.h"
#include "util/data/dname.h"
#include "ldns/rrdef.h"
#include "ldns/str2wire.h"
int
fwd_cmp(const void* k1, const void* k2)
@ -180,22 +179,23 @@ static struct delegpt*
read_fwds_name(struct config_stub* s)
{
struct delegpt* dp;
ldns_rdf* rdf;
uint8_t* dname;
size_t dname_len;
if(!s->name) {
log_err("forward zone without a name (use name \".\" to forward everything)");
return NULL;
}
rdf = ldns_dname_new_frm_str(s->name);
if(!rdf) {
dname = ldns_str2wire_dname(s->name, &dname_len);
if(!dname) {
log_err("cannot parse forward zone name %s", s->name);
return NULL;
}
if(!(dp=delegpt_create_mlc(ldns_rdf_data(rdf)))) {
ldns_rdf_deep_free(rdf);
if(!(dp=delegpt_create_mlc(dname))) {
free(dname);
log_err("out of memory");
return NULL;
}
ldns_rdf_deep_free(rdf);
free(dname);
return dp;
}
@ -204,21 +204,22 @@ static int
read_fwds_host(struct config_stub* s, struct delegpt* dp)
{
struct config_strlist* p;
ldns_rdf* rdf;
uint8_t* dname;
size_t dname_len;
for(p = s->hosts; p; p = p->next) {
log_assert(p->str);
rdf = ldns_dname_new_frm_str(p->str);
if(!rdf) {
dname = ldns_str2wire_dname(p->str, &dname_len);
if(!dname) {
log_err("cannot parse forward %s server name: '%s'",
s->name, p->str);
return 0;
}
if(!delegpt_add_ns_mlc(dp, ldns_rdf_data(rdf), 0)) {
ldns_rdf_deep_free(rdf);
if(!delegpt_add_ns_mlc(dp, dname, 0)) {
free(dname);
log_err("out of memory");
return 0;
}
ldns_rdf_deep_free(rdf);
free(dname);
}
return 1;
}
@ -290,19 +291,20 @@ static int
make_stub_holes(struct iter_forwards* fwd, struct config_file* cfg)
{
struct config_stub* s;
uint8_t* dname;
size_t dname_len;
for(s = cfg->stubs; s; s = s->next) {
ldns_rdf* rdf = ldns_dname_new_frm_str(s->name);
if(!rdf) {
dname = ldns_str2wire_dname(s->name, &dname_len);
if(!dname) {
log_err("cannot parse stub name '%s'", s->name);
return 0;
}
if(!fwd_add_stub_hole(fwd, LDNS_RR_CLASS_IN,
ldns_rdf_data(rdf))) {
ldns_rdf_deep_free(rdf);
if(!fwd_add_stub_hole(fwd, LDNS_RR_CLASS_IN, dname)) {
free(dname);
log_err("out of memory");
return 0;
}
ldns_rdf_deep_free(rdf);
free(dname);
}
return 1;
}

View File

@ -40,14 +40,15 @@
* Keep track of stub and root hints, and read those from config.
*/
#include "config.h"
#include <ldns/dname.h>
#include <ldns/rr.h>
#include "iterator/iter_hints.h"
#include "iterator/iter_delegpt.h"
#include "util/log.h"
#include "util/config_file.h"
#include "util/net_help.h"
#include "util/data/dname.h"
#include "ldns/rrdef.h"
#include "ldns/str2wire.h"
#include "ldns/wire2str.h"
struct iter_hints*
hints_create(void)
@ -92,19 +93,20 @@ ah(struct delegpt* dp, const char* sv, const char* ip)
{
struct sockaddr_storage addr;
socklen_t addrlen;
ldns_rdf* rdf = ldns_dname_new_frm_str(sv);
if(!rdf) {
size_t dname_len;
uint8_t* dname = ldns_str2wire_dname(sv, &dname_len);
if(!dname) {
log_err("could not parse %s", sv);
return 0;
}
if(!delegpt_add_ns_mlc(dp, ldns_rdf_data(rdf), 0) ||
if(!delegpt_add_ns_mlc(dp, dname, 0) ||
!extstrtoaddr(ip, &addr, &addrlen) ||
!delegpt_add_target_mlc(dp, ldns_rdf_data(rdf), ldns_rdf_size(rdf),
!delegpt_add_target_mlc(dp, dname, dname_len,
&addr, addrlen, 0, 0)) {
ldns_rdf_deep_free(rdf);
free(dname);
return 0;
}
ldns_rdf_deep_free(rdf);
free(dname);
return 1;
}
@ -186,22 +188,23 @@ static struct delegpt*
read_stubs_name(struct config_stub* s)
{
struct delegpt* dp;
ldns_rdf* rdf;
size_t dname_len;
uint8_t* dname;
if(!s->name) {
log_err("stub zone without a name");
return NULL;
}
rdf = ldns_dname_new_frm_str(s->name);
if(!rdf) {
dname = ldns_str2wire_dname(s->name, &dname_len);
if(!dname) {
log_err("cannot parse stub zone name %s", s->name);
return NULL;
}
if(!(dp=delegpt_create_mlc(ldns_rdf_data(rdf)))) {
ldns_rdf_deep_free(rdf);
if(!(dp=delegpt_create_mlc(dname))) {
free(dname);
log_err("out of memory");
return NULL;
}
ldns_rdf_deep_free(rdf);
free(dname);
return dp;
}
@ -210,21 +213,22 @@ static int
read_stubs_host(struct config_stub* s, struct delegpt* dp)
{
struct config_strlist* p;
ldns_rdf* rdf;
size_t dname_len;
uint8_t* dname;
for(p = s->hosts; p; p = p->next) {
log_assert(p->str);
rdf = ldns_dname_new_frm_str(p->str);
if(!rdf) {
dname = ldns_str2wire_dname(p->str, &dname_len);
if(!dname) {
log_err("cannot parse stub %s nameserver name: '%s'",
s->name, p->str);
return 0;
}
if(!delegpt_add_ns_mlc(dp, ldns_rdf_data(rdf), 0)) {
ldns_rdf_deep_free(rdf);
if(!delegpt_add_ns_mlc(dp, dname, 0)) {
free(dname);
log_err("out of memory");
return 0;
}
ldns_rdf_deep_free(rdf);
free(dname);
}
return 1;
}
@ -279,13 +283,11 @@ read_stubs(struct iter_hints* hints, struct config_file* cfg)
static int
read_root_hints(struct iter_hints* hints, char* fname)
{
int lineno = 0;
uint32_t default_ttl = 0;
ldns_rdf* origin = NULL;
ldns_rdf* prev_rr = NULL;
struct ldns_file_parse_state pstate;
struct delegpt* dp;
ldns_rr* rr = NULL;
ldns_status status;
uint8_t rr[LDNS_RR_BUF_SIZE];
size_t rr_len, dname_len;
int status;
uint16_t c = LDNS_RR_CLASS_IN;
FILE* f = fopen(fname, "r");
if(!f) {
@ -300,77 +302,78 @@ read_root_hints(struct iter_hints* hints, char* fname)
return 0;
}
verbose(VERB_QUERY, "Reading root hints from %s", fname);
memset(&pstate, 0, sizeof(pstate));
pstate.lineno = 1;
dp->has_parent_side_NS = 1;
while(!feof(f)) {
status = ldns_rr_new_frm_fp_l(&rr, f,
&default_ttl, &origin, &prev_rr, &lineno);
if(status == LDNS_STATUS_SYNTAX_EMPTY ||
status == LDNS_STATUS_SYNTAX_TTL ||
status == LDNS_STATUS_SYNTAX_ORIGIN)
continue;
if(status != LDNS_STATUS_OK) {
log_err("reading root hints %s %d: %s", fname,
lineno, ldns_get_errorstr_by_id(status));
rr_len = sizeof(rr);
dname_len = 0;
status = ldns_fp2wire_rr_buf(f, rr, &rr_len, &dname_len,
&pstate);
if(status != 0) {
log_err("reading root hints %s %d:%d: %s", fname,
pstate.lineno, LDNS_WIREPARSE_OFFSET(status),
ldns_get_errorstr_parse(status));
goto stop_read;
}
if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_NS) {
if(!delegpt_add_ns_mlc(dp,
ldns_rdf_data(ldns_rr_rdf(rr, 0)), 0)) {
if(rr_len == 0)
continue; /* EMPTY line, TTL or ORIGIN */
if(ldns_wirerr_get_type(rr, rr_len, dname_len)
== LDNS_RR_TYPE_NS) {
if(!delegpt_add_ns_mlc(dp, ldns_wirerr_get_rdata(rr,
rr_len, dname_len), 0)) {
log_err("out of memory reading root hints");
goto stop_read;
}
c = ldns_rr_get_class(rr);
c = ldns_wirerr_get_class(rr, rr_len, dname_len);
if(!dp->name) {
if(!delegpt_set_name_mlc(dp,
ldns_rdf_data(ldns_rr_owner(rr)))){
if(!delegpt_set_name_mlc(dp, rr)) {
log_err("out of memory.");
goto stop_read;
}
}
} else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_A) {
} else if(ldns_wirerr_get_type(rr, rr_len, dname_len)
== LDNS_RR_TYPE_A && ldns_wirerr_get_rdatalen(rr,
rr_len, dname_len) == INET_SIZE) {
struct sockaddr_in sa;
socklen_t len = (socklen_t)sizeof(sa);
memset(&sa, 0, len);
sa.sin_family = AF_INET;
sa.sin_port = (in_port_t)htons(UNBOUND_DNS_PORT);
memmove(&sa.sin_addr,
ldns_rdf_data(ldns_rr_rdf(rr, 0)), INET_SIZE);
if(!delegpt_add_target_mlc(dp,
ldns_rdf_data(ldns_rr_owner(rr)),
ldns_rdf_size(ldns_rr_owner(rr)),
ldns_wirerr_get_rdata(rr, rr_len, dname_len),
INET_SIZE);
if(!delegpt_add_target_mlc(dp, rr, dname_len,
(struct sockaddr_storage*)&sa, len,
0, 0)) {
log_err("out of memory reading root hints");
goto stop_read;
}
} else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_AAAA) {
} else if(ldns_wirerr_get_type(rr, rr_len, dname_len)
== LDNS_RR_TYPE_AAAA && ldns_wirerr_get_rdatalen(rr,
rr_len, dname_len) == INET6_SIZE) {
struct sockaddr_in6 sa;
socklen_t len = (socklen_t)sizeof(sa);
memset(&sa, 0, len);
sa.sin6_family = AF_INET6;
sa.sin6_port = (in_port_t)htons(UNBOUND_DNS_PORT);
memmove(&sa.sin6_addr,
ldns_rdf_data(ldns_rr_rdf(rr, 0)), INET6_SIZE);
if(!delegpt_add_target_mlc(dp,
ldns_rdf_data(ldns_rr_owner(rr)),
ldns_rdf_size(ldns_rr_owner(rr)),
ldns_wirerr_get_rdata(rr, rr_len, dname_len),
INET6_SIZE);
if(!delegpt_add_target_mlc(dp, rr, dname_len,
(struct sockaddr_storage*)&sa, len,
0, 0)) {
log_err("out of memory reading root hints");
goto stop_read;
}
} else {
log_warn("root hints %s:%d skipping type %d",
fname, lineno, ldns_rr_get_type(rr));
char buf[17];
ldns_wire2str_type_buf(ldns_wirerr_get_type(rr,
rr_len, dname_len), buf, sizeof(buf));
log_warn("root hints %s:%d skipping type %s",
fname, pstate.lineno, buf);
}
ldns_rr_free(rr);
}
if (origin)
ldns_rdf_deep_free(origin);
if (prev_rr)
ldns_rdf_deep_free(prev_rr);
fclose(f);
if(!dp->name) {
log_warn("root hints %s: no NS content", fname);
@ -384,10 +387,6 @@ read_root_hints(struct iter_hints* hints, char* fname)
return 1;
stop_read:
if (origin)
ldns_rdf_deep_free(origin);
if (prev_rr)
ldns_rdf_deep_free(prev_rr);
delegpt_free_mlc(dp);
fclose(f);
return 0;

View File

@ -41,7 +41,6 @@
*/
#include "config.h"
#include <ldns/dname.h>
#include "iterator/iter_priv.h"
#include "util/regional.h"
#include "util/log.h"
@ -50,6 +49,8 @@
#include "util/data/msgparse.h"
#include "util/net_help.h"
#include "util/storage/dnstree.h"
#include "ldns/str2wire.h"
#include "ldns/sbuffer.h"
struct iter_priv* priv_create(void)
{
@ -110,23 +111,21 @@ static int read_names(struct iter_priv* priv, struct config_file* cfg)
/* parse names, report errors, insert into tree */
struct config_strlist* p;
struct name_tree_node* n;
uint8_t* nm;
uint8_t* nm, *nmr;
size_t nm_len;
int nm_labs;
ldns_rdf* rdf;
for(p = cfg->private_domain; p; p = p->next) {
log_assert(p->str);
rdf = ldns_dname_new_frm_str(p->str);
if(!rdf) {
nm = ldns_str2wire_dname(p->str, &nm_len);
if(!nm) {
log_err("cannot parse private-domain: %s", p->str);
return 0;
}
nm = ldns_rdf_data(rdf);
nm_labs = dname_count_size_labels(nm, &nm_len);
nm = (uint8_t*)regional_alloc_init(priv->region, nm, nm_len);
ldns_rdf_deep_free(rdf);
if(!nm) {
nmr = (uint8_t*)regional_alloc_init(priv->region, nm, nm_len);
free(nm);
if(!nmr) {
log_err("out of memory");
return 0;
}
@ -136,7 +135,7 @@ static int read_names(struct iter_priv* priv, struct config_file* cfg)
log_err("out of memory");
return 0;
}
if(!name_tree_insert(&priv->n, n, nm, nm_len, nm_labs,
if(!name_tree_insert(&priv->n, n, nmr, nm_len, nm_labs,
LDNS_RR_CLASS_IN)) {
verbose(VERB_QUERY, "ignoring duplicate "
"private-domain: %s", p->str);

View File

@ -43,7 +43,7 @@
#ifndef ITERATOR_ITER_PRIV_H
#define ITERATOR_ITER_PRIV_H
#include "util/rbtree.h"
#include <ldns/buffer.h>
struct ldns_buffer;
struct iter_env;
struct config_file;
struct regional;
@ -99,7 +99,7 @@ int priv_apply_cfg(struct iter_priv* priv, struct config_file* cfg);
* @param rrset: the rrset to examine, A or AAAA.
* @return true if the rrset is bad and should be removed.
*/
int priv_rrset_bad(struct iter_priv* priv, ldns_buffer* pkt,
int priv_rrset_bad(struct iter_priv* priv, struct ldns_buffer* pkt,
struct rrset_parse* rrset);
/**

View File

@ -40,12 +40,13 @@
* one of the response types.
*/
#include "config.h"
#include <ldns/packet.h>
#include "iterator/iter_resptype.h"
#include "iterator/iter_delegpt.h"
#include "services/cache/dns.h"
#include "util/net_help.h"
#include "util/data/dname.h"
#include "ldns/rrdef.h"
#include "ldns/pkthdr.h"
enum response_type
response_type_from_cache(struct dns_msg* msg,

View File

@ -53,6 +53,7 @@
#include "util/data/dname.h"
#include "util/data/msgreply.h"
#include "util/alloc.h"
#include "ldns/sbuffer.h"
/** RRset flag used during scrubbing. The RRset is OK. */
#define RRSET_SCRUB_OK 0x80

View File

@ -42,7 +42,7 @@
#ifndef ITERATOR_ITER_SCRUB_H
#define ITERATOR_ITER_SCRUB_H
#include <ldns/buffer.h>
struct ldns_buffer;
struct msg_parse;
struct query_info;
struct regional;
@ -62,7 +62,7 @@ struct iter_env;
* @param ie: iterator module environment data.
* @return: false if the message is total waste. true if scrubbed with success.
*/
int scrub_message(ldns_buffer* pkt, struct msg_parse* msg,
int scrub_message(struct ldns_buffer* pkt, struct msg_parse* msg,
struct query_info* qinfo, uint8_t* zonename, struct regional* regional,
struct module_env* env, struct iter_env* ie);

View File

@ -63,6 +63,8 @@
#include "validator/val_kcache.h"
#include "validator/val_kentry.h"
#include "validator/val_utils.h"
#include "validator/val_sigcrypt.h"
#include "ldns/sbuffer.h"
/** time when nameserver glue is said to be 'recent' */
#define SUSPICION_RECENT_EXPIRY 86400
@ -682,7 +684,7 @@ rrset_equal(struct ub_packed_rrset_key* k1, struct ub_packed_rrset_key* k2)
}
int
reply_equal(struct reply_info* p, struct reply_info* q, ldns_buffer* scratch)
reply_equal(struct reply_info* p, struct reply_info* q, struct regional* region)
{
size_t i;
if(p->flags != q->flags ||
@ -697,27 +699,12 @@ reply_equal(struct reply_info* p, struct reply_info* q, ldns_buffer* scratch)
return 0;
for(i=0; i<p->rrset_count; i++) {
if(!rrset_equal(p->rrsets[i], q->rrsets[i])) {
/* fallback procedure: try to sort and canonicalize */
ldns_rr_list* pl, *ql;
pl = packed_rrset_to_rr_list(p->rrsets[i], scratch);
ql = packed_rrset_to_rr_list(q->rrsets[i], scratch);
if(!pl || !ql) {
ldns_rr_list_deep_free(pl);
ldns_rr_list_deep_free(ql);
if(!rrset_canonical_equal(region, p->rrsets[i],
q->rrsets[i])) {
regional_free_all(region);
return 0;
}
ldns_rr_list2canonical(pl);
ldns_rr_list2canonical(ql);
ldns_rr_list_sort(pl);
ldns_rr_list_sort(ql);
if(ldns_rr_list_compare(pl, ql) != 0) {
ldns_rr_list_deep_free(pl);
ldns_rr_list_deep_free(ql);
return 0;
}
ldns_rr_list_deep_free(pl);
ldns_rr_list_deep_free(ql);
continue;
regional_free_all(region);
}
}
return 1;

View File

@ -43,7 +43,7 @@
#ifndef ITERATOR_ITER_UTILS_H
#define ITERATOR_ITER_UTILS_H
#include "iterator/iter_resptype.h"
#include <ldns/buffer.h>
struct ldns_buffer;
struct iter_env;
struct iter_hints;
struct iter_forwards;
@ -102,7 +102,7 @@ struct delegpt_addr* iter_server_selection(struct iter_env* iter_env,
* @param regional: regional to use for allocation.
* @return newly allocated dns_msg, or NULL on memory error.
*/
struct dns_msg* dns_alloc_msg(ldns_buffer* pkt, struct msg_parse* msg,
struct dns_msg* dns_alloc_msg(struct ldns_buffer* pkt, struct msg_parse* msg,
struct regional* regional);
/**
@ -216,10 +216,10 @@ int iter_msg_from_zone(struct dns_msg* msg, struct delegpt* dp,
* @param p: reply one. The reply has rrset data pointers in region.
* Does not check rrset-IDs
* @param q: reply two
* @param buf: scratch buffer.
* @param region: scratch buffer.
* @return if one and two are equal.
*/
int reply_equal(struct reply_info* p, struct reply_info* q, ldns_buffer* buf);
int reply_equal(struct reply_info* p, struct reply_info* q, struct regional* region);
/**
* Store parent-side rrset in seperate rrset cache entries for later

View File

@ -41,7 +41,6 @@
*/
#include "config.h"
#include <ldns/ldns.h>
#include "iterator/iterator.h"
#include "iterator/iter_utils.h"
#include "iterator/iter_hints.h"
@ -62,6 +61,10 @@
#include "util/data/msgencode.h"
#include "util/fptr_wlist.h"
#include "util/config_file.h"
#include "ldns/rrdef.h"
#include "ldns/wire2str.h"
#include "ldns/parseutil.h"
#include "ldns/sbuffer.h"
int
iter_init(struct module_env* env, int id)
@ -2815,7 +2818,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
} else {
/* check if reply is the same, otherwise, fail */
if(!reply_equal(iq->response->rep, iq->caps_reply,
qstate->env->scratch_buffer)) {
qstate->env->scratch)) {
verbose(VERB_DETAIL, "Capsforid fallback: "
"getting different replies, failed");
outbound_list_remove(&iq->outlist, outbound);

368
ldns/keyraw.c Normal file
View File

@ -0,0 +1,368 @@
/*
* keyraw.c - raw key operations and conversions
*
* (c) NLnet Labs, 2004-2008
*
* See the file LICENSE for the license
*/
/**
* \file
* Implementation of raw DNSKEY functions (work on wire rdata).
*/
#include "config.h"
#include "ldns/keyraw.h"
#include "ldns/rrdef.h"
#ifdef HAVE_SSL
#include <openssl/ssl.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/err.h>
#include <openssl/md5.h>
#ifdef HAVE_OPENSSL_ENGINE_H
# include <openssl/engine.h>
#endif
#endif /* HAVE_SSL */
size_t
ldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
const size_t len, int alg)
{
/* for DSA keys */
uint8_t t;
/* for RSA keys */
uint16_t exp;
uint16_t int16;
switch ((ldns_algorithm)alg) {
case LDNS_DSA:
case LDNS_DSA_NSEC3:
if (len > 0) {
t = keydata[0];
return (64 + t*8)*8;
} else {
return 0;
}
break;
case LDNS_RSAMD5:
case LDNS_RSASHA1:
case LDNS_RSASHA1_NSEC3:
#ifdef USE_SHA2
case LDNS_RSASHA256:
case LDNS_RSASHA512:
#endif
if (len > 0) {
if (keydata[0] == 0) {
/* big exponent */
if (len > 3) {
memmove(&int16, keydata + 1, 2);
exp = ntohs(int16);
return (len - exp - 3)*8;
} else {
return 0;
}
} else {
exp = keydata[0];
return (len-exp-1)*8;
}
} else {
return 0;
}
break;
#ifdef USE_GOST
case LDNS_ECC_GOST:
return 512;
#endif
#ifdef USE_ECDSA
case LDNS_ECDSAP256SHA256:
return 256;
case LDNS_ECDSAP384SHA384:
return 384;
#endif
default:
return 0;
}
}
uint16_t ldns_calc_keytag_raw(uint8_t* key, size_t keysize)
{
if(keysize < 4) {
return 0;
}
/* look at the algorithm field, copied from 2535bis */
if (key[3] == LDNS_RSAMD5) {
uint16_t ac16 = 0;
if (keysize > 4) {
memmove(&ac16, key + keysize - 3, 2);
}
ac16 = ntohs(ac16);
return (uint16_t) ac16;
} else {
size_t i;
uint32_t ac32 = 0;
for (i = 0; i < keysize; ++i) {
ac32 += (i & 1) ? key[i] : key[i] << 8;
}
ac32 += (ac32 >> 16) & 0xFFFF;
return (uint16_t) (ac32 & 0xFFFF);
}
}
#ifdef HAVE_SSL
#ifdef USE_GOST
/** store GOST engine reference loaded into OpenSSL library */
ENGINE* ldns_gost_engine = NULL;
int
ldns_key_EVP_load_gost_id(void)
{
static int gost_id = 0;
const EVP_PKEY_ASN1_METHOD* meth;
ENGINE* e;
if(gost_id) return gost_id;
/* see if configuration loaded gost implementation from other engine*/
meth = EVP_PKEY_asn1_find_str(NULL, "gost2001", -1);
if(meth) {
EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
return gost_id;
}
/* see if engine can be loaded already */
e = ENGINE_by_id("gost");
if(!e) {
/* load it ourself, in case statically linked */
ENGINE_load_builtin_engines();
ENGINE_load_dynamic();
e = ENGINE_by_id("gost");
}
if(!e) {
/* no gost engine in openssl */
return 0;
}
if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
ENGINE_finish(e);
ENGINE_free(e);
return 0;
}
meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1);
if(!meth) {
/* algo not found */
ENGINE_finish(e);
ENGINE_free(e);
return 0;
}
/* Note: do not ENGINE_finish and ENGINE_free the acquired engine
* on some platforms this frees up the meth and unloads gost stuff */
ldns_gost_engine = e;
EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
return gost_id;
}
void ldns_key_EVP_unload_gost(void)
{
if(ldns_gost_engine) {
ENGINE_finish(ldns_gost_engine);
ENGINE_free(ldns_gost_engine);
ldns_gost_engine = NULL;
}
}
#endif /* USE_GOST */
DSA *
ldns_key_buf2dsa_raw(unsigned char* key, size_t len)
{
uint8_t T;
uint16_t length;
uint16_t offset;
DSA *dsa;
BIGNUM *Q; BIGNUM *P;
BIGNUM *G; BIGNUM *Y;
if(len == 0)
return NULL;
T = (uint8_t)key[0];
length = (64 + T * 8);
offset = 1;
if (T > 8) {
return NULL;
}
if(len < (size_t)1 + SHA_DIGEST_LENGTH + 3*length)
return NULL;
Q = BN_bin2bn(key+offset, SHA_DIGEST_LENGTH, NULL);
offset += SHA_DIGEST_LENGTH;
P = BN_bin2bn(key+offset, (int)length, NULL);
offset += length;
G = BN_bin2bn(key+offset, (int)length, NULL);
offset += length;
Y = BN_bin2bn(key+offset, (int)length, NULL);
offset += length;
/* create the key and set its properties */
if(!Q || !P || !G || !Y || !(dsa = DSA_new())) {
BN_free(Q);
BN_free(P);
BN_free(G);
BN_free(Y);
return NULL;
}
#ifndef S_SPLINT_S
dsa->p = P;
dsa->q = Q;
dsa->g = G;
dsa->pub_key = Y;
#endif /* splint */
return dsa;
}
RSA *
ldns_key_buf2rsa_raw(unsigned char* key, size_t len)
{
uint16_t offset;
uint16_t exp;
uint16_t int16;
RSA *rsa;
BIGNUM *modulus;
BIGNUM *exponent;
if (len == 0)
return NULL;
if (key[0] == 0) {
if(len < 3)
return NULL;
memmove(&int16, key+1, 2);
exp = ntohs(int16);
offset = 3;
} else {
exp = key[0];
offset = 1;
}
/* key length at least one */
if(len < (size_t)offset + exp + 1)
return NULL;
/* Exponent */
exponent = BN_new();
if(!exponent) return NULL;
(void) BN_bin2bn(key+offset, (int)exp, exponent);
offset += exp;
/* Modulus */
modulus = BN_new();
if(!modulus) {
BN_free(exponent);
return NULL;
}
/* length of the buffer must match the key length! */
(void) BN_bin2bn(key+offset, (int)(len - offset), modulus);
rsa = RSA_new();
if(!rsa) {
BN_free(exponent);
BN_free(modulus);
return NULL;
}
#ifndef S_SPLINT_S
rsa->n = modulus;
rsa->e = exponent;
#endif /* splint */
return rsa;
}
#ifdef USE_GOST
EVP_PKEY*
ldns_gost2pkey_raw(unsigned char* key, size_t keylen)
{
/* prefix header for X509 encoding */
uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85,
0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85,
0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03,
0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
unsigned char encoded[37+64];
const unsigned char* pp;
if(keylen != 64) {
/* key wrong size */
return NULL;
}
/* create evp_key */
memmove(encoded, asn, 37);
memmove(encoded+37, key, 64);
pp = (unsigned char*)&encoded[0];
return d2i_PUBKEY(NULL, &pp, (int)sizeof(encoded));
}
#endif /* USE_GOST */
#ifdef USE_ECDSA
EVP_PKEY*
ldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
{
unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
const unsigned char* pp = buf;
EVP_PKEY *evp_key;
EC_KEY *ec;
/* check length, which uncompressed must be 2 bignums */
if(algo == LDNS_ECDSAP256SHA256) {
if(keylen != 2*256/8) return NULL;
ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
} else if(algo == LDNS_ECDSAP384SHA384) {
if(keylen != 2*384/8) return NULL;
ec = EC_KEY_new_by_curve_name(NID_secp384r1);
} else ec = NULL;
if(!ec) return NULL;
if(keylen+1 > sizeof(buf))
return NULL; /* sanity check */
/* prepend the 0x02 (from docs) (or actually 0x04 from implementation
* of openssl) for uncompressed data */
buf[0] = POINT_CONVERSION_UNCOMPRESSED;
memmove(buf+1, key, keylen);
if(!o2i_ECPublicKey(&ec, &pp, (int)keylen+1)) {
EC_KEY_free(ec);
return NULL;
}
evp_key = EVP_PKEY_new();
if(!evp_key) {
EC_KEY_free(ec);
return NULL;
}
if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
EVP_PKEY_free(evp_key);
EC_KEY_free(ec);
return NULL;
}
return evp_key;
}
#endif /* USE_ECDSA */
int
ldns_digest_evp(unsigned char* data, unsigned int len, unsigned char* dest,
const EVP_MD* md)
{
EVP_MD_CTX* ctx;
ctx = EVP_MD_CTX_create();
if(!ctx)
return 0;
if(!EVP_DigestInit_ex(ctx, md, NULL) ||
!EVP_DigestUpdate(ctx, data, len) ||
!EVP_DigestFinal_ex(ctx, dest, NULL)) {
EVP_MD_CTX_destroy(ctx);
return 0;
}
EVP_MD_CTX_destroy(ctx);
return 1;
}
#endif /* HAVE_SSL */

112
ldns/keyraw.h Normal file
View File

@ -0,0 +1,112 @@
/*
* keyraw.h -- raw key and signature access and conversion
*
* Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
*
* See LICENSE for the license.
*
*/
/**
* \file
*
* raw key and signature access and conversion
*
* Since those functions heavily rely op cryptographic operations,
* this module is dependent on openssl.
*
*/
#ifndef LDNS_KEYRAW_H
#define LDNS_KEYRAW_H
#ifdef __cplusplus
extern "C" {
#endif
#if LDNS_BUILD_CONFIG_HAVE_SSL
# include <openssl/ssl.h>
# include <openssl/evp.h>
#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
/**
* 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, int alg);
/**
* 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
/**
* 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);
/**
* 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);
/**
* 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);
/**
* 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);
/**
* 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);
#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
#ifdef __cplusplus
}
#endif
#endif /* LDNS_KEYRAW_H */

451
ldns/parse.c Normal file
View File

@ -0,0 +1,451 @@
/*
* a generic (simple) parser. Use to parse rr's, private key
* information and /etc/resolv.conf files
*
* a Net::DNS like library for C
* LibDNS Team @ NLnet Labs
* (c) NLnet Labs, 2005-2006
* See the file LICENSE for the license
*/
#include "config.h"
#include "ldns/parse.h"
#include "ldns/parseutil.h"
#include "ldns/sbuffer.h"
#include <limits.h>
#include <strings.h>
ldns_lookup_table ldns_directive_types[] = {
{ LDNS_DIR_TTL, "$TTL" },
{ LDNS_DIR_ORIGIN, "$ORIGIN" },
{ LDNS_DIR_INCLUDE, "$INCLUDE" },
{ 0, NULL }
};
/* add max_limit here? */
ssize_t
ldns_fget_token(FILE *f, char *token, const char *delim, size_t limit)
{
return ldns_fget_token_l(f, token, delim, limit, NULL);
}
ssize_t
ldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *line_nr)
{
int c, prev_c;
int p; /* 0 -> no parenthese seen, >0 nr of ( seen */
int com, quoted;
char *t;
size_t i;
const char *d;
const char *del;
/* standard delimeters */
if (!delim) {
/* from isspace(3) */
del = LDNS_PARSE_NORMAL;
} else {
del = delim;
}
p = 0;
i = 0;
com = 0;
quoted = 0;
prev_c = 0;
t = token;
if (del[0] == '"') {
quoted = 1;
}
while ((c = getc(f)) != EOF) {
if (c == '\r') /* carriage return */
c = ' ';
if (c == '(' && prev_c != '\\' && !quoted) {
/* this only counts for non-comments */
if (com == 0) {
p++;
}
prev_c = c;
continue;
}
if (c == ')' && prev_c != '\\' && !quoted) {
/* this only counts for non-comments */
if (com == 0) {
p--;
}
prev_c = c;
continue;
}
if (p < 0) {
/* more ) then ( - close off the string */
*t = '\0';
return 0;
}
/* do something with comments ; */
if (c == ';' && quoted == 0) {
if (prev_c != '\\') {
com = 1;
}
}
if (c == '\"' && com == 0 && prev_c != '\\') {
quoted = 1 - quoted;
}
if (c == '\n' && com != 0) {
/* comments */
com = 0;
*t = ' ';
if (line_nr) {
*line_nr = *line_nr + 1;
}
if (p == 0 && i > 0) {
goto tokenread;
} else {
prev_c = c;
continue;
}
}
if (com == 1) {
*t = ' ';
prev_c = c;
continue;
}
if (c == '\n' && p != 0 && t > token) {
/* in parentheses */
if (line_nr) {
*line_nr = *line_nr + 1;
}
*t++ = ' ';
prev_c = c;
continue;
}
/* check if we hit the delim */
for (d = del; *d; d++) {
if (c == *d && i > 0 && prev_c != '\\' && p == 0) {
if (c == '\n' && line_nr) {
*line_nr = *line_nr + 1;
}
goto tokenread;
}
}
if (c != '\0' && c != '\n') {
i++;
}
if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
*t = '\0';
return -1;
}
if (c != '\0' && c != '\n') {
*t++ = c;
}
if (c == '\\' && prev_c == '\\')
prev_c = 0;
else prev_c = c;
}
*t = '\0';
if (c == EOF) {
return (ssize_t)i;
}
if (i == 0) {
/* nothing read */
return -1;
}
if (p != 0) {
return -1;
}
return (ssize_t)i;
tokenread:
ldns_fskipcs_l(f, del, line_nr);
*t = '\0';
if (p != 0) {
return -1;
}
return (ssize_t)i;
}
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)
{
return ldns_fget_keyword_data_l(f, keyword, k_del, data, d_del,
data_limit, NULL);
}
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)
{
/* we assume: keyword|sep|data */
char *fkeyword;
ssize_t i;
if(strlen(keyword) >= LDNS_MAX_KEYWORDLEN)
return -1;
fkeyword = (char*)malloc(LDNS_MAX_KEYWORDLEN);
if(!fkeyword)
return -1;
i = ldns_fget_token(f, fkeyword, k_del, LDNS_MAX_KEYWORDLEN);
if(i==0 || i==-1) {
free(fkeyword);
return -1;
}
/* case??? i instead of strlen? */
if (strncmp(fkeyword, keyword, LDNS_MAX_KEYWORDLEN - 1) == 0) {
/* whee! */
/* printf("%s\n%s\n", "Matching keyword", fkeyword); */
i = ldns_fget_token_l(f, data, d_del, data_limit, line_nr);
free(fkeyword);
return i;
} else {
/*printf("no match for %s (read: %s)\n", keyword, fkeyword);*/
free(fkeyword);
return -1;
}
}
ssize_t
ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit)
{
return ldns_bget_token_par(b, token, delim, limit, NULL, NULL);
}
ssize_t
ldns_bget_token_par(ldns_buffer *b, char *token, const char *delim,
size_t limit, int* par, const char* skipw)
{
int c, lc;
int p; /* 0 -> no parenthese seen, >0 nr of ( seen */
int com, quoted;
char *t;
size_t i;
const char *d;
const char *del;
/* standard delimiters */
if (!delim) {
/* from isspace(3) */
del = LDNS_PARSE_NORMAL;
} else {
del = delim;
}
p = (par?*par:0);
i = 0;
com = 0;
quoted = 0;
t = token;
lc = 0;
if (del[0] == '"') {
quoted = 1;
}
while ((c = ldns_bgetc(b)) != EOF) {
if (c == '\r') /* carriage return */
c = ' ';
if (c == '(' && lc != '\\' && !quoted) {
/* this only counts for non-comments */
if (com == 0) {
if(par) (*par)++;
p++;
}
lc = c;
continue;
}
if (c == ')' && lc != '\\' && !quoted) {
/* this only counts for non-comments */
if (com == 0) {
if(par) (*par)--;
p--;
}
lc = c;
continue;
}
if (p < 0) {
/* more ) then ( */
*t = '\0';
return 0;
}
/* do something with comments ; */
if (c == ';' && quoted == 0) {
if (lc != '\\') {
com = 1;
}
}
if (c == '"' && com == 0 && lc != '\\') {
quoted = 1 - quoted;
}
if (c == '\n' && com != 0) {
/* comments */
com = 0;
*t = ' ';
lc = c;
continue;
}
if (com == 1) {
*t = ' ';
lc = c;
continue;
}
if (c == '\n' && p != 0) {
/* in parentheses */
/* do not write ' ' if we want to skip spaces */
if(!(skipw && (strchr(skipw, c)||strchr(skipw, ' '))))
*t++ = ' ';
lc = c;
continue;
}
/* check to skip whitespace at start, but also after ( */
if(skipw && i==0 && !com && !quoted && lc != '\\') {
if(strchr(skipw, c)) {
lc = c;
continue;
}
}
/* check if we hit the delim */
for (d = del; *d; d++) {
/* we can only exit if no parens or user tracks them */
if (c == *d && lc != '\\' && (p == 0 || par)) {
goto tokenread;
}
}
i++;
if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
*t = '\0';
return -1;
}
*t++ = c;
if (c == '\\' && lc == '\\') {
lc = 0;
} else {
lc = c;
}
}
*t = '\0';
if (i == 0) {
/* nothing read */
return -1;
}
if (!par && p != 0) {
return -1;
}
return (ssize_t)i;
tokenread:
ldns_bskipcs(b, del);
*t = '\0';
if (!par && p != 0) {
return -1;
}
return (ssize_t)i;
}
void
ldns_bskipcs(ldns_buffer *buffer, const char *s)
{
int found;
char c;
const char *d;
while(ldns_buffer_available_at(buffer, buffer->_position, sizeof(char))) {
c = (char) ldns_buffer_read_u8_at(buffer, buffer->_position);
found = 0;
for (d = s; *d; d++) {
if (*d == c) {
found = 1;
}
}
if (found && buffer->_limit > buffer->_position) {
buffer->_position += sizeof(char);
} else {
return;
}
}
}
void
ldns_fskipcs(FILE *fp, const char *s)
{
ldns_fskipcs_l(fp, s, NULL);
}
void
ldns_fskipcs_l(FILE *fp, const char *s, int *line_nr)
{
int found;
int c;
const char *d;
while ((c = fgetc(fp)) != EOF) {
if (line_nr && c == '\n') {
*line_nr = *line_nr + 1;
}
found = 0;
for (d = s; *d; d++) {
if (*d == c) {
found = 1;
}
}
if (!found) {
/* with getc, we've read too far */
ungetc(c, fp);
return;
}
}
}
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)
{
/* we assume: keyword|sep|data */
char *fkeyword;
ssize_t i;
if(strlen(keyword) >= LDNS_MAX_KEYWORDLEN)
return -1;
fkeyword = (char*)malloc(LDNS_MAX_KEYWORDLEN);
if(!fkeyword)
return -1; /* out of memory */
i = ldns_bget_token(b, fkeyword, k_del, data_limit);
if(i==0 || i==-1) {
free(fkeyword);
return -1; /* nothing read */
}
/* case??? */
if (strncmp(fkeyword, keyword, strlen(keyword)) == 0) {
free(fkeyword);
/* whee, the match! */
/* retrieve it's data */
i = ldns_bget_token(b, data, d_del, 0);
return i;
} else {
free(fkeyword);
return -1;
}
}

184
ldns/parse.h Normal file
View File

@ -0,0 +1,184 @@
/*
* 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
struct ldns_buffer;
#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
* \param[in] *par if you pass nonNULL, set to 0 on first call, the parenthesis
* state is stored in it, for use on next call. User must check it is back
* to zero after last bget in string (for parse error). If you pass NULL,
* the entire parenthesized string is read in.
* \param[in] skipw string with whitespace to skip before the start of the
* token, like " ", or " \t", or NULL for none.
* \returns 0 on error of EOF of b. Otherwise return the length of what is read
*/
ssize_t ldns_bget_token_par(struct ldns_buffer *b, char *token, const char *delim, size_t limit, int* par, const char* skipw);
/**
* 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(struct 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(struct 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(struct 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(struct 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 */

726
ldns/parseutil.c Normal file
View File

@ -0,0 +1,726 @@
/*
* parseutil.c - parse utilities for string and wire conversion
*
* (c) NLnet Labs, 2004-2006
*
* See the file LICENSE for the license
*/
/**
* \file
*
* Utility functions for parsing, base32(DNS variant) and base64 encoding
* and decoding, Hex, Time units, Escape codes.
*/
#include "config.h"
#include "ldns/parseutil.h"
#include <sys/time.h>
#include <time.h>
#include <ctype.h>
ldns_lookup_table *
ldns_lookup_by_name(ldns_lookup_table *table, const char *name)
{
while (table->name != NULL) {
if (strcasecmp(name, table->name) == 0)
return table;
table++;
}
return NULL;
}
ldns_lookup_table *
ldns_lookup_by_id(ldns_lookup_table *table, int id)
{
while (table->name != NULL) {
if (table->id == id)
return table;
table++;
}
return NULL;
}
/* Number of days per month (except for February in leap years). */
static const int mdays[] = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
#define LDNS_MOD(x,y) (((x) % (y) < 0) ? ((x) % (y) + (y)) : ((x) % (y)))
#define LDNS_DIV(x,y) (((x) % (y) < 0) ? ((x) / (y) - 1 ) : ((x) / (y)))
static int
is_leap_year(int year)
{
return LDNS_MOD(year, 4) == 0 && (LDNS_MOD(year, 100) != 0
|| LDNS_MOD(year, 400) == 0);
}
static int
leap_days(int y1, int y2)
{
--y1;
--y2;
return (LDNS_DIV(y2, 4) - LDNS_DIV(y1, 4)) -
(LDNS_DIV(y2, 100) - LDNS_DIV(y1, 100)) +
(LDNS_DIV(y2, 400) - LDNS_DIV(y1, 400));
}
/*
* Code adapted from Python 2.4.1 sources (Lib/calendar.py).
*/
time_t
ldns_mktime_from_utc(const struct tm *tm)
{
int year = 1900 + tm->tm_year;
time_t days = 365 * ((time_t) year - 1970) + leap_days(1970, year);
time_t hours;
time_t minutes;
time_t seconds;
int i;
for (i = 0; i < tm->tm_mon; ++i) {
days += mdays[i];
}
if (tm->tm_mon > 1 && is_leap_year(year)) {
++days;
}
days += tm->tm_mday - 1;
hours = days * 24 + tm->tm_hour;
minutes = hours * 60 + tm->tm_min;
seconds = minutes * 60 + tm->tm_sec;
return seconds;
}
#if SIZEOF_TIME_T <= 4
static void
ldns_year_and_yday_from_days_since_epoch(int64_t days, struct tm *result)
{
int year = 1970;
int new_year;
while (days < 0 || days >= (int64_t) (is_leap_year(year) ? 366 : 365)) {
new_year = year + (int) LDNS_DIV(days, 365);
days -= (new_year - year) * 365;
days -= leap_days(year, new_year);
year = new_year;
}
result->tm_year = year;
result->tm_yday = (int) days;
}
/* Number of days per month in a leap year. */
static const int leap_year_mdays[] = {
31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
static void
ldns_mon_and_mday_from_year_and_yday(struct tm *result)
{
int idays = result->tm_yday;
const int *mon_lengths = is_leap_year(result->tm_year) ?
leap_year_mdays : mdays;
result->tm_mon = 0;
while (idays >= mon_lengths[result->tm_mon]) {
idays -= mon_lengths[result->tm_mon++];
}
result->tm_mday = idays + 1;
}
static void
ldns_wday_from_year_and_yday(struct tm *result)
{
result->tm_wday = 4 /* 1-1-1970 was a thursday */
+ LDNS_MOD((result->tm_year - 1970), 7) * LDNS_MOD(365, 7)
+ leap_days(1970, result->tm_year)
+ result->tm_yday;
result->tm_wday = LDNS_MOD(result->tm_wday, 7);
if (result->tm_wday < 0) {
result->tm_wday += 7;
}
}
static struct tm *
ldns_gmtime64_r(int64_t clock, struct tm *result)
{
result->tm_isdst = 0;
result->tm_sec = (int) LDNS_MOD(clock, 60);
clock = LDNS_DIV(clock, 60);
result->tm_min = (int) LDNS_MOD(clock, 60);
clock = LDNS_DIV(clock, 60);
result->tm_hour = (int) LDNS_MOD(clock, 24);
clock = LDNS_DIV(clock, 24);
ldns_year_and_yday_from_days_since_epoch(clock, result);
ldns_mon_and_mday_from_year_and_yday(result);
ldns_wday_from_year_and_yday(result);
result->tm_year -= 1900;
return result;
}
#endif /* SIZEOF_TIME_T <= 4 */
static int64_t
ldns_serial_arithmitics_time(int32_t time, time_t now)
{
int32_t offset = time - (int32_t) now;
return (int64_t) now + offset;
}
struct tm *
ldns_serial_arithmitics_gmtime_r(int32_t time, time_t now, struct tm *result)
{
#if SIZEOF_TIME_T <= 4
int64_t secs_since_epoch = ldns_serial_arithmitics_time(time, now);
return ldns_gmtime64_r(secs_since_epoch, result);
#else
time_t secs_since_epoch = ldns_serial_arithmitics_time(time, now);
return gmtime_r(&secs_since_epoch, result);
#endif
}
int
ldns_hexdigit_to_int(char ch)
{
switch (ch) {
case '0': return 0;
case '1': return 1;
case '2': return 2;
case '3': return 3;
case '4': return 4;
case '5': return 5;
case '6': return 6;
case '7': return 7;
case '8': return 8;
case '9': return 9;
case 'a': case 'A': return 10;
case 'b': case 'B': return 11;
case 'c': case 'C': return 12;
case 'd': case 'D': return 13;
case 'e': case 'E': return 14;
case 'f': case 'F': return 15;
default:
return -1;
}
}
uint32_t
ldns_str2period(const char *nptr, const char **endptr)
{
int sign = 0;
uint32_t i = 0;
uint32_t seconds = 0;
for(*endptr = nptr; **endptr; (*endptr)++) {
switch (**endptr) {
case ' ':
case '\t':
break;
case '-':
if(sign == 0) {
sign = -1;
} else {
return seconds;
}
break;
case '+':
if(sign == 0) {
sign = 1;
} else {
return seconds;
}
break;
case 's':
case 'S':
seconds += i;
i = 0;
break;
case 'm':
case 'M':
seconds += i * 60;
i = 0;
break;
case 'h':
case 'H':
seconds += i * 60 * 60;
i = 0;
break;
case 'd':
case 'D':
seconds += i * 60 * 60 * 24;
i = 0;
break;
case 'w':
case 'W':
seconds += i * 60 * 60 * 24 * 7;
i = 0;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
i *= 10;
i += (**endptr - '0');
break;
default:
seconds += i;
/* disregard signedness */
return seconds;
}
}
seconds += i;
/* disregard signedness */
return seconds;
}
int
ldns_parse_escape(uint8_t *ch_p, const char** str_p)
{
uint16_t val;
if ((*str_p)[0] && isdigit((*str_p)[0]) &&
(*str_p)[1] && isdigit((*str_p)[1]) &&
(*str_p)[2] && isdigit((*str_p)[2])) {
val = (uint16_t)(((*str_p)[0] - '0') * 100 +
((*str_p)[1] - '0') * 10 +
((*str_p)[2] - '0'));
if (val > 255) {
goto error;
}
*ch_p = (uint8_t)val;
*str_p += 3;
return 1;
} else if ((*str_p)[0] && !isdigit((*str_p)[0])) {
*ch_p = (uint8_t)*(*str_p)++;
return 1;
}
error:
*str_p = NULL;
return 0; /* LDNS_WIREPARSE_ERR_SYNTAX_BAD_ESCAPE */
}
/** parse one character, with escape codes */
int
ldns_parse_char(uint8_t *ch_p, const char** str_p)
{
switch (**str_p) {
case '\0': return 0;
case '\\': *str_p += 1;
return ldns_parse_escape(ch_p, str_p);
default: *ch_p = (uint8_t)*(*str_p)++;
return 1;
}
}
size_t ldns_b32_ntop_calculate_size(size_t src_data_length)
{
return src_data_length == 0 ? 0 : ((src_data_length - 1) / 5 + 1) * 8;
}
size_t ldns_b32_ntop_calculate_size_no_padding(size_t src_data_length)
{
return ((src_data_length + 3) * 8 / 5) - 4;
}
static int
ldns_b32_ntop_base(const uint8_t* src, size_t src_sz, char* dst, size_t dst_sz,
int extended_hex, int add_padding)
{
size_t ret_sz;
const char* b32 = extended_hex ? "0123456789abcdefghijklmnopqrstuv"
: "abcdefghijklmnopqrstuvwxyz234567";
size_t c = 0; /* c is used to carry partial base32 character over
* byte boundaries for sizes with a remainder.
* (i.e. src_sz % 5 != 0)
*/
ret_sz = add_padding ? ldns_b32_ntop_calculate_size(src_sz)
: ldns_b32_ntop_calculate_size_no_padding(src_sz);
/* Do we have enough space? */
if (dst_sz < ret_sz + 1)
return -1;
/* We know the size; terminate the string */
dst[ret_sz] = '\0';
/* First process all chunks of five */
while (src_sz >= 5) {
/* 00000... ........ ........ ........ ........ */
dst[0] = b32[(src[0] ) >> 3];
/* .....111 11...... ........ ........ ........ */
dst[1] = b32[(src[0] & 0x07) << 2 | src[1] >> 6];
/* ........ ..22222. ........ ........ ........ */
dst[2] = b32[(src[1] & 0x3e) >> 1];
/* ........ .......3 3333.... ........ ........ */
dst[3] = b32[(src[1] & 0x01) << 4 | src[2] >> 4];
/* ........ ........ ....4444 4....... ........ */
dst[4] = b32[(src[2] & 0x0f) << 1 | src[3] >> 7];
/* ........ ........ ........ .55555.. ........ */
dst[5] = b32[(src[3] & 0x7c) >> 2];
/* ........ ........ ........ ......66 666..... */
dst[6] = b32[(src[3] & 0x03) << 3 | src[4] >> 5];
/* ........ ........ ........ ........ ...77777 */
dst[7] = b32[(src[4] & 0x1f) ];
src_sz -= 5;
src += 5;
dst += 8;
}
/* Process what remains */
switch (src_sz) {
case 4: /* ........ ........ ........ ......66 666..... */
dst[6] = b32[(src[3] & 0x03) << 3];
/* ........ ........ ........ .55555.. ........ */
dst[5] = b32[(src[3] & 0x7c) >> 2];
/* ........ ........ ....4444 4....... ........ */
c = src[3] >> 7 ;
case 3: dst[4] = b32[(src[2] & 0x0f) << 1 | c];
/* ........ .......3 3333.... ........ ........ */
c = src[2] >> 4 ;
case 2: dst[3] = b32[(src[1] & 0x01) << 4 | c];
/* ........ ..22222. ........ ........ ........ */
dst[2] = b32[(src[1] & 0x3e) >> 1];
/* .....111 11...... ........ ........ ........ */
c = src[1] >> 6 ;
case 1: dst[1] = b32[(src[0] & 0x07) << 2 | c];
/* 00000... ........ ........ ........ ........ */
dst[0] = b32[ src[0] >> 3];
}
/* Add padding */
if (add_padding) {
switch (src_sz) {
case 1: dst[2] = '=';
dst[3] = '=';
case 2: dst[4] = '=';
case 3: dst[5] = '=';
dst[6] = '=';
case 4: dst[7] = '=';
}
}
return (int)ret_sz;
}
int
ldns_b32_ntop(const uint8_t* src, size_t src_sz, char* dst, size_t dst_sz)
{
return ldns_b32_ntop_base(src, src_sz, dst, dst_sz, 0, 1);
}
int
ldns_b32_ntop_extended_hex(const uint8_t* src, size_t src_sz,
char* dst, size_t dst_sz)
{
return ldns_b32_ntop_base(src, src_sz, dst, dst_sz, 1, 1);
}
size_t ldns_b32_pton_calculate_size(size_t src_text_length)
{
return src_text_length * 5 / 8;
}
static int
ldns_b32_pton_base(const char* src, size_t src_sz, uint8_t* dst, size_t dst_sz,
int extended_hex, int check_padding)
{
size_t i = 0;
char ch = '\0';
uint8_t buf[8];
uint8_t* start = dst;
while (src_sz) {
/* Collect 8 characters in buf (if possible) */
for (i = 0; i < 8; i++) {
do {
ch = *src++;
--src_sz;
} while (isspace(ch) && src_sz > 0);
if (ch == '=' || ch == '\0')
break;
else if (extended_hex)
if (ch >= '0' && ch <= '9')
buf[i] = (uint8_t)ch - '0';
else if (ch >= 'a' && ch <= 'v')
buf[i] = (uint8_t)ch - 'a' + 10;
else if (ch >= 'A' && ch <= 'V')
buf[i] = (uint8_t)ch - 'A' + 10;
else
return -1;
else if (ch >= 'a' && ch <= 'z')
buf[i] = (uint8_t)ch - 'a';
else if (ch >= 'A' && ch <= 'Z')
buf[i] = (uint8_t)ch - 'A';
else if (ch >= '2' && ch <= '7')
buf[i] = (uint8_t)ch - '2' + 26;
else
return -1;
}
/* Less that 8 characters. We're done. */
if (i < 8)
break;
/* Enough space available at the destination? */
if (dst_sz < 5)
return -1;
/* 00000... ........ ........ ........ ........ */
/* .....111 11...... ........ ........ ........ */
dst[0] = buf[0] << 3 | buf[1] >> 2;
/* .....111 11...... ........ ........ ........ */
/* ........ ..22222. ........ ........ ........ */
/* ........ .......3 3333.... ........ ........ */
dst[1] = buf[1] << 6 | buf[2] << 1 | buf[3] >> 4;
/* ........ .......3 3333.... ........ ........ */
/* ........ ........ ....4444 4....... ........ */
dst[2] = buf[3] << 4 | buf[4] >> 1;
/* ........ ........ ....4444 4....... ........ */
/* ........ ........ ........ .55555.. ........ */
/* ........ ........ ........ ......66 666..... */
dst[3] = buf[4] << 7 | buf[5] << 2 | buf[6] >> 3;
/* ........ ........ ........ ......66 666..... */
/* ........ ........ ........ ........ ...77777 */
dst[4] = buf[6] << 5 | buf[7];
dst += 5;
dst_sz -= 5;
}
/* Not ending on a eight byte boundary? */
if (i > 0 && i < 8) {
/* Enough space available at the destination? */
if (dst_sz < (i + 1) / 2)
return -1;
switch (i) {
case 7: /* ........ ........ ........ ......66 666..... */
/* ........ ........ ........ .55555.. ........ */
/* ........ ........ ....4444 4....... ........ */
dst[3] = buf[4] << 7 | buf[5] << 2 | buf[6] >> 3;
case 5: /* ........ ........ ....4444 4....... ........ */
/* ........ .......3 3333.... ........ ........ */
dst[2] = buf[3] << 4 | buf[4] >> 1;
case 4: /* ........ .......3 3333.... ........ ........ */
/* ........ ..22222. ........ ........ ........ */
/* .....111 11...... ........ ........ ........ */
dst[1] = buf[1] << 6 | buf[2] << 1 | buf[3] >> 4;
case 2: /* .....111 11...... ........ ........ ........ */
/* 00000... ........ ........ ........ ........ */
dst[0] = buf[0] << 3 | buf[1] >> 2;
break;
default:
return -1;
}
dst += (i + 1) / 2;
if (check_padding) {
/* Check remaining padding characters */
if (ch != '=')
return -1;
/* One down, 8 - i - 1 more to come... */
for (i = 8 - i - 1; i > 0; i--) {
do {
if (src_sz == 0)
return -1;
ch = *src++;
src_sz--;
} while (isspace(ch));
if (ch != '=')
return -1;
}
}
}
return dst - start;
}
int
ldns_b32_pton(const char* src, size_t src_sz, uint8_t* dst, size_t dst_sz)
{
return ldns_b32_pton_base(src, src_sz, dst, dst_sz, 0, 1);
}
int
ldns_b32_pton_extended_hex(const char* src, size_t src_sz,
uint8_t* dst, size_t dst_sz)
{
return ldns_b32_pton_base(src, src_sz, dst, dst_sz, 1, 1);
}
size_t ldns_b64_ntop_calculate_size(size_t srcsize)
{
return ((((srcsize + 2) / 3) * 4) + 1);
}
/* RFC 1521, section 5.2.
*
* 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.
*
* This routine does not insert spaces or linebreaks after 76 characters.
*/
int ldns_b64_ntop(uint8_t const *src, size_t srclength,
char *target, size_t targsize)
{
const char* b64 =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const char pad64 = '=';
size_t i = 0, o = 0;
if(targsize < ldns_b64_ntop_calculate_size(srclength))
return -1;
/* whole chunks: xxxxxxyy yyyyzzzz zzwwwwww */
while(i+3 <= srclength) {
if(o+4 > targsize) return -1;
target[o] = b64[src[i] >> 2];
target[o+1] = b64[ ((src[i]&0x03)<<4) | (src[i+1]>>4) ];
target[o+2] = b64[ ((src[i+1]&0x0f)<<2) | (src[i+2]>>6) ];
target[o+3] = b64[ (src[i+2]&0x3f) ];
i += 3;
o += 4;
}
/* remainder */
switch(srclength - i) {
case 2:
/* two at end, converted into A B C = */
target[o] = b64[src[i] >> 2];
target[o+1] = b64[ ((src[i]&0x03)<<4) | (src[i+1]>>4) ];
target[o+2] = b64[ ((src[i+1]&0x0f)<<2) ];
target[o+3] = pad64;
i += 2;
o += 4;
break;
case 1:
/* one at end, converted into A B = = */
target[o] = b64[src[i] >> 2];
target[o+1] = b64[ ((src[i]&0x03)<<4) ];
target[o+2] = pad64;
target[o+3] = pad64;
i += 1;
o += 4;
break;
case 0:
default:
/* nothing */
break;
}
/* assert: i == srclength */
if(o+1 > targsize) return -1;
target[o] = 0;
return (int)o;
}
size_t ldns_b64_pton_calculate_size(size_t srcsize)
{
return (((((srcsize + 3) / 4) * 3)) + 1);
}
int ldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
{
const uint8_t pad64 = 64; /* is 64th in the b64 array */
const char* s = src;
uint8_t in[4];
size_t o = 0, incount = 0;
while(*s) {
/* skip any character that is not base64 */
/* conceptually we do:
const char* b64 = pad'=' is appended to array
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
const char* d = strchr(b64, *s++);
and use d-b64;
*/
char d = *s++;
if(d <= 'Z' && d >= 'A')
d -= 'A';
else if(d <= 'z' && d >= 'a')
d = d - 'a' + 26;
else if(d <= '9' && d >= '0')
d = d - '0' + 52;
else if(d == '+')
d = 62;
else if(d == '/')
d = 63;
else if(d == '=')
d = 64;
else continue;
in[incount++] = (uint8_t)d;
if(incount != 4)
continue;
/* process whole block of 4 characters into 3 output bytes */
if(in[3] == pad64 && in[2] == pad64) { /* A B = = */
if(o+1 > targsize)
return -1;
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
o += 1;
break; /* we are done */
} else if(in[3] == pad64) { /* A B C = */
if(o+2 > targsize)
return -1;
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
target[o+1]= ((in[1]&0x0f)<<4) | ((in[2]&0x3c)>>2);
o += 2;
break; /* we are done */
} else {
if(o+3 > targsize)
return -1;
/* write xxxxxxyy yyyyzzzz zzwwwwww */
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
target[o+1]= ((in[1]&0x0f)<<4) | ((in[2]&0x3c)>>2);
target[o+2]= ((in[2]&0x03)<<6) | in[3];
o += 3;
}
incount = 0;
}
return (int)o;
}

148
ldns/parseutil.h Normal file
View File

@ -0,0 +1,148 @@
/*
* parseutil.h - parse utilities for string and wire conversion
*
* (c) NLnet Labs, 2004
*
* See the file LICENSE for the license
*/
/**
* \file
*
* Utility functions for parsing, base32(DNS variant) and base64 encoding
* and decoding, Hex, Time units, Escape codes.
*/
#ifndef LDNS_PARSEUTIL_H
#define LDNS_PARSEUTIL_H
struct tm;
/**
* 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 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);
/**
* 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 ldns_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);
/**
* 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);
/**
* 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);
/**
* calculates the size needed to store the result of b64_ntop
*/
size_t ldns_b64_ntop_calculate_size(size_t srcsize);
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 ldns_b64_pton
*/
size_t ldns_b64_pton_calculate_size(size_t srcsize);
int ldns_b64_pton(char const *src, uint8_t *target, size_t targsize);
/**
* calculates the size needed to store the result of b32_ntop
*/
size_t ldns_b32_ntop_calculate_size(size_t src_data_length);
size_t ldns_b32_ntop_calculate_size_no_padding(size_t src_data_length);
int ldns_b32_ntop(const uint8_t* src_data, size_t src_data_length,
char* target_text_buffer, size_t target_text_buffer_size);
int ldns_b32_ntop_extended_hex(const uint8_t* src_data, size_t src_data_length,
char* target_text_buffer, size_t target_text_buffer_size);
/**
* calculates the size needed to store the result of b32_pton
*/
size_t ldns_b32_pton_calculate_size(size_t src_text_length);
int ldns_b32_pton(const char* src_text, size_t src_text_length,
uint8_t* target_data_buffer, size_t target_data_buffer_size);
int ldns_b32_pton_extended_hex(const char* src_text, size_t src_text_length,
uint8_t* target_data_buffer, size_t target_data_buffer_size);
/*
* Checks whether the escaped value at **s is an octal value or
* a 'normally' escaped character (and not eos)
*
* @param ch_p: the parsed character
* @param str_p: the string. moved along for characters read.
* The string pointer at *s is increased by either 0 (on error), 1 (on
* normal escapes), or 3 (on octals)
*
* @return 0 on error
*/
int ldns_parse_escape(uint8_t *ch_p, const char** str_p);
/**
* Parse one character, with escape codes,
* @param ch_p: the parsed character
* @param str_p: the string. moved along for characters read.
* @return 0 on error
*/
int ldns_parse_char(uint8_t *ch_p, const char** str_p);
#endif /* LDNS_PARSEUTIL_H */

158
ldns/pkthdr.h Normal file
View File

@ -0,0 +1,158 @@
/*
* pkthdr.h - packet header 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 for the packet header.
*/
#ifndef LDNS_PKTHDR_H
#define LDNS_PKTHDR_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))
/**
* 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;
/* 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;
#ifdef __cplusplus
}
#endif
#endif /* LDNS_PKTHDR_H */

778
ldns/rrdef.c Normal file
View File

@ -0,0 +1,778 @@
/* rrdef.c
*
* access functions to rr definitions list.
* a Net::DNS like library for C
* LibDNS Team @ NLnet Labs
*
* (c) NLnet Labs, 2004-2006
* See the file LICENSE for the license
*/
/**
* \file
*
* Defines resource record types and constants.
*/
#include "config.h"
#include "ldns/rrdef.h"
#include "ldns/parseutil.h"
/* classes */
static ldns_lookup_table ldns_rr_classes_data[] = {
{ LDNS_RR_CLASS_IN, "IN" },
{ LDNS_RR_CLASS_CH, "CH" },
{ LDNS_RR_CLASS_HS, "HS" },
{ LDNS_RR_CLASS_NONE, "NONE" },
{ LDNS_RR_CLASS_ANY, "ANY" },
{ 0, NULL }
};
ldns_lookup_table* ldns_rr_classes = ldns_rr_classes_data;
/* types */
static const ldns_rdf_type type_0_wireformat[] = { LDNS_RDF_TYPE_UNKNOWN };
static const ldns_rdf_type type_a_wireformat[] = { LDNS_RDF_TYPE_A };
static const ldns_rdf_type type_ns_wireformat[] = { LDNS_RDF_TYPE_DNAME };
static const ldns_rdf_type type_md_wireformat[] = { LDNS_RDF_TYPE_DNAME };
static const ldns_rdf_type type_mf_wireformat[] = { LDNS_RDF_TYPE_DNAME };
static const ldns_rdf_type type_cname_wireformat[] = { LDNS_RDF_TYPE_DNAME };
static const ldns_rdf_type type_soa_wireformat[] = {
LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_INT32,
LDNS_RDF_TYPE_PERIOD, LDNS_RDF_TYPE_PERIOD, LDNS_RDF_TYPE_PERIOD,
LDNS_RDF_TYPE_PERIOD
};
static const ldns_rdf_type type_mb_wireformat[] = { LDNS_RDF_TYPE_DNAME };
static const ldns_rdf_type type_mg_wireformat[] = { LDNS_RDF_TYPE_DNAME };
static const ldns_rdf_type type_mr_wireformat[] = { LDNS_RDF_TYPE_DNAME };
static const ldns_rdf_type type_wks_wireformat[] = {
LDNS_RDF_TYPE_A, LDNS_RDF_TYPE_WKS
};
static const ldns_rdf_type type_ptr_wireformat[] = { LDNS_RDF_TYPE_DNAME };
static const ldns_rdf_type type_hinfo_wireformat[] = {
LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR
};
static const ldns_rdf_type type_minfo_wireformat[] = {
LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_DNAME
};
static const ldns_rdf_type type_mx_wireformat[] = {
LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME
};
static const ldns_rdf_type type_rp_wireformat[] = {
LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_DNAME
};
static const ldns_rdf_type type_afsdb_wireformat[] = {
LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME
};
static const ldns_rdf_type type_x25_wireformat[] = { LDNS_RDF_TYPE_STR };
static const ldns_rdf_type type_isdn_wireformat[] = {
LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR
};
static const ldns_rdf_type type_rt_wireformat[] = {
LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME
};
static const ldns_rdf_type type_nsap_wireformat[] = {
LDNS_RDF_TYPE_NSAP
};
static const ldns_rdf_type type_nsap_ptr_wireformat[] = {
LDNS_RDF_TYPE_STR
};
static const ldns_rdf_type type_sig_wireformat[] = {
LDNS_RDF_TYPE_TYPE, LDNS_RDF_TYPE_ALG, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT32,
LDNS_RDF_TYPE_TIME, LDNS_RDF_TYPE_TIME, LDNS_RDF_TYPE_INT16,
LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_B64
};
static const ldns_rdf_type type_key_wireformat[] = {
LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_B64
};
static const ldns_rdf_type type_px_wireformat[] = {
LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_DNAME
};
static const ldns_rdf_type type_gpos_wireformat[] = {
LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR
};
static const ldns_rdf_type type_aaaa_wireformat[] = { LDNS_RDF_TYPE_AAAA };
static const ldns_rdf_type type_loc_wireformat[] = { LDNS_RDF_TYPE_LOC };
static const ldns_rdf_type type_nxt_wireformat[] = {
LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_UNKNOWN
};
static const ldns_rdf_type type_eid_wireformat[] = {
LDNS_RDF_TYPE_HEX
};
static const ldns_rdf_type type_nimloc_wireformat[] = {
LDNS_RDF_TYPE_HEX
};
static const ldns_rdf_type type_srv_wireformat[] = {
LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME
};
static const ldns_rdf_type type_atma_wireformat[] = {
LDNS_RDF_TYPE_ATMA
};
static const ldns_rdf_type type_naptr_wireformat[] = {
LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_DNAME
};
static const ldns_rdf_type type_kx_wireformat[] = {
LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME
};
static const ldns_rdf_type type_cert_wireformat[] = {
LDNS_RDF_TYPE_CERT_ALG, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_ALG, LDNS_RDF_TYPE_B64
};
static const ldns_rdf_type type_a6_wireformat[] = { LDNS_RDF_TYPE_UNKNOWN };
static const ldns_rdf_type type_dname_wireformat[] = { LDNS_RDF_TYPE_DNAME };
static const ldns_rdf_type type_sink_wireformat[] = { LDNS_RDF_TYPE_INT8,
LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_B64
};
static const ldns_rdf_type type_apl_wireformat[] = {
LDNS_RDF_TYPE_APL
};
static const ldns_rdf_type type_ds_wireformat[] = {
LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_ALG, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_HEX
};
static const ldns_rdf_type type_sshfp_wireformat[] = {
LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_HEX
};
static const ldns_rdf_type type_ipseckey_wireformat[] = {
LDNS_RDF_TYPE_IPSECKEY
};
static const ldns_rdf_type type_rrsig_wireformat[] = {
LDNS_RDF_TYPE_TYPE, LDNS_RDF_TYPE_ALG, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT32,
LDNS_RDF_TYPE_TIME, LDNS_RDF_TYPE_TIME, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_B64
};
static const ldns_rdf_type type_nsec_wireformat[] = {
LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_NSEC
};
static const ldns_rdf_type type_dhcid_wireformat[] = {
LDNS_RDF_TYPE_B64
};
static const ldns_rdf_type type_talink_wireformat[] = {
LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_DNAME
};
/* nsec3 is some vars, followed by same type of data of nsec */
static const ldns_rdf_type type_nsec3_wireformat[] = {
/* LDNS_RDF_TYPE_NSEC3_VARS, LDNS_RDF_TYPE_NSEC3_NEXT_OWNER, LDNS_RDF_TYPE_NSEC*/
LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_NSEC3_SALT, LDNS_RDF_TYPE_NSEC3_NEXT_OWNER, LDNS_RDF_TYPE_NSEC
};
static const ldns_rdf_type type_nsec3param_wireformat[] = {
/* LDNS_RDF_TYPE_NSEC3_PARAMS_VARS*/
LDNS_RDF_TYPE_INT8,
LDNS_RDF_TYPE_INT8,
LDNS_RDF_TYPE_INT16,
LDNS_RDF_TYPE_NSEC3_SALT
};
static const ldns_rdf_type type_dnskey_wireformat[] = {
LDNS_RDF_TYPE_INT16,
LDNS_RDF_TYPE_INT8,
LDNS_RDF_TYPE_ALG,
LDNS_RDF_TYPE_B64
};
static const ldns_rdf_type type_tkey_wireformat[] = {
LDNS_RDF_TYPE_DNAME,
LDNS_RDF_TYPE_TIME,
LDNS_RDF_TYPE_TIME,
LDNS_RDF_TYPE_INT16,
LDNS_RDF_TYPE_INT16,
LDNS_RDF_TYPE_INT16_DATA,
LDNS_RDF_TYPE_INT16_DATA,
};
static const ldns_rdf_type type_tsig_wireformat[] = {
LDNS_RDF_TYPE_DNAME,
LDNS_RDF_TYPE_TSIGTIME,
LDNS_RDF_TYPE_INT16,
LDNS_RDF_TYPE_INT16_DATA,
LDNS_RDF_TYPE_INT16,
LDNS_RDF_TYPE_INT16,
LDNS_RDF_TYPE_INT16_DATA
};
static const ldns_rdf_type type_tlsa_wireformat[] = {
LDNS_RDF_TYPE_INT8,
LDNS_RDF_TYPE_INT8,
LDNS_RDF_TYPE_INT8,
LDNS_RDF_TYPE_HEX
};
/**
* With HIP, wire and presentation format are out of step.
* In presentation format, we have:
* - a PK algorithm presented as integer in range [0..255]
* - a variable length HIT field presented as hexstring
* - a variable length Public Key field presented as Base64
*
* Unfortunately in the wireformat the lengths of the variable
* length HIT and Public Key fields do not directly preceed them.
* In stead we have:
* - 1 byte HIT length: h
* - 1 byte PK algorithm
* - 2 bytes Public Key length: p
* - h bytes HIT
* - p bytes Public Key
*
* In ldns those deviations from the conventions for rdata fields are best
* tackeled by letting the array refered to by the descriptor for HIP represent
* host format only.
*
* BEWARE! Unlike other RR types, actual HIP wire format does not directly
* follow the RDF types enumerated in the array pointed to by _wireformat in
* its descriptor record.
*/
static const ldns_rdf_type type_hip_hostformat[] = {
LDNS_RDF_TYPE_INT8,
LDNS_RDF_TYPE_HEX,
LDNS_RDF_TYPE_B64
};
static const ldns_rdf_type type_nid_wireformat[] = {
LDNS_RDF_TYPE_INT16,
LDNS_RDF_TYPE_ILNP64
};
static const ldns_rdf_type type_l32_wireformat[] = {
LDNS_RDF_TYPE_INT16,
LDNS_RDF_TYPE_A
};
static const ldns_rdf_type type_l64_wireformat[] = {
LDNS_RDF_TYPE_INT16,
LDNS_RDF_TYPE_ILNP64
};
static const ldns_rdf_type type_lp_wireformat[] = {
LDNS_RDF_TYPE_INT16,
LDNS_RDF_TYPE_DNAME
};
#ifdef DRAFT_RRTYPES
static const ldns_rdf_type type_eui48_wireformat[] = {
LDNS_RDF_TYPE_EUI48
};
static const ldns_rdf_type type_eui64_wireformat[] = {
LDNS_RDF_TYPE_EUI64
};
static const ldns_rdf_type type_uri_wireformat[] = {
LDNS_RDF_TYPE_INT16,
LDNS_RDF_TYPE_INT16,
LDNS_RDF_TYPE_LONG_STR
};
#endif
static const ldns_rdf_type type_caa_wireformat[] = {
LDNS_RDF_TYPE_INT8,
LDNS_RDF_TYPE_TAG,
LDNS_RDF_TYPE_LONG_STR
};
/* All RR's defined in 1035 are well known and can thus
* be compressed. See RFC3597. These RR's are:
* CNAME HINFO MB MD MF MG MINFO MR MX NULL NS PTR SOA TXT
*/
static ldns_rr_descriptor rdata_field_descriptors[] = {
/* 0 */
{ 0, NULL, 0, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 1 */
{LDNS_RR_TYPE_A, "A", 1, 1, type_a_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 2 */
{LDNS_RR_TYPE_NS, "NS", 1, 1, type_ns_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
/* 3 */
{LDNS_RR_TYPE_MD, "MD", 1, 1, type_md_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
/* 4 */
{LDNS_RR_TYPE_MF, "MF", 1, 1, type_mf_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
/* 5 */
{LDNS_RR_TYPE_CNAME, "CNAME", 1, 1, type_cname_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
/* 6 */
{LDNS_RR_TYPE_SOA, "SOA", 7, 7, type_soa_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 2 },
/* 7 */
{LDNS_RR_TYPE_MB, "MB", 1, 1, type_mb_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
/* 8 */
{LDNS_RR_TYPE_MG, "MG", 1, 1, type_mg_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
/* 9 */
{LDNS_RR_TYPE_MR, "MR", 1, 1, type_mr_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
/* 10 */
{LDNS_RR_TYPE_NULL, "NULL", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 11 */
{LDNS_RR_TYPE_WKS, "WKS", 2, 2, type_wks_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 12 */
{LDNS_RR_TYPE_PTR, "PTR", 1, 1, type_ptr_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
/* 13 */
{LDNS_RR_TYPE_HINFO, "HINFO", 2, 2, type_hinfo_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 14 */
{LDNS_RR_TYPE_MINFO, "MINFO", 2, 2, type_minfo_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 2 },
/* 15 */
{LDNS_RR_TYPE_MX, "MX", 2, 2, type_mx_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
/* 16 */
{LDNS_RR_TYPE_TXT, "TXT", 1, 0, NULL, LDNS_RDF_TYPE_STR, LDNS_RR_NO_COMPRESS, 0 },
/* 17 */
{LDNS_RR_TYPE_RP, "RP", 2, 2, type_rp_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 2 },
/* 18 */
{LDNS_RR_TYPE_AFSDB, "AFSDB", 2, 2, type_afsdb_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
/* 19 */
{LDNS_RR_TYPE_X25, "X25", 1, 1, type_x25_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 20 */
{LDNS_RR_TYPE_ISDN, "ISDN", 1, 2, type_isdn_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 21 */
{LDNS_RR_TYPE_RT, "RT", 2, 2, type_rt_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
/* 22 */
{LDNS_RR_TYPE_NSAP, "NSAP", 1, 1, type_nsap_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 23 */
{LDNS_RR_TYPE_NSAP_PTR, "NSAP-PTR", 1, 1, type_nsap_ptr_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 24 */
{LDNS_RR_TYPE_SIG, "SIG", 9, 9, type_sig_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
/* 25 */
{LDNS_RR_TYPE_KEY, "KEY", 4, 4, type_key_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 26 */
{LDNS_RR_TYPE_PX, "PX", 3, 3, type_px_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 2 },
/* 27 */
{LDNS_RR_TYPE_GPOS, "GPOS", 3, 3, type_gpos_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 28 */
{LDNS_RR_TYPE_AAAA, "AAAA", 1, 1, type_aaaa_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 29 */
{LDNS_RR_TYPE_LOC, "LOC", 1, 1, type_loc_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 30 */
{LDNS_RR_TYPE_NXT, "NXT", 2, 2, type_nxt_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
/* 31 */
{LDNS_RR_TYPE_EID, "EID", 1, 1, type_eid_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 32 */
{LDNS_RR_TYPE_NIMLOC, "NIMLOC", 1, 1, type_nimloc_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 33 */
{LDNS_RR_TYPE_SRV, "SRV", 4, 4, type_srv_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
/* 34 */
{LDNS_RR_TYPE_ATMA, "ATMA", 1, 1, type_atma_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 35 */
{LDNS_RR_TYPE_NAPTR, "NAPTR", 6, 6, type_naptr_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
/* 36 */
{LDNS_RR_TYPE_KX, "KX", 2, 2, type_kx_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
/* 37 */
{LDNS_RR_TYPE_CERT, "CERT", 4, 4, type_cert_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 38 */
{LDNS_RR_TYPE_A6, "A6", 1, 1, type_a6_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 39 */
{LDNS_RR_TYPE_DNAME, "DNAME", 1, 1, type_dname_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
/* 40 */
{LDNS_RR_TYPE_SINK, "SINK", 1, 1, type_sink_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 41 */
{LDNS_RR_TYPE_OPT, "OPT", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 42 */
{LDNS_RR_TYPE_APL, "APL", 0, 0, type_apl_wireformat, LDNS_RDF_TYPE_APL, LDNS_RR_NO_COMPRESS, 0 },
/* 43 */
{LDNS_RR_TYPE_DS, "DS", 4, 4, type_ds_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 44 */
{LDNS_RR_TYPE_SSHFP, "SSHFP", 3, 3, type_sshfp_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 45 */
{LDNS_RR_TYPE_IPSECKEY, "IPSECKEY", 1, 1, type_ipseckey_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 46 */
{LDNS_RR_TYPE_RRSIG, "RRSIG", 9, 9, type_rrsig_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
/* 47 */
{LDNS_RR_TYPE_NSEC, "NSEC", 1, 2, type_nsec_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
/* 48 */
{LDNS_RR_TYPE_DNSKEY, "DNSKEY", 4, 4, type_dnskey_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 49 */
{LDNS_RR_TYPE_DHCID, "DHCID", 1, 1, type_dhcid_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 50 */
{LDNS_RR_TYPE_NSEC3, "NSEC3", 5, 6, type_nsec3_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 51 */
{LDNS_RR_TYPE_NSEC3PARAM, "NSEC3PARAM", 4, 4, type_nsec3param_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 52 */
{LDNS_RR_TYPE_TLSA, "TLSA", 4, 4, type_tlsa_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE53", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE54", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 55
* Hip ends with 0 or more Rendezvous Servers represented as dname's.
* Hence the LDNS_RDF_TYPE_DNAME _variable field and the _maximum field
* set to 0.
*
* BEWARE! Unlike other RR types, actual HIP wire format does not
* directly follow the RDF types enumerated in the array pointed to
* by _wireformat. For more info see type_hip_hostformat declaration.
*/
{LDNS_RR_TYPE_HIP, "HIP", 3, 3, type_hip_hostformat, LDNS_RDF_TYPE_DNAME, LDNS_RR_NO_COMPRESS, 0 },
#ifdef DRAFT_RRTYPES
/* 56 */
{LDNS_RR_TYPE_NINFO, "NINFO", 1, 0, NULL, LDNS_RDF_TYPE_STR, LDNS_RR_NO_COMPRESS, 0 },
/* 57 */
{LDNS_RR_TYPE_RKEY, "RKEY", 4, 4, type_key_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
#else
{LDNS_RR_TYPE_NULL, "TYPE56", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE57", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
#endif
/* 58 */
{LDNS_RR_TYPE_TALINK, "TALINK", 2, 2, type_talink_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 2 },
#ifdef DRAFT_RRTYPES
/* 59 */
{LDNS_RR_TYPE_CDS, "CDS", 4, 4, type_ds_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
#else
{LDNS_RR_TYPE_NULL, "TYPE59", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
#endif
{LDNS_RR_TYPE_NULL, "TYPE60", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE61", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE62", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE63", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE64", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE65", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE66", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE67", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE68", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE69", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE70", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE71", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE72", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE73", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE74", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE75", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE76", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE77", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE78", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE79", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE80", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE81", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE82", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE83", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE84", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE85", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE86", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE87", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE88", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE89", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE90", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE91", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE92", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE93", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE94", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE95", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE96", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE97", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE98", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 99 */
{LDNS_RR_TYPE_SPF, "SPF", 1, 0, NULL, LDNS_RDF_TYPE_STR, LDNS_RR_NO_COMPRESS, 0 },
/* UINFO [IANA-Reserved] */
{LDNS_RR_TYPE_NULL, "TYPE100", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* UID [IANA-Reserved] */
{LDNS_RR_TYPE_NULL, "TYPE101", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* GID [IANA-Reserved] */
{LDNS_RR_TYPE_NULL, "TYPE102", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* UNSPEC [IANA-Reserved] */
{LDNS_RR_TYPE_NULL, "TYPE103", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 104 */
{LDNS_RR_TYPE_NID, "NID", 2, 2, type_nid_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 105 */
{LDNS_RR_TYPE_L32, "L32", 2, 2, type_l32_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 106 */
{LDNS_RR_TYPE_L64, "L64", 2, 2, type_l64_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 107 */
{LDNS_RR_TYPE_LP, "LP", 2, 2, type_lp_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
#ifdef DRAFT_RRTYPES
/* 108 */
{LDNS_RR_TYPE_EUI48, "EUI48", 1, 1, type_eui48_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 109 */
{LDNS_RR_TYPE_EUI64, "EUI64", 1, 1, type_eui64_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
#else
{LDNS_RR_TYPE_NULL, "TYPE108", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE109", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
#endif
{LDNS_RR_TYPE_NULL, "TYPE110", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE111", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE112", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE113", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE114", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE115", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE116", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE117", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE118", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE119", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE120", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE121", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE122", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE123", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE124", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE125", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE126", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE127", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE128", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE129", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE130", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE131", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE132", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE133", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE134", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE135", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE136", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE137", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE138", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE139", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE140", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE141", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE142", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE143", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE144", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE145", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE146", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE147", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE148", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE149", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE150", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE151", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE152", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE153", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE154", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE155", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE156", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE157", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE158", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE159", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE160", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE161", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE162", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE163", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE164", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE165", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE166", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE167", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE168", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE169", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE170", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE171", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE172", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE173", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE174", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE175", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE176", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE177", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE178", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE179", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE180", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE181", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE182", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE183", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE184", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE185", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE186", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE187", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE188", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE189", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE190", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE191", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE192", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE193", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE194", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE195", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE196", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE197", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE198", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE199", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE200", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE201", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE202", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE203", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE204", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE205", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE206", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE207", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE208", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE209", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE210", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE211", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE212", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE213", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE214", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE215", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE216", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE217", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE218", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE219", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE220", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE221", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE222", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE223", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE224", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE225", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE226", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE227", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE228", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE229", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE230", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE231", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE232", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE233", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE234", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE235", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE236", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE237", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE238", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE239", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE240", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE241", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE242", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE243", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE244", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE245", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE246", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE247", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE248", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* LDNS_RDF_TYPE_INT16_DATA takes two fields (length and data) as one.
* So, unlike RFC 2930 spec, we have 7 min/max rdf's i.s.o. 8/9.
*/
/* 249 */
{LDNS_RR_TYPE_TKEY, "TKEY", 7, 7, type_tkey_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
/* LDNS_RDF_TYPE_INT16_DATA takes two fields (length and data) as one.
* So, unlike RFC 2930 spec, we have 7 min/max rdf's i.s.o. 8/9.
*/
/* 250 */
{LDNS_RR_TYPE_TSIG, "TSIG", 7, 7, type_tsig_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
/* IXFR: A request for a transfer of an incremental zone transfer */
{LDNS_RR_TYPE_IXFR, "IXFR", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* AXFR: A request for a transfer of an entire zone */
{LDNS_RR_TYPE_AXFR, "AXFR", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* MAILB: A request for mailbox-related records (MB, MG or MR) */
{LDNS_RR_TYPE_MAILB, "MAILB", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* MAILA: A request for mail agent RRs (Obsolete - see MX) */
{LDNS_RR_TYPE_MAILA, "MAILA", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* ANY: A request for all (available) records */
{LDNS_RR_TYPE_ANY, "ANY", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
#ifdef DRAFT_RRTYPES
/* 256 */
{LDNS_RR_TYPE_URI, "URI", 3, 3, type_uri_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
#else
{LDNS_RR_TYPE_NULL, "TYPE256", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
#endif
/* 257 */
{LDNS_RR_TYPE_CAA, "CAA", 3, 3, type_caa_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* split in array, no longer contiguous */
#ifdef DRAFT_RRTYPES
/* 32768 */
{LDNS_RR_TYPE_TA, "TA", 4, 4, type_ds_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
#else
{LDNS_RR_TYPE_NULL, "TYPE32768", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
#endif
/* 32769 */
{LDNS_RR_TYPE_DLV, "DLV", 4, 4, type_ds_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 }
};
/**
* \def LDNS_RDATA_FIELD_DESCRIPTORS_COUNT
* computes the number of rdata fields
*/
#define LDNS_RDATA_FIELD_DESCRIPTORS_COUNT \
(sizeof(rdata_field_descriptors)/sizeof(rdata_field_descriptors[0]))
const ldns_rr_descriptor *
ldns_rr_descript(uint16_t type)
{
size_t i;
if (type < LDNS_RDATA_FIELD_DESCRIPTORS_COMMON) {
return &rdata_field_descriptors[type];
} else {
/* because not all array index equals type code */
for (i = LDNS_RDATA_FIELD_DESCRIPTORS_COMMON;
i < LDNS_RDATA_FIELD_DESCRIPTORS_COUNT;
i++) {
if (rdata_field_descriptors[i]._type == type) {
return &rdata_field_descriptors[i];
}
}
return &rdata_field_descriptors[0];
}
}
size_t
ldns_rr_descriptor_minimum(const ldns_rr_descriptor *descriptor)
{
if (descriptor) {
return descriptor->_minimum;
} else {
return 0;
}
}
size_t
ldns_rr_descriptor_maximum(const ldns_rr_descriptor *descriptor)
{
if (descriptor) {
if (descriptor->_variable != LDNS_RDF_TYPE_NONE) {
/* Should really be SIZE_MAX... bad FreeBSD. */
return UINT_MAX;
} else {
return descriptor->_maximum;
}
} else {
return 0;
}
}
ldns_rdf_type
ldns_rr_descriptor_field_type(const ldns_rr_descriptor *descriptor,
size_t index)
{
assert(descriptor != NULL);
assert(index < descriptor->_maximum
|| descriptor->_variable != LDNS_RDF_TYPE_NONE);
if (index < descriptor->_maximum) {
return descriptor->_wireformat[index];
} else {
return descriptor->_variable;
}
}
ldns_rr_type
ldns_get_rr_type_by_name(const char *name)
{
unsigned int i;
const char *desc_name;
const ldns_rr_descriptor *desc;
/* TYPEXX representation */
if (strlen(name) > 4 && strncasecmp(name, "TYPE", 4) == 0) {
return atoi(name + 4);
}
/* Normal types */
for (i = 0; i < (unsigned int) LDNS_RDATA_FIELD_DESCRIPTORS_COUNT; i++) {
desc = &rdata_field_descriptors[i];
desc_name = desc->_name;
if(desc_name &&
strlen(name) == strlen(desc_name) &&
strncasecmp(name, desc_name, strlen(desc_name)) == 0) {
/* because not all array index equals type code */
return desc->_type;
}
}
/* special cases for query types */
if (strlen(name) == 4 && strncasecmp(name, "IXFR", 4) == 0) {
return 251;
} else if (strlen(name) == 4 && strncasecmp(name, "AXFR", 4) == 0) {
return 252;
} else if (strlen(name) == 5 && strncasecmp(name, "MAILB", 5) == 0) {
return 253;
} else if (strlen(name) == 5 && strncasecmp(name, "MAILA", 5) == 0) {
return 254;
} else if (strlen(name) == 3 && strncasecmp(name, "ANY", 3) == 0) {
return 255;
}
return 0;
}
ldns_rr_class
ldns_get_rr_class_by_name(const char *name)
{
ldns_lookup_table *lt;
/* CLASSXX representation */
if (strlen(name) > 5 && strncasecmp(name, "CLASS", 5) == 0) {
return atoi(name + 5);
}
/* Normal types */
lt = ldns_lookup_by_name(ldns_rr_classes, name);
if (lt) {
return lt->id;
}
return 0;
}

500
ldns/rrdef.h Normal file
View File

@ -0,0 +1,500 @@
/*
* rrdef.h
*
* RR definitions
*
* a Net::DNS like library for C
*
* (c) NLnet Labs, 2005-2006
*
* See the file LICENSE for the license
*/
/**
* \file
*
* Defines resource record types and constants.
*/
#ifndef LDNS_RRDEF_H
#define LDNS_RRDEF_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
#define LDNS_DNSSEC_KEYPROTO 3
#define LDNS_KEY_ZONE_KEY 0x0100 /* set for ZSK&KSK, rfc 4034 */
#define LDNS_KEY_SEP_KEY 0x0001 /* set for KSK, rfc 4034 */
#define LDNS_KEY_REVOKE_KEY 0x0080 /* used to revoke KSK, rfc 5011 */
/* The first fields are contiguous and can be referenced instantly */
#define LDNS_RDATA_FIELD_DESCRIPTORS_COMMON 258
/** lookuptable for rr types */
extern struct ldns_struct_lookup_table* ldns_rr_classes;
/**
* 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,
/** RFC4034, RFC3658 */
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,
LDNS_RR_TYPE_TLSA = 52, /* RFC 6698 */
LDNS_RR_TYPE_HIP = 55, /* RFC 5205 */
/** draft-reid-dnsext-zs */
LDNS_RR_TYPE_NINFO = 56,
/** draft-reid-dnsext-rkey */
LDNS_RR_TYPE_RKEY = 57,
/** draft-ietf-dnsop-trust-history */
LDNS_RR_TYPE_TALINK = 58,
/** draft-barwood-dnsop-ds-publis */
LDNS_RR_TYPE_CDS = 59,
LDNS_RR_TYPE_SPF = 99, /* RFC 4408 */
LDNS_RR_TYPE_UINFO = 100,
LDNS_RR_TYPE_UID = 101,
LDNS_RR_TYPE_GID = 102,
LDNS_RR_TYPE_UNSPEC = 103,
LDNS_RR_TYPE_NID = 104, /* RFC 6742 */
LDNS_RR_TYPE_L32 = 105, /* RFC 6742 */
LDNS_RR_TYPE_L64 = 106, /* RFC 6742 */
LDNS_RR_TYPE_LP = 107, /* RFC 6742 */
/** draft-jabley-dnsext-eui48-eui64-rrtypes */
LDNS_RR_TYPE_EUI48 = 108,
LDNS_RR_TYPE_EUI64 = 109,
LDNS_RR_TYPE_TKEY = 249, /* RFC 2930 */
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,
/** draft-faltstrom-uri-06 */
LDNS_RR_TYPE_URI = 256,
LDNS_RR_TYPE_CAA = 257, /* RFC 6844 */
/** DNSSEC Trust Authorities */
LDNS_RR_TYPE_TA = 32768,
/* 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;
/* RDATA */
#define LDNS_MAX_RDFLEN 65535
#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_8BYTES 8
#define LDNS_RDF_SIZE_16BYTES 16
#define LDNS_NSEC3_VARS_OPTOUT_MASK 0x01
#define LDNS_APL_IP4 1
#define LDNS_APL_IP6 2
#define LDNS_APL_MASK 0x7f
#define LDNS_APL_NEGATION 0x80
/**
* 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,
/** skip 21 unused */
/** variable length any type rdata where the length
is specified by the first 2 bytes */
LDNS_RDF_TYPE_INT16_DATA = 22,
/** 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,
/** 4 shorts represented as 4 * 16 bit hex numbers
* seperated by colons. For NID and L64.
*/
LDNS_RDF_TYPE_ILNP64,
/** 6 * 8 bit hex numbers seperated by dashes. For EUI48. */
LDNS_RDF_TYPE_EUI48,
/** 8 * 8 bit hex numbers seperated by dashes. For EUI64. */
LDNS_RDF_TYPE_EUI64,
/** A non-zero sequence of US-ASCII letters and numbers in lower case.
* For CAA.
*/
LDNS_RDF_TYPE_TAG,
/** A <character-string> encoding of the value field as specified
* [RFC1035], Section 5.1., encoded as remaining rdata.
* For CAA.
*/
LDNS_RDF_TYPE_LONG_STR,
/* Aliases */
LDNS_RDF_TYPE_BITMAP = LDNS_RDF_TYPE_NSEC
};
typedef enum ldns_enum_rdf_type ldns_rdf_type;
/**
* 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 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;
/**
* EDNS option codes
*/
enum ldns_enum_edns_option
{
LDNS_EDNS_LLQ = 1, /* http://files.dns-sd.org/draft-sekar-dns-llq.txt */
LDNS_EDNS_UL = 2, /* http://files.dns-sd.org/draft-sekar-dns-ul.txt */
LDNS_EDNS_NSID = 3, /* RFC5001 */
/* 4 draft-cheshire-edns0-owner-option */
LDNS_EDNS_DAU = 5, /* RFC6975 */
LDNS_EDNS_DHU = 6, /* RFC6975 */
LDNS_EDNS_N3U = 7, /* RFC6975 */
LDNS_EDNS_CLIENT_SUBNET = 8 /* draft-vandergaast-edns-client-subnet */
};
typedef enum ldns_edns_option ldns_edns_option;
#define LDNS_EDNS_MASK_DO_BIT 0x8000
/**
* 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;
/**
* 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);
/**
* 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);
#ifdef __cplusplus
}
#endif
#endif /* LDNS_RRDEF_H */

189
ldns/sbuffer.c Normal file
View File

@ -0,0 +1,189 @@
/*
* buffer.c -- generic memory buffer .
*
* Copyright (c) 2001-2008, NLnet Labs. All rights reserved.
*
* See LICENSE for the license.
*
*/
/**
* \file
*
* This file contains the definition of ldns_buffer, and functions to manipulate those.
*/
#include "config.h"
#include "ldns/sbuffer.h"
#include <stdarg.h>
ldns_buffer *
ldns_buffer_new(size_t capacity)
{
ldns_buffer *buffer = (ldns_buffer*)malloc(sizeof(ldns_buffer));
if (!buffer) {
return NULL;
}
buffer->_data = (uint8_t *) malloc(capacity);
if (!buffer->_data) {
free(buffer);
return NULL;
}
buffer->_position = 0;
buffer->_limit = buffer->_capacity = capacity;
buffer->_fixed = 0;
buffer->_status_err = 0;
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 = malloc(size);
if(!buffer->_data) {
buffer->_status_err = 1;
return;
}
memcpy(buffer->_data, data, size);
buffer->_status_err = 0;
ldns_buffer_invariant(buffer);
}
void
ldns_buffer_init_frm_data(ldns_buffer *buffer, void *data, size_t size)
{
memset(buffer, 0, sizeof(*buffer));
buffer->_data = data;
buffer->_capacity = buffer->_limit = size;
buffer->_fixed = 1;
}
int
ldns_buffer_set_capacity(ldns_buffer *buffer, size_t capacity)
{
void *data;
ldns_buffer_invariant(buffer);
assert(buffer->_position <= capacity);
data = (uint8_t *) realloc(buffer->_data, capacity);
if (!data) {
buffer->_status_err = 1;
return 0;
} else {
buffer->_data = data;
buffer->_limit = buffer->_capacity = capacity;
return 1;
}
}
int
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_err = 1;
return 0;
}
}
buffer->_limit = buffer->_capacity;
return 1;
}
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_err = 1;
return -1;
} else if ((size_t) written >= remaining) {
if (!ldns_buffer_reserve(buffer, (size_t) written + 1)) {
buffer->_status_err = 1;
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_err = 1;
return -1;
}
}
buffer->_position += written;
}
return written;
}
void
ldns_buffer_free(ldns_buffer *buffer)
{
if (!buffer) {
return;
}
if (!buffer->_fixed)
free(buffer->_data);
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);
}

706
ldns/sbuffer.h Normal file
View File

@ -0,0 +1,706 @@
/*
* 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_SBUFFER_H
#define LDNS_SBUFFER_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef S_SPLINT_S
# define INLINE
#else
# ifdef SWIG
# define INLINE static
# else
# define INLINE static inline
# endif
#endif
/*
* 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
}
/**
* \file sbuffer.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.
*/
struct ldns_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. */
unsigned _status_err : 1;
};
typedef struct ldns_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);
/**
* Setup a buffer with the data pointed to. No data copied, no memory allocs.
* The buffer is fixed.
* \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_init_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
*/
int 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
*/
int 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 int
ldns_buffer_status(ldns_buffer *buffer)
{
return (int)buffer->_status_err;
}
/**
* returns true if the status of the buffer is LDNS_STATUS_OK, false otherwise
* \param[in] buffer the buffer
* \return true or false
*/
INLINE int
ldns_buffer_status_ok(ldns_buffer *buffer)
{
if (buffer) {
return ldns_buffer_status(buffer) == 0;
} else {
return 0;
}
}
/**
* 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 from buffer to the result buffer and then flips
* the result buffer. Data will be silently truncated if the result 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_SBUFFER_H */

1840
ldns/str2wire.c Normal file

File diff suppressed because it is too large Load Diff

532
ldns/str2wire.h Normal file
View File

@ -0,0 +1,532 @@
/**
* str2wire.h - read txt presentation of RRs
*
* (c) NLnet Labs, 2005-2006
*
* See the file LICENSE for the license
*/
/**
* \file
*
* Parses text to wireformat.
*/
#ifndef LDNS_STR2WIRE_H
#define LDNS_STR2WIRE_H
/* include rrdef for MAX_DOMAINLEN constant */
#include <ldns/rrdef.h>
#ifdef __cplusplus
extern "C" {
#endif
struct ldns_struct_lookup_table;
/** buffer to read an RR, cannot be larger than 64K because of packet size */
#define LDNS_RR_BUF_SIZE 65535 /* bytes */
#define LDNS_DEFAULT_TTL 3600
/*
* To convert class and type to string see
* ldns_get_rr_class_by_name(str)
* ldns_get_rr_type_by_name(str)
* from rrdef.h
*/
/**
* Convert text string into dname wireformat, mallocless, with user buffer.
* @param str: the text string with the domain name.
* @param buf: the result buffer, suggested size LDNS_MAX_DOMAINLEN+1
* @param len: length of the buffer on input, length of the result on output.
* @return 0 on success, otherwise an error.
*/
int ldns_str2wire_dname_buf(const char* str, uint8_t* buf, size_t* len);
/**
* Same as ldns_str2wire_dname_buf, but concatenates origin if the domain
* name is relative (does not end in '.').
* @param str: the text string with the domain name.
* @param buf: the result buffer, suggested size LDNS_MAX_DOMAINLEN+1
* @param len: length of the buffer on input, length of the result on output.
* @param origin: the origin to append or NULL (nothing is appended).
* @param origin_len: length of origin.
* @return 0 on success, otherwise an error.
*/
int ldns_str2wire_dname_buf_origin(const char* str, uint8_t* buf, size_t* len,
uint8_t* origin, size_t origin_len);
/**
* Convert text string into dname wireformat
* @param str: the text string with the domain name.
* @param len: returned length of wireformat.
* @return wireformat dname (malloced) or NULL on failure.
*/
uint8_t* ldns_str2wire_dname(const char* str, size_t* len);
/**
* Convert text RR to wireformat, with user buffer.
* @param str: the RR data in text presentation format.
* @param rr: the buffer where the result is stored into. This buffer has
* the wire-dname(uncompressed), type, class, ttl, rdatalen, rdata.
* These values are probably not aligned, and in network format.
* Use the ldns_wirerr_get_xxx functions to access them safely.
* buffer size LDNS_RR_BUF_SIZE is suggested.
* @param len: on input the length of the buffer, on output the amount of
* the buffer used for the rr.
* @param dname_len: if non-NULL, filled with the dname length as result.
* Because after the dname you find the type, class, ttl, rdatalen, rdata.
* @param default_ttl: TTL used if no TTL available.
* @param origin: used for origin dname (if not NULL)
* @param origin_len: length of origin.
* @param prev: used for prev_rr dname (if not NULL)
* @param prev_len: length of prev.
* @return 0 on success, an error on failure.
*/
int ldns_str2wire_rr_buf(const char* str, uint8_t* rr, size_t* len,
size_t* dname_len, uint32_t default_ttl, uint8_t* origin,
size_t origin_len, uint8_t* prev, size_t prev_len);
/**
* Same as ldns_str2wire_rr_buf, but there is no rdata, it returns an RR
* with zero rdata and no ttl. It has name, type, class.
* You can access those with the ldns_wirerr_get_type and class functions.
* @param str: the RR data in text presentation format.
* @param rr: the buffer where the result is stored into.
* @param len: on input the length of the buffer, on output the amount of
* the buffer used for the rr.
* @param dname_len: if non-NULL, filled with the dname length as result.
* Because after the dname you find the type, class, ttl, rdatalen, rdata.
* @param origin: used for origin dname (if not NULL)
* @param origin_len: length of origin.
* @param prev: used for prev_rr dname (if not NULL)
* @param prev_len: length of prev.
* @return 0 on success, an error on failure.
*/
int ldns_str2wire_rr_question_buf(const char* str, uint8_t* rr, size_t* len,
size_t* dname_len, uint8_t* origin, size_t origin_len, uint8_t* prev,
size_t prev_len);
/**
* Get the type of the RR.
* @param rr: the RR in wire format.
* @param len: rr length.
* @param dname_len: dname length to skip.
* @return type in host byteorder
*/
uint16_t ldns_wirerr_get_type(uint8_t* rr, size_t len, size_t dname_len);
/**
* Get the class of the RR.
* @param rr: the RR in wire format.
* @param len: rr length.
* @param dname_len: dname length to skip.
* @return class in host byteorder
*/
uint16_t ldns_wirerr_get_class(uint8_t* rr, size_t len, size_t dname_len);
/**
* Get the ttl of the RR.
* @param rr: the RR in wire format.
* @param len: rr length.
* @param dname_len: dname length to skip.
* @return ttl in host byteorder
*/
uint32_t ldns_wirerr_get_ttl(uint8_t* rr, size_t len, size_t dname_len);
/**
* Get the rdata length of the RR.
* @param rr: the RR in wire format.
* @param len: rr length.
* @param dname_len: dname length to skip.
* @return rdata length in host byteorder
* If the rdata length is larger than the rr-len allows, it is truncated.
* So, that it is safe to read the data length returned
* from this function from the rdata pointer of ldns_wirerr_get_rdata.
*/
uint16_t ldns_wirerr_get_rdatalen(uint8_t* rr, size_t len, size_t dname_len);
/**
* Get the rdata pointer of the RR.
* @param rr: the RR in wire format.
* @param len: rr length.
* @param dname_len: dname length to skip.
* @return rdata pointer
*/
uint8_t* ldns_wirerr_get_rdata(uint8_t* rr, size_t len, size_t dname_len);
/**
* Get the rdata pointer of the RR. prefixed with rdata length.
* @param rr: the RR in wire format.
* @param len: rr length.
* @param dname_len: dname length to skip.
* @return pointer to rdatalength, followed by the rdata.
*/
uint8_t* ldns_wirerr_get_rdatawl(uint8_t* rr, size_t len, size_t dname_len);
/**
* Parse result codes
*/
#define LDNS_WIREPARSE_MASK 0x0fff
#define LDNS_WIREPARSE_SHIFT 12
#define LDNS_WIREPARSE_ERROR(e) ((e)&LDNS_WIREPARSE_MASK)
#define LDNS_WIREPARSE_OFFSET(e) (((e)&~LDNS_WIREPARSE_MASK)>>LDNS_WIREPARSE_SHIFT)
/* use lookuptable to get error string, ldns_wireparse_errors */
#define LDNS_WIREPARSE_ERR_OK 0
#define LDNS_WIREPARSE_ERR_GENERAL 342
#define LDNS_WIREPARSE_ERR_DOMAINNAME_OVERFLOW 343
#define LDNS_WIREPARSE_ERR_DOMAINNAME_UNDERFLOW 344
#define LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL 345
#define LDNS_WIREPARSE_ERR_LABEL_OVERFLOW 346
#define LDNS_WIREPARSE_ERR_EMPTY_LABEL 347
#define LDNS_WIREPARSE_ERR_SYNTAX_BAD_ESCAPE 348
#define LDNS_WIREPARSE_ERR_SYNTAX 349
#define LDNS_WIREPARSE_ERR_SYNTAX_TTL 350
#define LDNS_WIREPARSE_ERR_SYNTAX_TYPE 351
#define LDNS_WIREPARSE_ERR_SYNTAX_CLASS 352
#define LDNS_WIREPARSE_ERR_SYNTAX_RDATA 353
#define LDNS_WIREPARSE_ERR_SYNTAX_MISSING_VALUE 354
#define LDNS_WIREPARSE_ERR_INVALID_STR 355
#define LDNS_WIREPARSE_ERR_SYNTAX_B64 356
#define LDNS_WIREPARSE_ERR_SYNTAX_B32_EXT 357
#define LDNS_WIREPARSE_ERR_SYNTAX_HEX 358
#define LDNS_WIREPARSE_ERR_CERT_BAD_ALGORITHM 359
#define LDNS_WIREPARSE_ERR_SYNTAX_TIME 360
#define LDNS_WIREPARSE_ERR_SYNTAX_PERIOD 361
#define LDNS_WIREPARSE_ERR_SYNTAX_ILNP64 362
#define LDNS_WIREPARSE_ERR_SYNTAX_EUI48 363
#define LDNS_WIREPARSE_ERR_SYNTAX_EUI64 364
#define LDNS_WIREPARSE_ERR_SYNTAX_TAG 365
#define LDNS_WIREPARSE_ERR_NOT_IMPL 366
#define LDNS_WIREPARSE_ERR_SYNTAX_INT 367
#define LDNS_WIREPARSE_ERR_SYNTAX_IP4 368
#define LDNS_WIREPARSE_ERR_SYNTAX_IP6 369
#define LDNS_WIREPARSE_ERR_SYNTAX_INTEGER_OVERFLOW 370
#define LDNS_WIREPARSE_ERR_INCLUDE 371
#define LDNS_WIREPARSE_ERR_PARENTHESIS 372
/**
* Get reference to a constant string for the (parse) error.
* @param e: error return value
* @return string.
*/
const char* ldns_get_errorstr_parse(int e);
/**
* wire parse state for parsing files
*/
struct ldns_file_parse_state {
/** the origin domain name, if len!=0. uncompressed wireformat */
uint8_t origin[LDNS_MAX_DOMAINLEN+1];
/** length of origin domain name, in bytes. 0 if not set. */
size_t origin_len;
/** the previous domain name, if len!=0. uncompressed wireformat*/
uint8_t prev_rr[LDNS_MAX_DOMAINLEN+1];
/** length of the previous domain name, in bytes. 0 if not set. */
size_t prev_rr_len;
/** default TTL, this is used if the text does not specify a TTL,
* host byteorder */
uint32_t default_ttl;
/** line number information */
int lineno;
};
/**
* Read one RR from zonefile with buffer for the data.
* @param in: file that is read from (one RR, multiple lines if it spans them).
* @param rr: this is malloced by the user and the result is stored here,
* if an RR is read. If no RR is read this is signalled with the
* return len set to 0 (for ORIGIN, TTL directives).
* @param len: on input, the length of the rr buffer. on output the rr len.
* Buffer size of 64k should be enough.
* @param dname_len: returns the length of the dname initial part of the rr.
* @param parse_state: pass a pointer to user-allocated struct.
* Contents are maintained by this function.
* If you pass NULL then ORIGIN and TTL directives are not honored.
* You can start out with a particular origin by pre-filling it.
* otherwise, zero the structure before passing it.
* lineno is incremented when a newline is passed by the parser,
* you should initialize it at 1 at the start of the file.
* @return 0 on success, error on failure.
*/
int ldns_fp2wire_rr_buf(FILE* in, uint8_t* rr, size_t* len, size_t* dname_len,
struct ldns_file_parse_state* parse_state);
/**
* Convert one rdf in rdata to wireformat and parse from string.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @param rdftype: the type of the rdf.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_rdf_buf(const char* str, uint8_t* rd, size_t* len,
ldns_rdf_type rdftype);
/**
* Convert rdf of type LDNS_RDF_TYPE_INT8 from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_int8_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_INT16 from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_int16_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_INT32 from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_int32_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_A from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_a_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_AAAA from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_aaaa_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_STR from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_str_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_APL from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_apl_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_B64 from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_b64_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_B32_EXT from string to wireformat.
* And also LDNS_RDF_TYPE_NSEC3_NEXT_OWNER.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_b32_ext_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_HEX from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_hex_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_NSEC from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_nsec_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_TYPE from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_type_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_CLASS from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_class_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_CERT_ALG from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_cert_alg_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_ALG from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_alg_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_TIME from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_time_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_PERIOD from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_period_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_LOC from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_loc_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_WKS from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_wks_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_NSAP from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_nsap_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_ATMA from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_atma_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_IPSECKEY from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_ipseckey_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_NSEC3_SALT from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_nsec3_salt_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_ILNP64 from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_ilnp64_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_EUI48 from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_eui48_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_EUI64 from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_eui64_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_TAG from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_tag_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_LONG_STR from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_long_str_buf(const char* str, uint8_t* rd, size_t* len);
/**
* Convert rdf of type LDNS_RDF_TYPE_INT16_DATA from string to wireformat.
* @param str: the text to convert for this rdata element.
* @param rd: rdata buffer for the wireformat.
* @param len: length of rd buffer on input, used length on output.
* @return 0 on success, error on failure.
*/
int ldns_str2wire_int16_data_buf(const char* str, uint8_t* rd, size_t* len);
#ifdef __cplusplus
}
#endif
#endif /* LDNS_STR2WIRE_H */

1925
ldns/wire2str.c Normal file

File diff suppressed because it is too large Load Diff

973
ldns/wire2str.h Normal file
View File

@ -0,0 +1,973 @@
/**
* wire2str.h - txt presentation of RRs
*
* (c) NLnet Labs, 2005-2006
*
* See the file LICENSE for the license
*/
/**
* \file
*
* Contains functions to translate the wireformat to text
* representation, as well as functions to print them.
*/
#ifndef LDNS_WIRE2STR_H
#define LDNS_WIRE2STR_H
#ifdef __cplusplus
extern "C" {
#endif
struct ldns_struct_lookup_table;
enum ldns_enum_rdf_type;
/* lookup tables for standard DNS stuff */
/** Taken from RFC 2535, section 7. */
extern struct ldns_struct_lookup_table* ldns_algorithms;
/** DS record hash algorithms */
extern struct ldns_struct_lookup_table* ldns_hashes;
/** Taken from RFC 2538, section 2.1. */
extern struct ldns_struct_lookup_table* ldns_cert_algorithms;
/** Response codes */
extern struct ldns_struct_lookup_table* ldns_rcodes;
/** Operation codes */
extern struct ldns_struct_lookup_table* ldns_opcodes;
/** EDNS flags */
extern struct ldns_struct_lookup_table* ldns_edns_flags;
/** EDNS option codes */
extern struct ldns_struct_lookup_table* ldns_edns_options;
/** error string from wireparse */
extern struct ldns_struct_lookup_table* ldns_wireparse_errors;
/**
* Convert wireformat packet to a string representation
* @param data: wireformat packet data (starting at ID bytes).
* @param len: length of packet.
* @return string(malloced) or NULL on failure.
*/
char* ldns_wire2str_pkt(uint8_t* data, size_t len);
/**
* Convert wireformat RR to a string representation.
* @param rr: the wireformat RR, in uncompressed form. Starts at the domain
* name start, ends with the rdata of the RR.
* @param len: length of the rr wireformat.
* @return string(malloced) or NULL on failure.
*/
char* ldns_wire2str_rr(uint8_t* rr, size_t len);
/**
* Conver wire dname to a string.
* @param dname: the dname in uncompressed wireformat.
* @param dname_len: length of the dname.
* @return string or NULL on failure.
*/
char* ldns_wire2str_dname(uint8_t* dname, size_t dname_len);
/**
* Convert wire RR type to a string, 'MX', 'TYPE1234'...
* @param rrtype: the RR type in host order.
* @return malloced string with the RR type or NULL on malloc failure.
*/
char* ldns_wire2str_type(uint16_t rrtype);
/**
* Convert wire RR class to a string, 'IN', 'CLASS1'.
* @param rrclass: the RR class in host order.
* @return malloced string with the RR class or NULL on malloc failure.
*/
char* ldns_wire2str_class(uint16_t rrclass);
/**
* Convert wire packet rcode to a string, 'NOERROR', 'NXDOMAIN'...
* @param rcode: as integer, host order
* @return malloced string with the rcode or NULL on malloc failure.
*/
char* ldns_wire2str_rcode(int rcode);
/**
* Print to string, move string along for next content. With va_list.
* @param str: string buffer. Adjusted at end to after the output.
* @param slen: length of the string buffer. Adjusted at end.
* @param format: printf format string.
* @param args: arguments for printf.
* @return number of characters needed. Can be larger than slen.
*/
int ldns_str_vprint(char** str, size_t* slen, const char* format, va_list args);
/**
* Print to string, move string along for next content.
* @param str: string buffer. Adjusted at end to after the output.
* @param slen: length of the string buffer. Adjusted at end.
* @param format: printf format string and arguments for it.
* @return number of characters needed. Can be larger than slen.
*/
int ldns_str_print(char** str, size_t* slen, const char* format, ...)
ATTR_FORMAT(printf, 3, 4);
/**
* Convert wireformat packet to a string representation with user buffer
* It appends every RR with default comments.
* For more formatter options use the function: TBD(TODO)
* @param data: wireformat packet data (starting at ID bytes).
* @param data_len: length of packet.
* @param str: the string buffer for the output.
* If you pass NULL as the str the return value of the function is
* the str_len you need for the entire packet. It does not include
* the 0 byte at the end.
* @param str_len: the size of the string buffer. If more is needed, it'll
* silently truncate the output to fit in the buffer.
* @return the number of characters for this element, excluding zerobyte.
* Is larger than str_len if output was truncated.
*/
int ldns_wire2str_pkt_buf(uint8_t* data, size_t data_len, char* str,
size_t str_len);
/**
* Scan wireformat packet to a string representation with user buffer
* It appends every RR with default comments.
* For more formatter options use the function: TBD(TODO)
* @param data: wireformat packet data (starting at ID bytes).
* @param data_len: length of packet.
* @param str: the string buffer for the output.
* @param str_len: the size of the string buffer.
* @return number of characters for string.
* returns the number of characters that are needed (except terminating null),
* so it may return a value larger than str_len.
* On error you get less output (i.e. shorter output in str (null terminated))
* On exit the data, data_len, str and str_len values are adjusted to move them
* from their original position along the input and output for the content
* that has been consumed (and produced) by this function. If the end of the
* output string is reached, *str_len is set to 0. The output string is null
* terminated (shortening the output if necessary). If the end of the input
* is reached *data_len is set to 0.
*/
int ldns_wire2str_pkt_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat rr to string, with user buffers. It shifts the arguments
* to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @param pkt: packet for decompression, if NULL no decompression.
* @param pktlen: length of packet buffer.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_rr_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len, uint8_t* pkt, size_t pktlen);
/**
* Scan wireformat question rr to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @param pkt: packet for decompression, if NULL no decompression.
* @param pktlen: length of packet buffer.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_rrquestion_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len, uint8_t* pkt, size_t pktlen);
/**
* Scan wireformat RR to string in unknown RR format, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @param pkt: packet for decompression, if NULL no decompression.
* @param pktlen: length of packet buffer.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_rr_unknown_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len, uint8_t* pkt, size_t pktlen);
/**
* Print to string the RR-information comment in default format,
* with user buffers. Moves string along.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @param rr: wireformat data.
* @param rrlen: length of data buffer.
* @param dname_off: offset in buffer behind owner dname, the compressed size
* of the owner name.
* @param rrtype: type of the RR, host format.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_rr_comment_print(char** str, size_t* str_len, uint8_t* rr,
size_t rrlen, size_t dname_off, uint16_t rrtype);
/**
* Scan wireformat packet header to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_header_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat rdata to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer. The length of the rdata in the
* buffer. The rdatalen itself has already been scanned, the data
* points to the rdata after the rdatalen.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @param rrtype: RR type of Rdata, host format.
* @param pkt: packet for decompression, if NULL no decompression.
* @param pktlen: length of packet buffer.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_rdata_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len, uint16_t rrtype, uint8_t* pkt, size_t pktlen);
/**
* Scan wireformat rdata to string in unknown format, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer, the length of the rdata in buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_rdata_unknown_scan(uint8_t** data, size_t* data_len,
char** str, size_t* str_len);
/**
* Scan wireformat domain name to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @param pkt: packet for decompression, if NULL no decompression.
* @param pktlen: length of packet buffer.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_dname_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len, uint8_t* pkt, size_t pktlen);
/**
* Scan wireformat rr type to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_type_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat rr class to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_class_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat rr ttl to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_ttl_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Print host format rr type to string. Moves string along, user buffers.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @param rrtype: host format rr type.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_type_print(char** str, size_t* str_len, uint16_t rrtype);
/**
* Print host format rr class to string. Moves string along, user buffers.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @param rrclass: host format rr class.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_class_print(char** str, size_t* str_len, uint16_t rrclass);
/**
* Print host format rcode to string. Moves string along, user buffers.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @param rcode: host format rcode number.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_rcode_print(char** str, size_t* str_len, int rcode);
/**
* Print host format opcode to string. Moves string along, user buffers.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @param opcode: host format opcode number.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_opcode_print(char** str, size_t* str_len, int opcode);
/**
* Print host format EDNS0 option to string. Moves string along, user buffers.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @param opcode: host format option number.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_edns_option_code_print(char** str, size_t* str_len,
uint16_t opcode);
/**
* Convert RR to string presentation format, on one line. User buffer.
* @param rr: wireformat RR data
* @param rr_len: length of the rr wire data.
* @param str: the string buffer to write to.
* If you pass NULL as the str, the return value of the function is
* the str_len you need for the entire packet. It does not include
* the 0 byte at the end.
* @param str_len: the size of the string buffer. If more is needed, it'll
* silently truncate the output to fit in the buffer.
* @return the number of characters for this element, excluding zerobyte.
* Is larger than str_len if output was truncated.
*/
int ldns_wire2str_rr_buf(uint8_t* rr, size_t rr_len, char* str,
size_t str_len);
/**
* 3597 printout of an RR in unknown rr format.
* There are more format and comment options available for printout
* with the function: TBD(TODO)
* @param rr: wireformat RR data
* @param rr_len: length of the rr wire data.
* @param str: the string buffer to write to.
* If you pass NULL as the str, the return value of the function is
* the str_len you need for the entire rr. It does not include
* the 0 byte at the end.
* @param str_len: the size of the string buffer. If more is needed, it'll
* silently truncate the output to fit in the buffer.
* @return the number of characters for this element, excluding zerobyte.
* Is larger than str_len if output was truncated.
*/
int ldns_wire2str_rr_unknown_buf(uint8_t* rr, size_t rr_len, char* str,
size_t str_len);
/**
* This creates the comment to print after the RR. ; keytag=... , and other
* basic comments for RRs.
* There are more format and comment options available for printout
* with the function: TBD(TODO)
* @param rr: wireformat RR data
* @param rr_len: length of the rr wire data.
* @param dname_len: length of the dname in front of the RR.
* @param str: the string buffer to write to.
* If you pass NULL as the str, the return value of the function is
* the str_len you need for the entire comment. It does not include
* the 0 byte at the end.
* @param str_len: the size of the string buffer. If more is needed, it'll
* silently truncate the output to fit in the buffer.
* @return the number of characters for this element, excluding zerobyte.
* Is larger than str_len if output was truncated.
*/
int ldns_wire2str_rr_comment_buf(uint8_t* rr, size_t rr_len, size_t dname_len,
char* str, size_t str_len);
/**
* Convert RDATA to string presentation format, on one line. User buffer.
* @param rdata: wireformat rdata part of an RR.
* @param rdata_len: length of the rr wire data.
* @param str: the string buffer to write to.
* If you pass NULL as the str, the return value of the function is
* the str_len you need for the entire packet. It does not include
* the 0 byte at the end.
* @param str_len: the size of the string buffer. If more is needed, it'll
* silently truncate the output to fit in the buffer.
* @param rrtype: rr type of the data
* @return the number of characters for this element, excluding zerobyte.
* Is larger than str_len if output was truncated.
*/
int ldns_wire2str_rdata_buf(uint8_t* rdata, size_t rdata_len, char* str,
size_t str_len, uint16_t rrtype);
/**
* Convert wire RR type to a string, 'MX', 'TYPE12'. With user buffer.
* @param rrtype: the RR type in host order.
* @param str: the string to write to.
* @param len: length of str.
* @return the number of characters for this element, excluding zerobyte.
* Is larger than str_len if output was truncated.
*/
int ldns_wire2str_type_buf(uint16_t rrtype, char* str, size_t len);
/**
* Convert wire RR class to a string, 'IN', 'CLASS12'. With user buffer.
* @param rrclass: the RR class in host order.
* @param str: the string to write to.
* @param len: length of str.
* @return the number of characters for this element, excluding zerobyte.
* Is larger than str_len if output was truncated.
*/
int ldns_wire2str_class_buf(uint16_t rrclass, char* str, size_t len);
/**
* Convert wire RR rcode to a string, 'NOERROR', 'NXDOMAIN'. With user buffer.
* @param rcode: rcode as integer in host order
* @param str: the string to write to.
* @param len: length of str.
* @return the number of characters for this element, excluding zerobyte.
* Is larger than str_len if output was truncated.
*/
int ldns_wire2str_rcode_buf(int rcode, char* str, size_t len);
/**
* Convert wire dname to a string, "example.com.". With user buffer.
* @param dname: the dname in uncompressed wireformat.
* @param dname_len: length of the dname.
* @param str: the string to write to.
* @param len: length of string.
* @return the number of characters for this element, excluding zerobyte.
* Is larger than str_len if output was truncated.
*/
int ldns_wire2str_dname_buf(uint8_t* dname, size_t dname_len, char* str,
size_t len);
/**
* Scan wireformat rdf field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @param rdftype: the type of the rdata field.
* @param pkt: packet for decompression, if NULL no decompression.
* @param pktlen: length of packet buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_rdf_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len, enum ldns_enum_rdf_type rdftype, uint8_t* pkt,
size_t pktlen);
/**
* Scan wireformat int8 field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_int8_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat int16 field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_int16_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat int32 field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_int32_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat period field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_period_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat tsigtime field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_tsigtime_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat ip4 A field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_a_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat ip6 AAAA field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_aaaa_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat str field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_str_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat apl field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_apl_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat b32_ext field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_b32_ext_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat b64 field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_b64_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat hex field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_hex_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat nsec bitmap field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_nsec_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat nsec3_salt field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_nsec3_salt_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat cert_alg field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_cert_alg_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat alg field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_alg_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat type unknown field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_unknown_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat time field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_time_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat LOC field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_loc_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat WKS field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_wks_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat NSAP field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_nsap_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat ATMA field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_atma_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat IPSECKEY field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @param pkt: packet for decompression, if NULL no decompression.
* @param pktlen: length of packet buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_ipseckey_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len, uint8_t* pkt, size_t pktlen);
/**
* Scan wireformat int16_data field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_int16_data_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat nsec3_next_owner field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_nsec3_next_owner_scan(uint8_t** data, size_t* data_len,
char** str, size_t* str_len);
/**
* Scan wireformat ILNP64 field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_ilnp64_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat EUI48 field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_eui48_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat EUI64 field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_eui64_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat TAG field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_tag_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Scan wireformat long_str field to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @return number of characters (except null) needed to print.
* Can return -1 on failure.
*/
int ldns_wire2str_long_str_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len);
/**
* Print EDNS LLQ option data to string. User buffers, moves string pointers.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @param option_data: buffer with EDNS option code data.
* @param option_len: length of the data for this option.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_edns_llq_print(char** str, size_t* str_len,
uint8_t* option_data, size_t option_len);
/**
* Print EDNS UL option data to string. User buffers, moves string pointers.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @param option_data: buffer with EDNS option code data.
* @param option_len: length of the data for this option.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_edns_ul_print(char** str, size_t* str_len,
uint8_t* option_data, size_t option_len);
/**
* Print EDNS NSID option data to string. User buffers, moves string pointers.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @param option_data: buffer with EDNS option code data.
* @param option_len: length of the data for this option.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_edns_nsid_print(char** str, size_t* str_len,
uint8_t* option_data, size_t option_len);
/**
* Print EDNS DAU option data to string. User buffers, moves string pointers.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @param option_data: buffer with EDNS option code data.
* @param option_len: length of the data for this option.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_edns_dau_print(char** str, size_t* str_len,
uint8_t* option_data, size_t option_len);
/**
* Print EDNS DHU option data to string. User buffers, moves string pointers.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @param option_data: buffer with EDNS option code data.
* @param option_len: length of the data for this option.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_edns_dhu_print(char** str, size_t* str_len,
uint8_t* option_data, size_t option_len);
/**
* Print EDNS N3U option data to string. User buffers, moves string pointers.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @param option_data: buffer with EDNS option code data.
* @param option_len: length of the data for this option.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_edns_n3u_print(char** str, size_t* str_len,
uint8_t* option_data, size_t option_len);
/**
* Print EDNS SUBNET option data to string. User buffers, moves string pointers.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @param option_data: buffer with EDNS option code data.
* @param option_len: length of the data for this option.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_edns_subnet_print(char** str, size_t* str_len,
uint8_t* option_data, size_t option_len);
/**
* Print an EDNS option as OPT: VALUE. User buffers, moves string pointers.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @param option_code: host format EDNS option code.
* @param option_data: buffer with EDNS option code data.
* @param option_len: length of the data for this option.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_edns_option_print(char** str, size_t* str_len,
uint16_t option_code, uint8_t* option_data, size_t option_len);
/**
* Scan wireformat EDNS OPT to string, with user buffers.
* It shifts the arguments to move along (see ldns_wire2str_pkt_scan).
* @param data: wireformat data.
* @param data_len: length of data buffer.
* @param str: string buffer.
* @param str_len: length of string buffer.
* @param pkt: packet with header and other info (may be NULL)
* @param pktlen: length of packet buffer.
* @return number of characters (except null) needed to print.
*/
int ldns_wire2str_edns_scan(uint8_t** data, size_t* data_len, char** str,
size_t* str_len, uint8_t* pkt, size_t pktlen);
#ifdef __cplusplus
}
#endif
#endif /* LDNS_WIRE2STR_H */

View File

@ -49,6 +49,7 @@
#include "services/cache/infra.h"
#include "util/data/msgreply.h"
#include "util/storage/slabhash.h"
#include "ldns/sbuffer.h"
int
context_finalize(struct ub_ctx* ctx)

View File

@ -48,6 +48,7 @@
#include "util/data/packed_rrset.h"
struct libworker;
struct tube;
struct ldns_buffer;
struct event_base;
/**
@ -281,7 +282,7 @@ uint8_t* context_serialize_new_query(struct ctx_query* q, uint32_t* len);
* @return: an alloc, or NULL on mem error.
*/
uint8_t* context_serialize_answer(struct ctx_query* q, int err,
ldns_buffer* pkt, uint32_t* len);
struct ldns_buffer* pkt, uint32_t* len);
/**
* Serialize a query cancellation. Serializes query async id

View File

@ -61,6 +61,7 @@
#include "services/localzone.h"
#include "services/cache/infra.h"
#include "services/cache/rrset.h"
#include "ldns/sbuffer.h"
#ifdef HAVE_PTHREAD
#include <signal.h>
#endif
@ -1173,18 +1174,10 @@ int ub_ctx_zone_remove(struct ub_ctx* ctx, const char *zone_name)
/* Add new RR data */
int ub_ctx_data_add(struct ub_ctx* ctx, const char *data)
{
ldns_buffer* buf;
int res = ub_ctx_finalize(ctx);
if (res) return res;
lock_basic_lock(&ctx->cfglock);
buf = ldns_buffer_new(ctx->env->cfg->msg_buffer_size);
lock_basic_unlock(&ctx->cfglock);
if(!buf) return UB_NOMEM;
res = local_zones_add_RR(ctx->local_zones, data, buf);
ldns_buffer_free(buf);
res = local_zones_add_RR(ctx->local_zones, data);
return (!res) ? UB_NOMEM : UB_NOERROR;
}

View File

@ -42,8 +42,6 @@
* returns from the procedure when done.
*/
#include "config.h"
#include <ldns/dname.h>
#include <ldns/wire2host.h>
#ifdef HAVE_SSL
#include <openssl/ssl.h>
#endif
@ -70,6 +68,8 @@
#include "util/tube.h"
#include "iterator/iter_fwd.h"
#include "iterator/iter_hints.h"
#include "ldns/sbuffer.h"
#include "ldns/str2wire.h"
/** handle new query command for bg worker */
static void handle_newq(struct libworker* w, uint8_t* buf, uint32_t len);
@ -566,22 +566,12 @@ static int
setup_qinfo_edns(struct libworker* w, struct ctx_query* q,
struct query_info* qinfo, struct edns_data* edns)
{
ldns_rdf* rdf;
qinfo->qtype = (uint16_t)q->res->qtype;
qinfo->qclass = (uint16_t)q->res->qclass;
rdf = ldns_dname_new_frm_str(q->res->qname);
if(!rdf) {
qinfo->qname = ldns_str2wire_dname(q->res->qname, &qinfo->qname_len);
if(!qinfo->qname) {
return 0;
}
#ifdef UNBOUND_ALLOC_LITE
qinfo->qname = memdup(ldns_rdf_data(rdf), ldns_rdf_size(rdf));
qinfo->qname_len = ldns_rdf_size(rdf);
ldns_rdf_deep_free(rdf);
rdf = 0;
#else
qinfo->qname = ldns_rdf_data(rdf);
qinfo->qname_len = ldns_rdf_size(rdf);
#endif
edns->edns_present = 1;
edns->ext_rcode = 0;
edns->edns_version = 0;
@ -590,7 +580,6 @@ setup_qinfo_edns(struct libworker* w, struct ctx_query* q,
edns->udp_size = (uint16_t)ldns_buffer_capacity(
w->back->udp_buff);
else edns->udp_size = 65535;
ldns_rdf_free(rdf);
return 1;
}

View File

@ -57,6 +57,7 @@ struct comm_point;
struct comm_reply;
struct regional;
struct tube;
struct ldns_buffer;
struct event_base;
/**
@ -174,15 +175,15 @@ void libworker_handle_result_write(struct tube* tube, uint8_t* msg, size_t len,
int err, void* arg);
/** mesh callback with fg results */
void libworker_fg_done_cb(void* arg, int rcode, ldns_buffer* buf,
void libworker_fg_done_cb(void* arg, int rcode, struct ldns_buffer* buf,
enum sec_status s, char* why_bogus);
/** mesh callback with bg results */
void libworker_bg_done_cb(void* arg, int rcode, ldns_buffer* buf,
void libworker_bg_done_cb(void* arg, int rcode, struct ldns_buffer* buf,
enum sec_status s, char* why_bogus);
/** mesh callback with event results */
void libworker_event_done_cb(void* arg, int rcode, ldns_buffer* buf,
void libworker_event_done_cb(void* arg, int rcode, struct ldns_buffer* buf,
enum sec_status s, char* why_bogus);
/**
@ -194,7 +195,7 @@ void libworker_event_done_cb(void* arg, int rcode, ldns_buffer* buf,
* On error, the res may contain a different status
* (out of memory is not secure, not bogus).
*/
void libworker_enter_result(struct ub_result* res, ldns_buffer* buf,
void libworker_enter_result(struct ub_result* res, struct ldns_buffer* buf,
struct regional* temp, enum sec_status msg_security);
#endif /* LIBUNBOUND_WORKER_H */

View File

@ -50,6 +50,7 @@
#include "util/net_help.h"
#include "util/regional.h"
#include "util/config_file.h"
#include "ldns/sbuffer.h"
/** store rrsets in the rrset cache.
* @param env: module environment with caches.

View File

@ -39,7 +39,7 @@
* This file contains the infrastructure cache.
*/
#include "config.h"
#include <ldns/rr.h>
#include "ldns/rrdef.h"
#include "services/cache/infra.h"
#include "util/storage/slabhash.h"
#include "util/storage/lookup3.h"

View File

@ -40,6 +40,7 @@
*/
#include "config.h"
#include "services/cache/rrset.h"
#include "ldns/rrdef.h"
#include "util/storage/slabhash.h"
#include "util/config_file.h"
#include "util/data/packed_rrset.h"

View File

@ -49,6 +49,7 @@
#include "util/log.h"
#include "util/config_file.h"
#include "util/net_help.h"
#include "ldns/sbuffer.h"
#ifdef HAVE_NETDB_H
#include <netdb.h>
@ -75,7 +76,7 @@ verbose_print_addr(struct addrinfo *addr)
#endif /* INET6 */
if(inet_ntop(addr->ai_family, sinaddr, buf,
(socklen_t)sizeof(buf)) == 0) {
strncpy(buf, "(null)", sizeof(buf));
strlcpy(buf, "(null)", sizeof(buf));
}
buf[sizeof(buf)-1] = 0;
verbose(VERB_ALGO, "creating %s%s socket %s %d",
@ -581,9 +582,9 @@ make_sock_port(int stype, const char* ifname, const char* port,
*noip6 = 0;
return -1;
}
strncpy(newif, ifname, sizeof(newif));
strlcpy(newif, ifname, sizeof(newif));
newif[s-ifname] = 0;
strncpy(p, s+1, sizeof(p));
strlcpy(p, s+1, sizeof(p));
p[strlen(s+1)]=0;
return make_sock(stype, newif, p, hints, v6only, noip6,
rcv, snd);

View File

@ -46,6 +46,7 @@
struct listen_list;
struct config_file;
struct addrinfo;
struct ldns_buffer;
/**
* Listening for queries structure.
@ -57,7 +58,7 @@ struct listen_dnsport {
/** buffer shared by UDP connections, since there is only one
datagram at any time. */
ldns_buffer* udp_buff;
struct ldns_buffer* udp_buff;
/** list of comm points used to get incoming events */
struct listen_list* cps;

View File

@ -39,9 +39,9 @@
* This file contains functions to enable local zone authority service.
*/
#include "config.h"
#include <ldns/dname.h>
#include <ldns/host2wire.h>
#include "services/localzone.h"
#include "ldns/str2wire.h"
#include "ldns/sbuffer.h"
#include "util/regional.h"
#include "util/config_file.h"
#include "util/data/dname.h"
@ -125,19 +125,10 @@ local_data_cmp(const void* d1, const void* d2)
int
parse_dname(const char* str, uint8_t** res, size_t* len, int* labs)
{
ldns_rdf* rdf;
*res = NULL;
*len = 0;
*res = ldns_str2wire_dname(str, len);
*labs = 0;
rdf = ldns_dname_new_frm_str(str);
if(!rdf) {
log_err("cannot parse name %s", str);
return 0;
}
*res = memdup(ldns_rdf_data(rdf), ldns_rdf_size(rdf));
ldns_rdf_deep_free(rdf);
if(!*res) {
log_err("out of memory");
log_err("cannot parse name %s", str);
return 0;
}
*labs = dname_count_size_labels(*res, len);
@ -225,39 +216,28 @@ lz_enter_zone(struct local_zones* zones, const char* name, const char* type,
/** return name and class and rdata of rr; parses string */
static int
get_rr_content(const char* str, uint8_t** nm, uint16_t* type,
uint16_t* dclass, time_t* ttl, ldns_buffer* rdata)
uint16_t* dclass, time_t* ttl, uint8_t* rr, size_t len,
uint8_t** rdata, size_t* rdata_len)
{
ldns_rr* rr = NULL;
ldns_status status = ldns_rr_new_frm_str(&rr, str, 3600, NULL, NULL);
if(status != LDNS_STATUS_OK) {
log_err("error parsing local-data '%s': %s",
str, ldns_get_errorstr_by_id(status));
ldns_rr_free(rr);
size_t dname_len = 0;
int e = ldns_str2wire_rr_buf(str, rr, &len, &dname_len, 3600,
NULL, 0, NULL, 0);
if(e) {
log_err("error parsing local-data at %d: '%s': %s",
LDNS_WIREPARSE_OFFSET(e), str,
ldns_get_errorstr_parse(e));
return 0;
}
*nm = memdup(ldns_rdf_data(ldns_rr_owner(rr)),
ldns_rdf_size(ldns_rr_owner(rr)));
*nm = memdup(rr, dname_len);
if(!*nm) {
log_err("out of memory");
ldns_rr_free(rr);
return 0;
}
*dclass = ldns_rr_get_class(rr);
*type = ldns_rr_get_type(rr);
*ttl = (time_t)ldns_rr_ttl(rr);
ldns_buffer_clear(rdata);
ldns_buffer_skip(rdata, 2);
status = ldns_rr_rdata2buffer_wire(rdata, rr);
ldns_rr_free(rr);
if(status != LDNS_STATUS_OK) {
log_err("error converting RR '%s' to wireformat: %s",
str, ldns_get_errorstr_by_id(status));
free(*nm);
*nm = NULL;
return 0;
}
ldns_buffer_flip(rdata);
ldns_buffer_write_u16_at(rdata, 0, ldns_buffer_limit(rdata) - 2);
*dclass = ldns_wirerr_get_class(rr, len, dname_len);
*type = ldns_wirerr_get_type(rr, len, dname_len);
*ttl = (time_t)ldns_wirerr_get_ttl(rr, len, dname_len);
*rdata = ldns_wirerr_get_rdatawl(rr, len, dname_len);
*rdata_len = ldns_wirerr_get_rdatalen(rr, len, dname_len)+2;
return 1;
}
@ -265,18 +245,18 @@ get_rr_content(const char* str, uint8_t** nm, uint16_t* type,
static int
get_rr_nameclass(const char* str, uint8_t** nm, uint16_t* dclass)
{
ldns_rr* rr = NULL;
ldns_status status = ldns_rr_new_frm_str(&rr, str, 3600, NULL, NULL);
if(status != LDNS_STATUS_OK) {
log_err("error parsing local-data '%s': %s",
str, ldns_get_errorstr_by_id(status));
ldns_rr_free(rr);
uint8_t rr[LDNS_RR_BUF_SIZE];
size_t len = sizeof(rr), dname_len = 0;
int s = ldns_str2wire_rr_buf(str, rr, &len, &dname_len, 3600,
NULL, 0, NULL, 0);
if(s != 0) {
log_err("error parsing local-data at %d '%s': %s",
LDNS_WIREPARSE_OFFSET(s), str,
ldns_get_errorstr_parse(s));
return 0;
}
*nm = memdup(ldns_rdf_data(ldns_rr_owner(rr)),
ldns_rdf_size(ldns_rr_owner(rr)));
*dclass = ldns_rr_get_class(rr);
ldns_rr_free(rr);
*nm = memdup(rr, dname_len);
*dclass = ldns_wirerr_get_class(rr, len, dname_len);
if(!*nm) {
log_err("out of memory");
return 0;
@ -304,13 +284,12 @@ local_data_find_type(struct local_data* data, uint16_t type)
/** check for RR duplicates */
static int
rr_is_duplicate(struct packed_rrset_data* pd, ldns_buffer* buf)
rr_is_duplicate(struct packed_rrset_data* pd, uint8_t* rdata, size_t rdata_len)
{
size_t i;
for(i=0; i<pd->count; i++) {
if(ldns_buffer_limit(buf) == pd->rr_len[i] &&
memcmp(ldns_buffer_begin(buf), pd->rr_data[i],
ldns_buffer_limit(buf)) == 0)
if(pd->rr_len[i] == rdata_len &&
memcmp(pd->rr_data[i], rdata, rdata_len) == 0)
return 1;
}
return 0;
@ -356,7 +335,7 @@ new_local_rrset(struct regional* region, struct local_data* node,
/** insert RR into RRset data structure; Wastes a couple of bytes */
static int
insert_rr(struct regional* region, struct packed_rrset_data* pd,
ldns_buffer* buf, time_t ttl)
uint8_t* rdata, size_t rdata_len, time_t ttl)
{
size_t* oldlen = pd->rr_len;
time_t* oldttl = pd->rr_ttl;
@ -379,10 +358,9 @@ insert_rr(struct regional* region, struct packed_rrset_data* pd,
memcpy(pd->rr_data+1, olddata,
sizeof(*pd->rr_data)*(pd->count-1));
}
pd->rr_len[0] = ldns_buffer_limit(buf);
pd->rr_len[0] = rdata_len;
pd->rr_ttl[0] = ttl;
pd->rr_data[0] = regional_alloc_init(region,
ldns_buffer_begin(buf), ldns_buffer_limit(buf));
pd->rr_data[0] = regional_alloc_init(region, rdata, rdata_len);
if(!pd->rr_data[0]) {
log_err("out of memory");
return 0;
@ -440,8 +418,7 @@ lz_find_create_node(struct local_zone* z, uint8_t* nm, size_t nmlen,
/** enter data RR into auth zone */
static int
lz_enter_rr_into_zone(struct local_zone* z, ldns_buffer* buf,
const char* rrstr)
lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr)
{
uint8_t* nm;
size_t nmlen;
@ -451,7 +428,11 @@ lz_enter_rr_into_zone(struct local_zone* z, ldns_buffer* buf,
struct packed_rrset_data* pd;
uint16_t rrtype = 0, rrclass = 0;
time_t ttl = 0;
if(!get_rr_content(rrstr, &nm, &rrtype, &rrclass, &ttl, buf)) {
uint8_t rr[LDNS_RR_BUF_SIZE];
uint8_t* rdata;
size_t rdata_len;
if(!get_rr_content(rrstr, &nm, &rrtype, &rrclass, &ttl, rr, sizeof(rr),
&rdata, &rdata_len)) {
log_err("bad local-data: %s", rrstr);
return 0;
}
@ -487,16 +468,16 @@ lz_enter_rr_into_zone(struct local_zone* z, ldns_buffer* buf,
log_assert(rrset && pd);
/* check for duplicate RR */
if(rr_is_duplicate(pd, buf)) {
if(rr_is_duplicate(pd, rdata, rdata_len)) {
verbose(VERB_ALGO, "ignoring duplicate RR: %s", rrstr);
return 1;
}
return insert_rr(z->region, pd, buf, ttl);
return insert_rr(z->region, pd, rdata, rdata_len, ttl);
}
/** enter a data RR into auth data; a zone for it must exist */
static int
lz_enter_rr_str(struct local_zones* zones, const char* rr, ldns_buffer* buf)
lz_enter_rr_str(struct local_zones* zones, const char* rr)
{
uint8_t* rr_name;
uint16_t rr_class;
@ -518,7 +499,7 @@ lz_enter_rr_str(struct local_zones* zones, const char* rr, ldns_buffer* buf)
lock_rw_wrlock(&z->lock);
lock_quick_unlock(&zones->lock);
free(rr_name);
r = lz_enter_rr_into_zone(z, buf, rr);
r = lz_enter_rr_into_zone(z, rr);
lock_rw_unlock(&z->lock);
return r;
}
@ -582,7 +563,7 @@ lz_nodefault(struct config_file* cfg, const char* name)
/** enter AS112 default zone */
static int
add_as112_default(struct local_zones* zones, struct config_file* cfg,
ldns_buffer* buf, const char* name)
const char* name)
{
struct local_zone* z;
char str[1024]; /* known long enough */
@ -592,12 +573,12 @@ add_as112_default(struct local_zones* zones, struct config_file* cfg,
return 0;
snprintf(str, sizeof(str), "%s 10800 IN SOA localhost. "
"nobody.invalid. 1 3600 1200 604800 10800", name);
if(!lz_enter_rr_into_zone(z, buf, str)) {
if(!lz_enter_rr_into_zone(z, str)) {
lock_rw_unlock(&z->lock);
return 0;
}
snprintf(str, sizeof(str), "%s 10800 IN NS localhost. ", name);
if(!lz_enter_rr_into_zone(z, buf, str)) {
if(!lz_enter_rr_into_zone(z, str)) {
lock_rw_unlock(&z->lock);
return 0;
}
@ -607,8 +588,7 @@ add_as112_default(struct local_zones* zones, struct config_file* cfg,
/** enter default zones */
static int
lz_enter_defaults(struct local_zones* zones, struct config_file* cfg,
ldns_buffer* buf)
lz_enter_defaults(struct local_zones* zones, struct config_file* cfg)
{
struct local_zone* z;
@ -619,14 +599,14 @@ lz_enter_defaults(struct local_zones* zones, struct config_file* cfg,
!lz_nodefault(cfg, "localhost.")) {
if(!(z=lz_enter_zone(zones, "localhost.", "static",
LDNS_RR_CLASS_IN)) ||
!lz_enter_rr_into_zone(z, buf,
!lz_enter_rr_into_zone(z,
"localhost. 10800 IN NS localhost.") ||
!lz_enter_rr_into_zone(z, buf,
!lz_enter_rr_into_zone(z,
"localhost. 10800 IN SOA localhost. nobody.invalid. "
"1 3600 1200 604800 10800") ||
!lz_enter_rr_into_zone(z, buf,
!lz_enter_rr_into_zone(z,
"localhost. 10800 IN A 127.0.0.1") ||
!lz_enter_rr_into_zone(z, buf,
!lz_enter_rr_into_zone(z,
"localhost. 10800 IN AAAA ::1")) {
log_err("out of memory adding default zone");
if(z) { lock_rw_unlock(&z->lock); }
@ -639,12 +619,12 @@ lz_enter_defaults(struct local_zones* zones, struct config_file* cfg,
!lz_nodefault(cfg, "127.in-addr.arpa.")) {
if(!(z=lz_enter_zone(zones, "127.in-addr.arpa.", "static",
LDNS_RR_CLASS_IN)) ||
!lz_enter_rr_into_zone(z, buf,
!lz_enter_rr_into_zone(z,
"127.in-addr.arpa. 10800 IN NS localhost.") ||
!lz_enter_rr_into_zone(z, buf,
!lz_enter_rr_into_zone(z,
"127.in-addr.arpa. 10800 IN SOA localhost. "
"nobody.invalid. 1 3600 1200 604800 10800") ||
!lz_enter_rr_into_zone(z, buf,
!lz_enter_rr_into_zone(z,
"1.0.0.127.in-addr.arpa. 10800 IN PTR localhost.")) {
log_err("out of memory adding default zone");
if(z) { lock_rw_unlock(&z->lock); }
@ -657,12 +637,12 @@ lz_enter_defaults(struct local_zones* zones, struct config_file* cfg,
!lz_nodefault(cfg, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.")) {
if(!(z=lz_enter_zone(zones, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", "static",
LDNS_RR_CLASS_IN)) ||
!lz_enter_rr_into_zone(z, buf,
!lz_enter_rr_into_zone(z,
"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN NS localhost.") ||
!lz_enter_rr_into_zone(z, buf,
!lz_enter_rr_into_zone(z,
"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN SOA localhost. "
"nobody.invalid. 1 3600 1200 604800 10800") ||
!lz_enter_rr_into_zone(z, buf,
!lz_enter_rr_into_zone(z,
"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN PTR localhost.")) {
log_err("out of memory adding default zone");
if(z) { lock_rw_unlock(&z->lock); }
@ -670,37 +650,37 @@ lz_enter_defaults(struct local_zones* zones, struct config_file* cfg,
}
lock_rw_unlock(&z->lock);
}
if ( !add_as112_default(zones, cfg, buf, "10.in-addr.arpa.") ||
!add_as112_default(zones, cfg, buf, "16.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, buf, "17.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, buf, "18.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, buf, "19.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, buf, "20.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, buf, "21.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, buf, "22.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, buf, "23.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, buf, "24.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, buf, "25.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, buf, "26.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, buf, "27.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, buf, "28.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, buf, "29.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, buf, "30.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, buf, "31.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, buf, "168.192.in-addr.arpa.") ||
!add_as112_default(zones, cfg, buf, "0.in-addr.arpa.") ||
!add_as112_default(zones, cfg, buf, "254.169.in-addr.arpa.") ||
!add_as112_default(zones, cfg, buf, "2.0.192.in-addr.arpa.") ||
!add_as112_default(zones, cfg, buf, "100.51.198.in-addr.arpa.") ||
!add_as112_default(zones, cfg, buf, "113.0.203.in-addr.arpa.") ||
!add_as112_default(zones, cfg, buf, "255.255.255.255.in-addr.arpa.") ||
!add_as112_default(zones, cfg, buf, "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.") ||
!add_as112_default(zones, cfg, buf, "d.f.ip6.arpa.") ||
!add_as112_default(zones, cfg, buf, "8.e.f.ip6.arpa.") ||
!add_as112_default(zones, cfg, buf, "9.e.f.ip6.arpa.") ||
!add_as112_default(zones, cfg, buf, "a.e.f.ip6.arpa.") ||
!add_as112_default(zones, cfg, buf, "b.e.f.ip6.arpa.") ||
!add_as112_default(zones, cfg, buf, "8.b.d.0.1.0.0.2.ip6.arpa.")) {
if ( !add_as112_default(zones, cfg, "10.in-addr.arpa.") ||
!add_as112_default(zones, cfg, "16.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, "17.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, "18.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, "19.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, "20.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, "21.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, "22.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, "23.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, "24.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, "25.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, "26.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, "27.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, "28.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, "29.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, "30.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, "31.172.in-addr.arpa.") ||
!add_as112_default(zones, cfg, "168.192.in-addr.arpa.") ||
!add_as112_default(zones, cfg, "0.in-addr.arpa.") ||
!add_as112_default(zones, cfg, "254.169.in-addr.arpa.") ||
!add_as112_default(zones, cfg, "2.0.192.in-addr.arpa.") ||
!add_as112_default(zones, cfg, "100.51.198.in-addr.arpa.") ||
!add_as112_default(zones, cfg, "113.0.203.in-addr.arpa.") ||
!add_as112_default(zones, cfg, "255.255.255.255.in-addr.arpa.") ||
!add_as112_default(zones, cfg, "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.") ||
!add_as112_default(zones, cfg, "d.f.ip6.arpa.") ||
!add_as112_default(zones, cfg, "8.e.f.ip6.arpa.") ||
!add_as112_default(zones, cfg, "9.e.f.ip6.arpa.") ||
!add_as112_default(zones, cfg, "a.e.f.ip6.arpa.") ||
!add_as112_default(zones, cfg, "b.e.f.ip6.arpa.") ||
!add_as112_default(zones, cfg, "8.b.d.0.1.0.0.2.ip6.arpa.")) {
log_err("out of memory adding default zone");
return 0;
}
@ -825,12 +805,11 @@ lz_setup_implicit(struct local_zones* zones, struct config_file* cfg)
/** enter auth data */
static int
lz_enter_data(struct local_zones* zones, struct config_file* cfg,
ldns_buffer* buf)
lz_enter_data(struct local_zones* zones, struct config_file* cfg)
{
struct config_strlist* p;
for(p = cfg->local_data; p; p = p->next) {
if(!lz_enter_rr_str(zones, p->str, buf))
if(!lz_enter_rr_str(zones, p->str))
return 0;
}
return 1;
@ -851,35 +830,27 @@ lz_freeup_cfg(struct config_file* cfg)
int
local_zones_apply_cfg(struct local_zones* zones, struct config_file* cfg)
{
ldns_buffer* buf = ldns_buffer_new(65535);
if(!buf) fatal_exit("cannot create temporary buffer");
/* create zones from zone statements. */
if(!lz_enter_zones(zones, cfg)) {
ldns_buffer_free(buf);
return 0;
}
/* apply default zones+content (unless disabled, or overridden) */
if(!lz_enter_defaults(zones, cfg, buf)) {
ldns_buffer_free(buf);
if(!lz_enter_defaults(zones, cfg)) {
return 0;
}
/* create implicit transparent zone from data. */
if(!lz_setup_implicit(zones, cfg)) {
ldns_buffer_free(buf);
return 0;
}
/* setup parent ptrs for lookup during data entry */
init_parents(zones);
/* insert local data */
if(!lz_enter_data(zones, cfg, buf)) {
ldns_buffer_free(buf);
if(!lz_enter_data(zones, cfg)) {
return 0;
}
/* freeup memory from cfg struct. */
lz_freeup_cfg(cfg);
ldns_buffer_free(buf);
return 1;
}
@ -1255,7 +1226,7 @@ void local_zones_del_zone(struct local_zones* zones, struct local_zone* z)
}
int
local_zones_add_RR(struct local_zones* zones, const char* rr, ldns_buffer* buf)
local_zones_add_RR(struct local_zones* zones, const char* rr)
{
uint8_t* rr_name;
uint16_t rr_class;
@ -1281,7 +1252,7 @@ local_zones_add_RR(struct local_zones* zones, const char* rr, ldns_buffer* buf)
}
lock_rw_wrlock(&z->lock);
lock_quick_unlock(&zones->lock);
r = lz_enter_rr_into_zone(z, buf, rr);
r = lz_enter_rr_into_zone(z, rr);
lock_rw_unlock(&z->lock);
return r;
}

View File

@ -48,6 +48,7 @@ struct regional;
struct config_file;
struct edns_data;
struct query_info;
struct ldns_buffer;
/**
* Local zone type
@ -224,7 +225,7 @@ void local_zones_print(struct local_zones* zones);
* value is true, but the buffer is cleared (empty).
*/
int local_zones_answer(struct local_zones* zones, struct query_info* qinfo,
struct edns_data* edns, ldns_buffer* buf, struct regional* temp);
struct edns_data* edns, struct ldns_buffer* buf, struct regional* temp);
/**
* Parse the string into localzone type.
@ -286,11 +287,9 @@ void local_zones_del_zone(struct local_zones* zones, struct local_zone* zone);
* name of the RR is created.
* @param zones: the zones tree. Not locked by caller.
* @param rr: string with on RR.
* @param buf: buffer for scratch.
* @return false on failure.
*/
int local_zones_add_RR(struct local_zones* zones, const char* rr,
ldns_buffer* buf);
int local_zones_add_RR(struct local_zones* zones, const char* rr);
/**
* Remove data from domain name in the tree.

View File

@ -43,7 +43,6 @@
* send back to clients.
*/
#include "config.h"
#include <ldns/wire2host.h>
#include "services/mesh.h"
#include "services/outbound_list.h"
#include "services/cache/dns.h"
@ -56,6 +55,7 @@
#include "util/fptr_wlist.h"
#include "util/alloc.h"
#include "util/config_file.h"
#include "ldns/sbuffer.h"
/** subtract timers and the values do not overflow or become negative */
static void

View File

@ -51,6 +51,7 @@
#include "util/data/msgparse.h"
#include "util/module.h"
#include "services/modstack.h"
struct ldns_buffer;
struct mesh_state;
struct mesh_reply;
struct mesh_cb;
@ -125,7 +126,7 @@ struct mesh_area {
/** backup of query if other operations recurse and need the
* network buffers */
ldns_buffer* qbuf_bak;
struct ldns_buffer* qbuf_bak;
/** double linked list of the run-to-completion query states.
* These are query states with a reply */
@ -219,7 +220,7 @@ struct mesh_reply {
* Mesh result callback func.
* called as func(cb_arg, rcode, buffer_with_reply, security, why_bogus);
*/
typedef void (*mesh_cb_func_t)(void*, int, ldns_buffer*, enum sec_status,
typedef void (*mesh_cb_func_t)(void*, int, struct ldns_buffer*, enum sec_status,
char*);
/**
@ -235,7 +236,7 @@ struct mesh_cb {
/** flags of query, for reply flags */
uint16_t qflags;
/** buffer for reply */
ldns_buffer* buf;
struct ldns_buffer* buf;
/** callback routine for results. if rcode != 0 buf has message.
* called as cb(cb_arg, rcode, buf, sec_state);
@ -294,7 +295,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
* @return 0 on error.
*/
int mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
uint16_t qflags, struct edns_data* edns, ldns_buffer* buf,
uint16_t qflags, struct edns_data* edns, struct ldns_buffer* buf,
uint16_t qid, mesh_cb_func_t cb, void* cb_arg);
/**
@ -473,7 +474,7 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
* @return: 0 on alloc error.
*/
int mesh_state_add_cb(struct mesh_state* s, struct edns_data* edns,
ldns_buffer* buf, mesh_cb_func_t cb, void* cb_arg, uint16_t qid,
struct ldns_buffer* buf, mesh_cb_func_t cb, void* cb_arg, uint16_t qid,
uint16_t qflags);
/**
@ -548,7 +549,7 @@ int mesh_state_ref_compare(const void* ap, const void* bp);
* You can pass NULL if there is no buffer that must be backed up.
* @return false if no space is available.
*/
int mesh_make_new_space(struct mesh_area* mesh, ldns_buffer* qbuf);
int mesh_make_new_space(struct mesh_area* mesh, struct ldns_buffer* qbuf);
/**
* Insert mesh state into a double linked list. Inserted at end.

View File

@ -45,7 +45,6 @@
# include <sys/types.h>
#endif
#include <sys/time.h>
#include <ldns/wire2host.h>
#include "services/outside_network.h"
#include "services/listen_dnsport.h"
#include "services/cache/infra.h"
@ -58,6 +57,7 @@
#include "util/net_help.h"
#include "util/random.h"
#include "util/fptr_wlist.h"
#include "ldns/sbuffer.h"
#ifdef HAVE_OPENSSL_SSL_H
#include <openssl/ssl.h>
#endif

View File

@ -54,6 +54,7 @@ struct waiting_udp;
struct infra_cache;
struct port_comm;
struct port_if;
struct ldns_buffer;
/**
* Send queries to outside servers and wait for answers from servers.
@ -69,7 +70,7 @@ struct outside_network {
/** buffer shared by UDP connections, since there is only one
datagram at any time. */
ldns_buffer* udp_buff;
struct ldns_buffer* udp_buff;
/** serviced_callbacks malloc overhead when processing multiple
* identical serviced queries to the same server. */
size_t svcd_overhead;
@ -411,7 +412,7 @@ void outside_network_quit_prepare(struct outside_network* outnet);
* @return: NULL on error for malloc or socket. Else the pending query object.
*/
struct pending* pending_udp_query(struct outside_network* outnet,
ldns_buffer* packet, struct sockaddr_storage* addr,
struct ldns_buffer* packet, struct sockaddr_storage* addr,
socklen_t addrlen, int timeout, comm_point_callback_t* callback,
void* callback_arg);
@ -431,7 +432,7 @@ struct pending* pending_udp_query(struct outside_network* outnet,
* @return: false on error for malloc or socket. Else the pending TCP object.
*/
struct waiting_tcp* pending_tcp_query(struct outside_network* outnet,
ldns_buffer* packet, struct sockaddr_storage* addr,
struct ldns_buffer* packet, struct sockaddr_storage* addr,
socklen_t addrlen, int timeout, comm_point_callback_t* callback,
void* callback_arg, int ssl_upstream);
@ -476,7 +477,7 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
uint16_t flags, int dnssec, int want_dnssec, int tcp_upstream,
int ssl_upstream, struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* zone, size_t zonelen, comm_point_callback_t* callback,
void* callback_arg, ldns_buffer* buff);
void* callback_arg, struct ldns_buffer* buff);
/**
* Remove service query callback.

View File

@ -116,7 +116,7 @@
#include "config.h"
#include "libunbound/unbound.h"
#include <ldns/rr.h>
#include "ldns/rrdef.h"
#include <expat.h>
#ifndef HAVE_EXPAT_H
#error "need libexpat to parse root-anchors.xml file."
@ -669,6 +669,15 @@ count_unused(struct ip_list* p)
return num;
}
static int get_random(void)
{
int r;
if (RAND_bytes((unsigned char*)&r, (int)sizeof(r)) == 1) {
return r;
}
return (int)random();
}
/** pick random unused element from IP list */
static struct ip_list*
pick_random_ip(struct ip_list* list)
@ -678,7 +687,7 @@ pick_random_ip(struct ip_list* list)
int sel;
if(num == 0) return NULL;
/* not perfect, but random enough */
sel = (int)ldns_get_random() % num;
sel = get_random() % num;
/* skip over unused elements that we did not select */
while(sel > 0 && p) {
if(!p->used) sel--;

View File

@ -53,6 +53,7 @@
#include "iterator/iter_hints.h"
#include "validator/validator.h"
#include "services/localzone.h"
#include "ldns/sbuffer.h"
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
@ -343,9 +344,9 @@ morechecks(struct config_file* cfg, const char* fname)
if(fname[0] != '/') {
if(getcwd(buf, sizeof(buf)) == NULL)
fatal_exit("getcwd: %s", strerror(errno));
strncat(buf, "/", sizeof(buf)-strlen(buf)-1);
strlcat(buf, "/", sizeof(buf));
}
strncat(buf, fname, sizeof(buf)-strlen(buf)-1);
strlcat(buf, fname, sizeof(buf));
if(strncmp(buf, cfg->chrootdir, strlen(cfg->chrootdir)) != 0)
fatal_exit("config file %s is not inside chroot %s",
buf, cfg->chrootdir);

View File

@ -60,7 +60,8 @@
#define unbound_lite_wrapstr(s) s
#endif
#include "libunbound/unbound.h"
#include <ldns/ldns.h>
#include "ldns/rrdef.h"
#include "ldns/wire2str.h"
#ifdef HAVE_NSS
/* nss3 */
#include "nss.h"
@ -215,61 +216,36 @@ secure_str(struct ub_result* result)
static void
pretty_type(char* s, size_t len, int t)
{
char* d = ldns_rr_type2str(t);
char d[16];
ldns_wire2str_type_buf((uint16_t)t, d, sizeof(d));
snprintf(s, len, "%s", d);
free(d);
}
/** nice string for class */
static void
pretty_class(char* s, size_t len, int c)
{
char* d = ldns_rr_class2str(c);
char d[16];
ldns_wire2str_class_buf((uint16_t)c, d, sizeof(d));
snprintf(s, len, "%s", d);
free(d);
}
/** nice string for rcode */
static void
pretty_rcode(char* s, size_t len, int r)
{
ldns_lookup_table *rcode = ldns_lookup_by_id(ldns_rcodes, r);
if(rcode) {
snprintf(s, len, "%s", rcode->name);
} else {
snprintf(s, len, "RCODE%d", r);
}
char d[16];
ldns_wire2str_rcode_buf(r, d, sizeof(d));
snprintf(s, len, "%s", d);
}
/** convert and print rdata */
static void
print_rd(int t, char* data, size_t len)
{
size_t i, pos = 0;
uint8_t* rd = (uint8_t*)malloc(len+2);
ldns_rr* rr = ldns_rr_new();
ldns_status status;
if(!rd || !rr) {
fprintf(stderr, "out of memory");
exit(1);
}
ldns_rr_set_type(rr, t);
ldns_write_uint16(rd, len);
memmove(rd+2, data, len);
ldns_rr_set_owner(rr, NULL);
status = ldns_wire2rdf(rr, rd, len+2, &pos);
if(status != LDNS_STATUS_OK) {
free(rd);
ldns_rr_free(rr);
printf("error_printing_data");
return;
}
for(i=0; i<ldns_rr_rd_count(rr); i++) {
printf(" ");
ldns_rdf_print(stdout, ldns_rr_rdf(rr, i));
}
ldns_rr_free(rr);
free(rd);
char s[65535];
ldns_wire2str_rdata_buf((uint8_t*)data, len, s, sizeof(s), (uint16_t)t);
printf(" %s", s);
}
/** pretty line of RR data for results */
@ -344,24 +320,14 @@ pretty_output(char* q, int t, int c, struct ub_result* result, int docname)
else if(t == LDNS_RR_TYPE_MX)
printf(" has no mail handler record");
else if(t == LDNS_RR_TYPE_ANY) {
ldns_pkt* p = NULL;
if(ldns_wire2pkt(&p, result->answer_packet,
(size_t)result->answer_len)==LDNS_STATUS_OK){
if(ldns_rr_list_rr_count(
ldns_pkt_answer(p)) == 0)
printf(" has no records\n");
else {
printf(" ANY:\n");
ldns_rr_list_print(stdout,
ldns_pkt_answer(p));
}
} else {
fprintf(stderr, "could not parse "
"reply packet to ANY query\n");
char* s = ldns_wire2str_pkt(
result->answer_packet,
(size_t)result->answer_len);
if(!s) {
fprintf(stderr, "alloc failure\n");
exit(1);
}
ldns_pkt_free(p);
printf("%s\n", s);
} else printf(" has no %s record", tstr);
printf(" %s\n", secstatus);
}

View File

@ -166,21 +166,21 @@ void libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube),
}
void libworker_fg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
struct ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
char* ATTR_UNUSED(why_bogus))
{
log_assert(0);
}
void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
struct ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
char* ATTR_UNUSED(why_bogus))
{
log_assert(0);
}
void libworker_event_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
struct ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
char* ATTR_UNUSED(why_bogus))
{
log_assert(0);

View File

@ -48,6 +48,7 @@
#include "libunbound/context.h"
#include "util/locks.h"
#include "util/log.h"
#include "ldns/rrdef.h"
#ifdef UNBOUND_ALLOC_LITE
#undef malloc
#undef calloc

View File

@ -50,6 +50,7 @@
#include <sys/time.h>
#include "util/net_help.h"
#include "util/config_file.h"
#include "ldns/sbuffer.h"
#include <signal.h>
/** number of reads per select for delayer */
@ -889,12 +890,12 @@ proxy_list_clear(struct proxy* p)
if(inet_ntop(AF_INET6,
&((struct sockaddr_in6*)&p->addr)->sin6_addr,
from, (socklen_t)sizeof(from)) == 0)
strncpy(from, "err", sizeof(from));
strlcpy(from, "err", sizeof(from));
} else {
if(inet_ntop(AF_INET,
&((struct sockaddr_in*)&p->addr)->sin_addr,
from, (socklen_t)sizeof(from)) == 0)
strncpy(from, "err", sizeof(from));
strlcpy(from, "err", sizeof(from));
}
printf("client[%d]: last %s@%d of %d : %u in, %u out, "
"%u returned\n", i++, from, port, (int)p->numreuse+1,

View File

@ -57,9 +57,12 @@
#include "services/outside_network.h"
#include "services/cache/infra.h"
#include "testcode/replay.h"
#include "testcode/ldns-testpkts.h"
#include "testcode/testpkts.h"
#include "util/log.h"
#include "util/fptr_wlist.h"
#include "ldns/sbuffer.h"
#include "ldns/wire2str.h"
#include "ldns/str2wire.h"
#include <signal.h>
struct worker;
struct daemon_remote;
@ -108,11 +111,11 @@ fake_event_cleanup(void)
/** helper function that logs a ldns_pkt packet to logfile */
static void
log_pkt(const char* desc, ldns_pkt* pkt)
log_pkt(const char* desc, uint8_t* pkt, size_t len)
{
char* str = ldns_pkt2str(pkt);
char* str = ldns_wire2str_pkt(pkt, len);
if(!str)
log_info("%s: (failed)", desc);
fatal_exit("%s: (failed out of memory wire2str_pkt)", desc);
else {
log_info("%s%s", desc, str);
free(str);
@ -150,7 +153,7 @@ delete_fake_pending(struct fake_pending* pend)
return;
free(pend->zone);
ldns_buffer_free(pend->buffer);
ldns_pkt_free(pend->pkt);
free(pend->pkt);
free(pend);
}
@ -164,7 +167,7 @@ delete_replay_answer(struct replay_answer* a)
ldns_buffer_free(a->repinfo.c->buffer);
free(a->repinfo.c);
}
ldns_pkt_free(a->pkt);
free(a->pkt);
free(a);
}
@ -186,7 +189,8 @@ pending_matches_current(struct replay_runtime* runtime,
sockaddr_cmp(&p->addr, p->addrlen, &runtime->now->addr,
runtime->now->addrlen) != 0)
continue;
if((e=find_match(runtime->now->match, p->pkt, p->transport))) {
if((e=find_match(runtime->now->match, p->pkt, p->pkt_len,
p->transport))) {
*entry = e;
*pend = p;
return 1;
@ -212,13 +216,16 @@ pending_find_match(struct replay_runtime* runtime, struct entry** entry,
if(p->start_step <= timenow && timenow <= p->end_step &&
(p->addrlen == 0 || sockaddr_cmp(&p->addr, p->addrlen,
&pend->addr, pend->addrlen) == 0) &&
(*entry = find_match(p->match, pend->pkt, pend->transport))) {
(*entry = find_match(p->match, pend->pkt, pend->pkt_len,
pend->transport))) {
log_info("matched query time %d in range [%d, %d] "
"with entry line %d", timenow,
p->start_step, p->end_step, (*entry)->lineno);
if(p->addrlen != 0)
log_addr(0, "matched ip", &p->addr, p->addrlen);
log_pkt("matched pkt: ", (*entry)->reply_list->reply);
log_pkt("matched pkt: ",
(*entry)->reply_list->reply_pkt,
(*entry)->reply_list->reply_len);
return 1;
}
p = p->next_range;
@ -275,31 +282,26 @@ pending_list_delete(struct replay_runtime* runtime, struct fake_pending* pend)
* Fill buffer with reply from the entry.
*/
static void
fill_buffer_with_reply(ldns_buffer* buffer, struct entry* entry, ldns_pkt* q)
fill_buffer_with_reply(ldns_buffer* buffer, struct entry* entry, uint8_t* q,
size_t qlen)
{
ldns_status status;
ldns_pkt* answer_pkt = NULL;
uint8_t* c;
size_t clen;
log_assert(entry && entry->reply_list);
ldns_buffer_clear(buffer);
if(entry->reply_list->reply_from_hex) {
status = ldns_buffer2pkt_wire(&answer_pkt,
entry->reply_list->reply_from_hex);
if(status != LDNS_STATUS_OK) {
log_err("testbound: hex packet unparsable, used asis.");
ldns_buffer_write(buffer,
ldns_buffer_begin(entry->reply_list->reply_from_hex),
ldns_buffer_limit(entry->reply_list->reply_from_hex));
}
c = ldns_buffer_begin(entry->reply_list->reply_from_hex);
clen = ldns_buffer_limit(entry->reply_list->reply_from_hex);
if(!c) fatal_exit("out of memory");
} else {
answer_pkt = ldns_pkt_clone(entry->reply_list->reply);
c = entry->reply_list->reply_pkt;
clen = entry->reply_list->reply_len;
}
if(answer_pkt) {
if(q) adjust_packet(entry, answer_pkt, q);
status = ldns_pkt2buffer_wire(buffer, answer_pkt);
if(status != LDNS_STATUS_OK)
fatal_exit("ldns: cannot pkt2buffer_wire parsed pkt");
if(c) {
if(q) adjust_packet(entry, &c, &clen, q, qlen);
ldns_buffer_write(buffer, c, clen);
if(q) free(c);
}
ldns_pkt_free(answer_pkt);
ldns_buffer_flip(buffer);
}
@ -324,7 +326,7 @@ answer_callback_from_entry(struct replay_runtime* runtime,
c.type = comm_udp;
if(pend->transport == transport_tcp)
c.type = comm_tcp;
fill_buffer_with_reply(c.buffer, entry, pend->pkt);
fill_buffer_with_reply(c.buffer, entry, pend->pkt, pend->pkt_len);
repinfo.c = &c;
repinfo.addrlen = pend->addrlen;
memcpy(&repinfo.addr, &pend->addr, pend->addrlen);
@ -351,7 +353,8 @@ answer_check_it(struct replay_runtime* runtime)
if((runtime->now->addrlen == 0 || sockaddr_cmp(
&runtime->now->addr, runtime->now->addrlen,
&ans->repinfo.addr, ans->repinfo.addrlen) == 0) &&
find_match(runtime->now->match, ans->pkt, tr)) {
find_match(runtime->now->match, ans->pkt,
ans->pkt_len, tr)) {
log_info("testbound matched event entry from line %d",
runtime->now->match->lineno);
log_info("testbound: do STEP %d %s",
@ -394,9 +397,10 @@ fake_front_query(struct replay_runtime* runtime, struct replay_moment *todo)
if(todo->match->match_transport == transport_tcp)
repinfo.c->type = comm_tcp;
else repinfo.c->type = comm_udp;
fill_buffer_with_reply(repinfo.c->buffer, todo->match, NULL);
fill_buffer_with_reply(repinfo.c->buffer, todo->match, NULL, 0);
log_info("testbound: incoming QUERY");
log_pkt("query pkt", todo->match->reply_list->reply);
log_pkt("query pkt", todo->match->reply_list->reply_pkt,
todo->match->reply_list->reply_len);
/* call the callback for incoming queries */
if((*runtime->callback_query)(repinfo.c, runtime->cb_arg,
NETEVENT_NOERROR, &repinfo)) {
@ -424,13 +428,13 @@ fake_pending_callback(struct replay_runtime* runtime,
if(!p) fatal_exit("No pending queries.");
cb_arg = p->cb_arg;
cb = p->callback;
log_assert(todo->qname == NULL); /* or find that one */
c.buffer = ldns_buffer_new(runtime->bufsize);
c.type = comm_udp;
if(p->transport == transport_tcp)
c.type = comm_tcp;
if(todo->evt_type == repevt_back_reply && todo->match) {
fill_buffer_with_reply(c.buffer, todo->match, p->pkt);
fill_buffer_with_reply(c.buffer, todo->match, p->pkt,
p->pkt_len);
}
repinfo.c = &c;
repinfo.addrlen = p->addrlen;
@ -552,16 +556,17 @@ do_infra_rtt(struct replay_runtime* runtime)
{
struct replay_moment* now = runtime->now;
int rto;
ldns_rdf* dp = ldns_dname_new_frm_str(now->variable);
size_t dplen = 0;
uint8_t* dp = ldns_str2wire_dname(now->variable, &dplen);
if(!dp) fatal_exit("cannot parse %s", now->variable);
rto = infra_rtt_update(runtime->infra, &now->addr,
now->addrlen, ldns_rdf_data(dp), ldns_rdf_size(dp),
LDNS_RR_TYPE_A, atoi(now->string), -1, runtime->now_secs);
rto = infra_rtt_update(runtime->infra, &now->addr, now->addrlen,
dp, dplen, LDNS_RR_TYPE_A, atoi(now->string),
-1, runtime->now_secs);
log_addr(0, "INFRA_RTT for", &now->addr, now->addrlen);
log_info("INFRA_RTT(%s roundtrip %d): rto of %d", now->variable,
atoi(now->string), rto);
if(rto == 0) fatal_exit("infra_rtt_update failed");
ldns_rdf_deep_free(dp);
free(dp);
}
/** perform exponential backoff on the timout */
@ -712,7 +717,7 @@ run_scenario(struct replay_runtime* runtime)
struct fake_pending* p;
log_err("testbound: there are still messages pending.");
for(p = runtime->pending_list; p; p=p->next) {
log_pkt("pending msg", p->pkt);
log_pkt("pending msg", p->pkt, p->pkt_len);
log_addr(0, "pending to", &p->addr, p->addrlen);
}
fatal_exit("testbound: there are still messages pending.");
@ -856,7 +861,6 @@ comm_point_send_reply(struct comm_reply* repinfo)
{
struct replay_answer* ans = (struct replay_answer*)calloc(1,
sizeof(struct replay_answer));
ldns_status status;
struct replay_runtime* runtime = (struct replay_runtime*)repinfo->c->ev;
log_info("testbound: comm_point_send_reply fake");
/* dump it into the todo list */
@ -869,13 +873,11 @@ comm_point_send_reply(struct comm_reply* repinfo)
runtime->answer_last = ans;
/* try to parse packet */
status = ldns_buffer2pkt_wire(&ans->pkt, ans->repinfo.c->buffer);
if(status != LDNS_STATUS_OK) {
log_err("ldns error parsing packet: %s",
ldns_get_errorstr_by_id(status));
fatal_exit("Sending unparseable DNS replies to clients!");
}
log_pkt("reply pkt: ", ans->pkt);
ans->pkt = memdup(ldns_buffer_begin(ans->repinfo.c->buffer),
ldns_buffer_limit(ans->repinfo.c->buffer));
ans->pkt_len = ldns_buffer_limit(ans->repinfo.c->buffer);
if(!ans->pkt) fatal_exit("out of memory");
log_pkt("reply pkt: ", ans->pkt, ans->pkt_len);
}
void
@ -938,7 +940,6 @@ pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
struct replay_runtime* runtime = (struct replay_runtime*)outnet->base;
struct fake_pending* pend = (struct fake_pending*)calloc(1,
sizeof(struct fake_pending));
ldns_status status;
log_assert(pend);
pend->buffer = ldns_buffer_new(ldns_buffer_capacity(packet));
log_assert(pend->buffer);
@ -955,20 +956,18 @@ pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
pend->zone = NULL;
pend->serviced = 0;
pend->runtime = runtime;
status = ldns_buffer2pkt_wire(&pend->pkt, packet);
if(status != LDNS_STATUS_OK) {
log_err("ldns error parsing udp output packet: %s",
ldns_get_errorstr_by_id(status));
fatal_exit("Sending unparseable DNS packets to servers!");
}
log_pkt("pending udp pkt: ", pend->pkt);
pend->pkt_len = ldns_buffer_limit(packet);
pend->pkt = memdup(ldns_buffer_begin(packet), pend->pkt_len);
if(!pend->pkt) fatal_exit("out of memory");
log_pkt("pending udp pkt: ", pend->pkt, pend->pkt_len);
/* see if it matches the current moment */
if(runtime->now && runtime->now->evt_type == repevt_back_query &&
(runtime->now->addrlen == 0 || sockaddr_cmp(
&runtime->now->addr, runtime->now->addrlen,
&pend->addr, pend->addrlen) == 0) &&
find_match(runtime->now->match, pend->pkt, pend->transport)) {
find_match(runtime->now->match, pend->pkt, pend->pkt_len,
pend->transport)) {
log_info("testbound: matched pending to event. "
"advance time between events.");
log_info("testbound: do STEP %d %s", runtime->now->time_step,
@ -992,7 +991,6 @@ pending_tcp_query(struct outside_network* outnet, ldns_buffer* packet,
struct replay_runtime* runtime = (struct replay_runtime*)outnet->base;
struct fake_pending* pend = (struct fake_pending*)calloc(1,
sizeof(struct fake_pending));
ldns_status status;
log_assert(pend);
pend->buffer = ldns_buffer_new(ldns_buffer_capacity(packet));
log_assert(pend->buffer);
@ -1009,20 +1007,18 @@ pending_tcp_query(struct outside_network* outnet, ldns_buffer* packet,
pend->zone = NULL;
pend->runtime = runtime;
pend->serviced = 0;
status = ldns_buffer2pkt_wire(&pend->pkt, packet);
if(status != LDNS_STATUS_OK) {
log_err("ldns error parsing tcp output packet: %s",
ldns_get_errorstr_by_id(status));
fatal_exit("Sending unparseable DNS packets to servers!");
}
log_pkt("pending tcp pkt: ", pend->pkt);
pend->pkt_len = ldns_buffer_limit(packet);
pend->pkt = memdup(ldns_buffer_begin(packet), pend->pkt_len);
if(!pend->pkt) fatal_exit("out of memory");
log_pkt("pending tcp pkt: ", pend->pkt, pend->pkt_len);
/* see if it matches the current moment */
if(runtime->now && runtime->now->evt_type == repevt_back_query &&
(runtime->now->addrlen == 0 || sockaddr_cmp(
&runtime->now->addr, runtime->now->addrlen,
&pend->addr, pend->addrlen) == 0) &&
find_match(runtime->now->match, pend->pkt, pend->transport)) {
find_match(runtime->now->match, pend->pkt, pend->pkt_len,
pend->transport)) {
log_info("testbound: matched pending to event. "
"advance time between events.");
log_info("testbound: do STEP %d %s", runtime->now->time_step,
@ -1049,7 +1045,6 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
struct fake_pending* pend = (struct fake_pending*)calloc(1,
sizeof(struct fake_pending));
char z[256];
ldns_status status;
log_assert(pend);
log_nametypeclass(VERB_OPS, "pending serviced query",
qname, qtype, qclass);
@ -1096,20 +1091,18 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
pend->pkt = NULL;
pend->runtime = runtime;
pend->serviced = 1;
status = ldns_buffer2pkt_wire(&pend->pkt, pend->buffer);
if(status != LDNS_STATUS_OK) {
log_err("ldns error parsing serviced output packet: %s",
ldns_get_errorstr_by_id(status));
fatal_exit("internal error");
}
/*log_pkt("pending serviced query: ", pend->pkt);*/
pend->pkt_len = ldns_buffer_limit(pend->buffer);
pend->pkt = memdup(ldns_buffer_begin(pend->buffer), pend->pkt_len);
if(!pend->pkt) fatal_exit("out of memory");
/*log_pkt("pending serviced query: ", pend->pkt, pend->pkt_len);*/
/* see if it matches the current moment */
if(runtime->now && runtime->now->evt_type == repevt_back_query &&
(runtime->now->addrlen == 0 || sockaddr_cmp(
&runtime->now->addr, runtime->now->addrlen,
&pend->addr, pend->addrlen) == 0) &&
find_match(runtime->now->match, pend->pkt, pend->transport)) {
find_match(runtime->now->match, pend->pkt, pend->pkt_len,
pend->transport)) {
log_info("testbound: matched pending to event. "
"advance time between events.");
log_info("testbound: do STEP %d %s", runtime->now->time_step,
@ -1138,7 +1131,7 @@ void outnet_serviced_query_stop(struct serviced_query* sq, void* cb_arg)
prev->next = p->next;
else runtime->pending_list = p->next;
ldns_buffer_free(p->buffer);
ldns_pkt_free(p->pkt);
free(p->pkt);
free(p->zone);
free(p);
return;

View File

@ -1,857 +0,0 @@
/*
* testcode/harvest.c - debug program to get relevant data to a set of queries.
*
* Copyright (c) 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
*
* This program downloads relevant DNS data to a set of queries.
* This means that the queries are asked to root, TLD, SLD servers and
* the results stored per zone.
* The following data is pertinent:
*
* At each label:
* SOA
* NS
* DNSKEY
* DS
* For the whole query:
* the result.
* For NS-records:
* their label data
* and the A and AAAA records for it.
* (as if the name, with A and AAAA query type is in the list,
* referred to as recursion depth+1)
* Any NSEC, NSEC3, SOA records or additional data found in answers.
*
* All of this is data that would be encountered during an iterative lookup
* for the queries in the list. It is saved to enable a replay of iterative
* lookups for performance testing.
*
* A number of assumptions are made.
* 1) configuration is correct.
* The parent has the same NS records as the child.
* All nameservers carry the same data.
* 2) EDNS/nonEDNS responses and other behaviour is ignored.
* Only the data is saved.
* This creates a snapshot that represents the data as this resolver saw it.
*/
#include "config.h"
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
#include <ldns/ldns.h>
#include <signal.h>
#include "libunbound/unbound.h"
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef UNBOUND_ALLOC_LITE
#undef malloc
#undef calloc
#undef realloc
#undef free
#undef strdup
#define unbound_lite_wrapstr(s) s
#endif
struct todo_item;
struct labdata;
/** this represents the data that has been collected
* as well as a todo list and some settings */
struct harvest_data {
/** the unbound context */
struct ub_ctx* ctx;
/** a tree per label; thus this first one is one root entry,
* that has a tree of TLD labels. Those have trees of SLD labels. */
struct labdata* root;
/** the original query list */
struct todo_item* orig_list;
/** the query list todo */
struct todo_item* todo_list;
/** last item in todo list */
struct todo_item* todo_last;
/** number of todo items */
int numtodo;
/** where to store the results */
char* resultdir;
/** maximum recursion depth */
int maxdepth;
/** current recursion depth */
int curdepth;
/** max depth of labels */
int maxlabels;
/** number of RRs stored */
int num_rrs;
/** number of zones written */
int num_zones;
};
/**
* Todo item
*/
struct todo_item {
/** the next item */
struct todo_item* next;
/** query as rdf */
ldns_rdf* qname;
/** the query type */
int qtype;
/** query class */
int qclass;
/** recursion depth of todo item (orig list is 0) */
int depth;
/** the label associated with the query */
struct labdata* lab;
};
/**
* Every label has a sest of sublabels, that have sets of sublabels ...
* Per label is stored also a set of data items, and todo information
*/
struct labdata {
/** node in ldns rbtree */
ldns_rbnode_t node;
/** the name of this label */
ldns_rdf* label;
/** full name of point in domain tree */
ldns_rdf* name;
/** parent in label tree (NULL for root) */
struct labdata* parent;
/** tree of sublabels (if any) */
ldns_rbtree_t* sublabels;
/** list of RRs for this label */
ldns_rr_list* rrlist;
/** have queries for this label been queued */
int done;
};
/** usage information for harvest */
static void usage(char* nm)
{
printf("usage: %s [options]\n", nm);
printf("-f fnm query list to read from file\n");
printf(" every line has format: qname qclass qtype\n");
printf("-v verbose (-v -v even more)\n");
printf("-C cfg config file with resolver options\n");
exit(1);
}
/** verbosity for harvest */
static int hverb = 0;
/** exit with error */
static void error_exit(const char* str)
{
printf("error: %s\n", str);
exit(1);
}
/** read a query file */
static void
qlist_read_file(struct harvest_data* data, char* fname)
{
char buf[1024];
char nm[1024], cl[1024], tp[1024];
int r;
int num = 0;
FILE* in = fopen(fname, "r");
struct todo_item* t;
if(!in) {
perror(fname);
error_exit("could not open file");
}
while(fgets(buf, (int)sizeof(buf), in)) {
if(buf[0] == 0) continue;
if(buf[0] == '\n') continue;
/* allow some comments */
if(buf[0] == ';') continue;
if(buf[0] == '#') continue;
nm[0] = 0; cl[0] = 0; tp[0] = 0;
r = sscanf(buf, " %1023s %1023s %1023s", nm, cl, tp);
if(r == 0) continue;
t = (struct todo_item*)calloc(1, sizeof(*t));
if(!t) error_exit("out of memory");
t->qname = ldns_dname_new_frm_str(nm);
if(!t->qname) {
printf("parse error: %s\n", nm);
error_exit("bad qname");
}
t->depth = 0;
t->qtype = LDNS_RR_TYPE_A;
t->qclass = LDNS_RR_CLASS_IN;
if(r >= 2) {
if(strcmp(cl, "IN") == 0 || strcmp(cl, "CH") == 0)
t->qclass = ldns_get_rr_class_by_name(cl);
else t->qtype = ldns_get_rr_type_by_name(cl);
}
if(r >= 3) {
if(strcmp(tp, "IN") == 0 || strcmp(tp, "CH") == 0)
t->qclass = ldns_get_rr_class_by_name(tp);
else t->qtype = ldns_get_rr_type_by_name(tp);
}
num++;
t->next = data->orig_list;
data->orig_list = t;
}
printf("read %s: %d queries\n", fname, num);
fclose(in);
}
/** compare two labels */
static int
lab_cmp(const void *x, const void *y)
{
return ldns_dname_compare((const ldns_rdf*)x, (const ldns_rdf*)y);
}
/** create label entry */
static struct labdata*
lab_create(const char* name)
{
struct labdata* lab = (struct labdata*)calloc(1, sizeof(*lab));
if(!lab) error_exit("out of memory");
lab->label = ldns_dname_new_frm_str(name);
if(!lab->label) error_exit("out of memory");
lab->name = ldns_dname_new_frm_str(name);
if(!lab->name) error_exit("out of memory");
lab->node.key = lab->label;
lab->node.data = lab;
lab->sublabels = ldns_rbtree_create(lab_cmp);
if(!lab->sublabels) error_exit("out of memory");
lab->rrlist = ldns_rr_list_new();
if(!lab->rrlist) error_exit("out of memory");
return lab;
}
/** for this name, lookup the label, create if does not exist */
static struct labdata*
find_create_lab(struct harvest_data* data, ldns_rdf* name)
{
struct labdata* lab = data->root;
struct labdata* nextlab;
ldns_rdf* next;
uint8_t numlab = ldns_dname_label_count(name);
if((int)numlab > data->maxlabels)
data->maxlabels = (int)numlab;
while(numlab--) {
next = ldns_dname_label(name, numlab);
if(!next) error_exit("ldns_dname_label");
nextlab = (struct labdata*)
ldns_rbtree_search(lab->sublabels, next);
if(!nextlab) {
/* create it */
nextlab = (struct labdata*)calloc(1, sizeof(*lab));
if(!nextlab) error_exit("out of memory");
nextlab->label = ldns_rdf_clone(next);
if(!nextlab->label) error_exit("out of memory");
nextlab->node.key = nextlab->label;
nextlab->node.data = nextlab;
nextlab->sublabels = ldns_rbtree_create(lab_cmp);
if(!nextlab->sublabels) error_exit("out of memory");
nextlab->parent = lab;
nextlab->name = ldns_rdf_clone(next);
if(!nextlab->name) error_exit("out of memory");
if(ldns_dname_cat(nextlab->name, lab->name)
!= LDNS_STATUS_OK) error_exit("outofmem");
nextlab->rrlist = ldns_rr_list_new();
if(!nextlab->rrlist) error_exit("out of memory");
(void)ldns_rbtree_insert(lab->sublabels,
&nextlab->node);
if(hverb) {
printf("new label: ");
ldns_rdf_print(stdout, nextlab->name);
printf("\n");
}
}
lab = nextlab;
ldns_rdf_deep_free(next);
}
return lab;
}
/** for given query, create todo items, and labels if needed */
static void
new_todo_item(struct harvest_data* data, ldns_rdf* qname, int qtype,
int qclass, int depth)
{
struct labdata* lab = find_create_lab(data, qname);
struct todo_item* it;
if(!lab) error_exit("out of memory creating new label");
it = (struct todo_item*)calloc(1, sizeof(*it));
it->qname = ldns_rdf_clone(qname);
it->qtype = qtype;
it->qclass = qclass;
it->depth = depth;
it->lab = lab;
it->next = NULL;
if(data->todo_last)
data->todo_last->next = it;
else data->todo_list = it;
data->todo_last = it;
data->numtodo ++;
if(hverb >= 2) {
printf("new todo: ");
ldns_rdf_print(stdout, it->qname);
if(ldns_rr_descript((uint16_t)it->qtype) &&
ldns_rr_descript((uint16_t)it->qtype)->_name)
printf(" %s", ldns_rr_descript((uint16_t)
it->qtype)->_name);
if(ldns_lookup_by_id(ldns_rr_classes, it->qclass) &&
ldns_lookup_by_id(ldns_rr_classes, it->qclass)->name)
printf(" %s", ldns_lookup_by_id(ldns_rr_classes,
it->qclass)->name);
printf("\n");
}
}
/** add infra todo items for this query */
static void
new_todo_infra(struct harvest_data* data, struct labdata* startlab, int depth)
{
struct labdata* lab;
for(lab = startlab; lab; lab = lab->parent) {
if(lab->done)
return;
new_todo_item(data, lab->name, LDNS_RR_TYPE_NS,
LDNS_RR_CLASS_IN, depth);
new_todo_item(data, lab->name, LDNS_RR_TYPE_SOA,
LDNS_RR_CLASS_IN, depth);
new_todo_item(data, lab->name, LDNS_RR_TYPE_DNSKEY,
LDNS_RR_CLASS_IN, depth);
new_todo_item(data, lab->name, LDNS_RR_TYPE_DS,
LDNS_RR_CLASS_IN, depth);
new_todo_item(data, lab->name, LDNS_RR_TYPE_A,
LDNS_RR_CLASS_IN, depth);
new_todo_item(data, lab->name, LDNS_RR_TYPE_AAAA,
LDNS_RR_CLASS_IN, depth);
lab->done = 1;
}
}
/** make todo items for initial data */
static void
make_todo(struct harvest_data* data)
{
struct todo_item* it;
for(it=data->orig_list; it; it = it->next) {
/* create todo item for this query itself */
new_todo_item(data, it->qname, it->qtype, it->qclass, 0);
/* create todo items for infra queries to support it */
new_todo_infra(data, data->todo_list->lab,
data->todo_list->depth);
}
}
/** store RR and make new work items for it if needed */
static void
process_rr(struct harvest_data* data, ldns_rr* rr, int depth)
{
/* must free or store rr */
struct labdata* lab = find_create_lab(data, ldns_rr_owner(rr));
if(!lab) error_exit("cannot find/create label");
/* generate extra queries */
if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_NS) {
new_todo_infra(data, find_create_lab(data,
ldns_rr_ns_nsdname(rr)), depth+1);
} else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_MX) {
new_todo_infra(data, find_create_lab(data,
ldns_rr_mx_exchange(rr)), depth+1);
} else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
new_todo_infra(data, find_create_lab(data,
ldns_rr_rdf(rr, 0)), depth+1);
} else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_CNAME) {
int t = ldns_rr_get_type(rr);
if(t!=LDNS_RR_TYPE_A && t!=LDNS_RR_TYPE_AAAA &&
t!=LDNS_RR_TYPE_SOA && t!=LDNS_RR_TYPE_NS &&
t!=LDNS_RR_TYPE_DS && t!=LDNS_RR_TYPE_DNSKEY)
new_todo_item(data, ldns_rr_rdf(rr, 0), t,
ldns_rr_get_class(rr), depth+1);
/* can get caught in CNAME loop, but depth will
* catch that; unbound cache helps too(servfails on
* a cname loop) */
new_todo_infra(data, find_create_lab(data,
ldns_rr_rdf(rr, 0)), depth+1);
}
/* store it */
if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC) {
/* find correct zone to store NSEC in (for delegation zones) */
if(ldns_dname_compare(ldns_rr_rdf(rr, 0), ldns_rr_owner(rr))
== 0) {
/* store at the single name = apex */
} else if(!ldns_dname_is_subdomain(ldns_rr_rdf(rr, 0),
ldns_rr_owner(rr)) && lab->parent) {
/* if owner NSEC subdomain-of-owner then
* store at owner (owner is apex or empty nonterminal).
* Otherwise at owner parent. */
lab = lab->parent;
}
} else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_DS) {
/* store DSes in parent zone */
if(lab->parent)
lab = lab->parent;
} else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3) {
/* store NSEC3s one label up at zone apex */
if(lab->parent)
lab = lab->parent;
}
/* we assume NS set is equal across parent-child border. */
if(!ldns_rr_list_contains_rr(lab->rrlist, rr)) {
if(hverb >= 2) {
printf("store RR ");
ldns_rr_print(stdout, rr);
printf("\n");
}
if(!ldns_rr_list_push_rr(lab->rrlist, rr))
error_exit("outofmem ldns_rr_list_push_rr");
data->num_rrs++;
} else {
if(hverb >= 2) {
printf("duplicate RR ");
ldns_rr_print(stdout, rr);
printf("\n");
}
ldns_rr_free(rr);
}
}
/** store RRs and make new work items if needed */
static void
process_pkt(struct harvest_data* data, ldns_pkt* pkt, int depth)
{
size_t i;
ldns_rr_list* list;
list = ldns_pkt_get_section_clone(pkt, LDNS_SECTION_ANY_NOQUESTION);
if(!list) error_exit("outofmemory");
for(i=0; i<ldns_rr_list_rr_count(list); i++) {
process_rr(data, ldns_rr_list_rr(list, i), depth);
}
ldns_rr_list_free(list);
}
/** process a todo item */
static void
process(struct harvest_data* data, struct todo_item* it)
{
int r;
char* nm;
struct ub_result* result = NULL;
ldns_pkt* pkt = NULL;
ldns_status s;
if(hverb) {
printf("process: ");
ldns_rdf_print(stdout, it->qname);
if(ldns_rr_descript((uint16_t)it->qtype) &&
ldns_rr_descript((uint16_t)it->qtype)->_name)
printf(" %s", ldns_rr_descript((uint16_t)
it->qtype)->_name);
if(ldns_lookup_by_id(ldns_rr_classes, it->qclass) &&
ldns_lookup_by_id(ldns_rr_classes, it->qclass)->name)
printf(" %s", ldns_lookup_by_id(ldns_rr_classes,
it->qclass)->name);
printf("\n");
}
/* do lookup */
nm = ldns_rdf2str(it->qname);
if(!nm) error_exit("ldns_rdf2str");
r = ub_resolve(data->ctx, nm, it->qtype, it->qclass, &result);
if(r != 0) {
printf("ub_resolve(%s, %d, %d): %s\n", nm, it->qtype,
it->qclass, ub_strerror(r));
free(nm);
return;
}
if(result->rcode == LDNS_RCODE_SERVFAIL) {
free(nm);
return;
}
/* even if result is a negative, try to store resulting SOA/NSEC */
/* create ldns pkt */
s = ldns_wire2pkt(&pkt, result->answer_packet,
(size_t)result->answer_len);
if(s != LDNS_STATUS_OK) {
printf("ldns_wire2pkt failed! %s %d %d %s %d\n", nm,
it->qtype, it->qclass, ldns_get_errorstr_by_id(s),
result->answer_len);
free(nm);
return;
}
if(hverb >= 2) {
printf("answer: ");
ldns_pkt_print(stdout, pkt);
printf("\n");
}
/* process results */
process_pkt(data, pkt, it->depth);
ldns_pkt_free(pkt);
free(nm);
ub_resolve_free(result);
}
/** perform main harvesting */
static void
harvest_main(struct harvest_data* data)
{
struct todo_item* it;
int numdone = 0;
/* register todo queries for all original queries */
make_todo(data);
printf("depth 0: done %d todo %d\n", 0, data->numtodo);
/* pick up a todo item and process it */
while(data->todo_list) {
numdone++;
it = data->todo_list;
data->todo_list = it->next;
if(!data->todo_list) data->todo_last = NULL;
if(numdone%1000==0 || it->depth > data->curdepth) {
data->curdepth = it->depth;
printf("depth %d: done %d todo %d, %d rrs\n",
it->depth, numdone, data->numtodo,
data->num_rrs);
}
if(it->depth >= data->maxdepth) {
printf("obtained %d rrs to a max of %d labels.\n",
data->num_rrs, data->maxlabels);
return;
}
data->numtodo--;
process(data, it);
usleep(1000000/100);
}
}
/** create directory if it does not exist */
static void
hv_mkdir(char* dir)
{
#ifdef MKDIR_HAS_ONE_ARG
if(mkdir(dir) == -1) {
#else
if(mkdir(dir, 0755) == -1) {
#endif
if(errno == EEXIST)
return;
perror(dir);
error_exit("mkdir failed");
}
}
/** see if rrlist contains a SOA record */
static ldns_rr*
has_SOA(ldns_rr_list* list)
{
size_t i;
for(i=0; i<ldns_rr_list_rr_count(list); i++) {
if(ldns_rr_get_type(ldns_rr_list_rr(list, i))
== LDNS_RR_TYPE_SOA)
return ldns_rr_list_rr(list, i);
}
return NULL;
}
/** write moredata for a zone*/
static void
write_moredata(struct harvest_data* data, struct labdata* zone,
FILE *f, struct labdata* thislab, ldns_rr* nslist)
{
struct labdata* lab;
size_t i;
ldns_rr* ns;
LDNS_RBTREE_FOR(lab, struct labdata*, thislab->sublabels) {
if(has_SOA(lab->rrlist)) {
/* copy only NS glue */
for(i=0; i<ldns_rr_list_rr_count(lab->rrlist); i++) {
ns = ldns_rr_list_rr(lab->rrlist, i);
if(ldns_rr_get_type(ns) == LDNS_RR_TYPE_NS) {
ldns_rr_print(f, ns);
if(ldns_dname_is_subdomain(
ldns_rr_ns_nsdname(ns),
lab->name)) {
ldns_rr_push_rdf(nslist,
ldns_rdf_clone(
ldns_rr_ns_nsdname(ns)));
}
}
}
} else {
/* copy all, recurse */
for(i=0; i<ldns_rr_list_rr_count(lab->rrlist); i++) {
ldns_rr_print(f,
ldns_rr_list_rr(lab->rrlist, i));
}
write_moredata(data, zone, f, lab, nslist);
}
}
}
/** find and write glue into zone file */
static void
write_glue(struct harvest_data* data, struct labdata* thislab, FILE* f,
ldns_rdf* name, int dep)
{
size_t i;
struct labdata* lab;
ldns_rr* rr;
if(ldns_dname_compare(name, thislab->name) == 0) {
/* this is it! Did we go outside the zone? */
if(dep == 0)
return;
/* find A and AAAA */
for(i=0; i<ldns_rr_list_rr_count(thislab->rrlist); i++) {
rr = ldns_rr_list_rr(thislab->rrlist, i);
if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_A ||
ldns_rr_get_type(rr) == LDNS_RR_TYPE_AAAA) {
ldns_rr_print(f, rr);
}
}
return;
}
/* recurse deeper */
LDNS_RBTREE_FOR(lab, struct labdata*, thislab->sublabels) {
if(has_SOA(lab->rrlist)) {
write_glue(data, lab, f, name, dep+1);
} else {
write_glue(data, lab, f, name, dep);
}
}
}
/** write zonefile for zone at this apex */
static void
write_zonefile(struct harvest_data* data, int dep, FILE* zlist,
struct labdata* apex, ldns_rr* soa)
{
FILE *f;
char fname[1024];
char* zname = ldns_rdf2str(apex->name);
time_t tm = time(NULL);
size_t i;
ldns_rr* nslist;
if(!zname) error_exit("out of mem ldns_rdf2str");
if(strcmp(zname, ".") == 0)
snprintf(fname, sizeof(fname), "l%d/root.zone", dep);
else snprintf(fname, sizeof(fname), "l%d/%szone", dep, zname);
fprintf(zlist, "zone: name: \"%s\" %s%szonefile: \"%s\"\n",
zname,
strlen(zname)/8<1?"\t":"",
strlen(zname)/8<2?"\t":"",
fname);
if(hverb) printf("writing %s\n", fname);
f = fopen(fname, "w");
if(!f) {
perror(fname);
error_exit("cannot open zone file");
}
fprintf(f, "; %s - generated by harvest program.\n", fname);
fprintf(f, "; zone name %s - this is a partial snapshot of "
"data relevant to the query list.\n", zname);
fprintf(f, "; created %u - date %s\n", (unsigned)tm, ctime(&tm));
ldns_rr_print(f, soa);
fprintf(f, "\n");
for(i=0; i<ldns_rr_list_rr_count(apex->rrlist); i++) {
if(ldns_rr_get_type(ldns_rr_list_rr(apex->rrlist, i))
== LDNS_RR_TYPE_SOA) continue;
ldns_rr_print(f, ldns_rr_list_rr(apex->rrlist, i));
}
/* search for more data - subdomains inside the zone, NS glue */
nslist = ldns_rr_new();
if(!nslist) error_exit("out of memory");
fprintf(f, "; end of apex, more data follows\n");
write_moredata(data, apex, f, apex, nslist);
/* add NS from apex that need glue too */
for(i=0; i<ldns_rr_list_rr_count(apex->rrlist); i++) {
if(ldns_rr_get_type(ldns_rr_list_rr(apex->rrlist, i)) !=
LDNS_RR_TYPE_NS)
continue;
/* these are only added again if in a subzone */
if(ldns_dname_is_subdomain(ldns_rr_ns_nsdname(
ldns_rr_list_rr(apex->rrlist, i)), apex->name)) {
ldns_rr_push_rdf(nslist, ldns_rdf_clone(
ldns_rr_ns_nsdname(ldns_rr_list_rr(
apex->rrlist, i))));
}
}
fprintf(f, "; glue data follows\n");
/* lookup and add glue (if not already in zone) */
for(i=0; i<ldns_rr_rd_count(nslist); i++) {
write_glue(data, apex, f, ldns_rr_rdf(nslist, i), 0);
}
fclose(f);
ldns_rr_free(nslist);
free(zname);
}
/** create zones at depth d in label tree */
static void
create_zones(struct harvest_data* data, int dep, FILE* zlist,
struct labdata* labnow, int depnow)
{
struct labdata* s;
ldns_rr* soa;
if(depnow == dep) {
/* see if this is a zone start - a SOA */
if((soa=has_SOA(labnow->rrlist))) {
write_zonefile(data, dep, zlist, labnow, soa);
data->num_zones++;
}
return;
}
/* recurse */
LDNS_RBTREE_FOR(s, struct labdata*, labnow->sublabels) {
create_zones(data, dep, zlist, s, depnow+1);
}
}
/** sort rrlists */
static void
harvest_sort(struct labdata* lab)
{
struct labdata* s;
/* prettier output if sorted here */
ldns_rr_list_sort(lab->rrlist);
/* and recurse */
LDNS_RBTREE_FOR(s, struct labdata*, lab->sublabels) {
harvest_sort(s);
}
}
/** output harvested results */
static void
harvest_output(struct harvest_data* data)
{
int d;
char buf[20];
FILE* zlist;
int lastzones;
hv_mkdir(data->resultdir);
if(chdir(data->resultdir) == -1) {
perror(data->resultdir);
error_exit("cannot chdir");
}
harvest_sort(data->root);
/* create zones */
for(d = 0; d<data->maxlabels; d++) {
lastzones = data->num_zones;
printf("creating zones %d\n", d);
snprintf(buf, sizeof(buf), "l%d", d);
hv_mkdir(buf);
snprintf(buf, sizeof(buf), "l%d.zones", d);
zlist = fopen(buf, "w");
if(!zlist) {
perror(buf);
error_exit("cannot write zonelist file");
}
fprintf(zlist, "# partial zones at depth %d\n", d);
create_zones(data, d, zlist, data->root, 0);
fclose(zlist);
printf("creating zones %d - %d zones written\n", d,
data->num_zones - lastzones);
}
}
/** getopt global, in case header files fail to declare it. */
extern int optind;
/** getopt global, in case header files fail to declare it. */
extern char* optarg;
/** main program for harvest */
int main(int argc, char* argv[])
{
struct harvest_data data;
char* nm = argv[0];
int c;
/* defaults */
memset(&data, 0, sizeof(data));
data.ctx = ub_ctx_create();
data.resultdir = strdup("harvested_zones");
if(!data.resultdir) error_exit("out of memory");
data.maxdepth = 2;
/* parse the options */
while( (c=getopt(argc, argv, "hf:vC:")) != -1) {
switch(c) {
case 'C':
if(ub_ctx_config(data.ctx, optarg) != 0)
error_exit("config read failed");
break;
case 'f':
qlist_read_file(&data, optarg);
break;
case 'v':
hverb++;
break;
case '?':
case 'h':
default:
usage(nm);
}
}
argc -= optind;
argv += optind;
if(argc != 0)
usage(nm);
if(data.orig_list == NULL)
error_exit("No queries to make, use -f (help with -h).");
data.root = lab_create(".");
if(!data.root) error_exit("out of memory");
/* harvest the data */
harvest_main(&data);
harvest_output(&data);
/* no cleanup except the context (to close open sockets) */
ub_ctx_delete(data.ctx);
return 0;
}

View File

@ -1,898 +0,0 @@
/*
* ldns-testpkts. Data file parse for test packets, and query matching.
*
* Data storage for specially crafted replies for testing purposes.
*
* (c) NLnet Labs, 2005, 2006, 2007, 2008
* See the file LICENSE for the license
*/
/**
* \file
* This is a debugging aid. It is not efficient, especially
* with a long config file, but it can give any reply to any query.
* This can help the developer pre-script replies for queries.
*
* You can specify a packet RR by RR with header flags to return.
*
* Missing features:
* - matching content different from reply content.
* - find way to adjust mangled packets?
*/
#include "config.h"
struct sockaddr_storage;
#include <ldns/ldns.h>
#include <errno.h>
#include "ldns-testpkts.h"
/** max line length */
#define MAX_LINE 10240
/** string to show in warnings and errors */
static const char* prog_name = "ldns-testpkts";
#ifndef UTIL_LOG_H
/** verbosity definition for compat */
enum verbosity_value { NO_VERBOSE=0 };
#endif
/** logging routine, provided by caller */
void verbose(enum verbosity_value lvl, const char* msg, ...) ATTR_FORMAT(printf, 2, 3);
/** print error and exit */
static void error(const char* msg, ...)
{
va_list args;
va_start(args, msg);
fprintf(stderr, "%s error: ", prog_name);
vfprintf(stderr, msg, args);
fprintf(stderr, "\n");
fflush(stderr);
va_end(args);
exit(EXIT_FAILURE);
}
/** return if string is empty or comment */
static bool isendline(char c)
{
if(c == ';' || c == '#'
|| c == '\n' || c == 0)
return true;
return false;
}
/** true if the string starts with the keyword given. Moves the str ahead.
* @param str: before keyword, afterwards after keyword and spaces.
* @param keyword: the keyword to match
* @return: true if keyword present. False otherwise, and str unchanged.
*/
static bool str_keyword(char** str, const char* keyword)
{
size_t len = strlen(keyword);
assert(str && keyword);
if(strncmp(*str, keyword, len) != 0)
return false;
*str += len;
while(isspace((int)**str))
(*str)++;
return true;
}
/** Add reply packet to entry */
static struct reply_packet*
entry_add_reply(struct entry* entry)
{
struct reply_packet* pkt = (struct reply_packet*)malloc(
sizeof(struct reply_packet));
struct reply_packet ** p = &entry->reply_list;
pkt->next = NULL;
pkt->packet_sleep = 0;
pkt->reply = ldns_pkt_new();
pkt->reply_from_hex = NULL;
/* link at end */
while(*p)
p = &((*p)->next);
*p = pkt;
return pkt;
}
/** parse MATCH line */
static void matchline(char* line, struct entry* e)
{
char* parse = line;
while(*parse) {
if(isendline(*parse))
return;
if(str_keyword(&parse, "opcode")) {
e->match_opcode = true;
} else if(str_keyword(&parse, "qtype")) {
e->match_qtype = true;
} else if(str_keyword(&parse, "qname")) {
e->match_qname = true;
} else if(str_keyword(&parse, "subdomain")) {
e->match_subdomain = true;
} else if(str_keyword(&parse, "all")) {
e->match_all = true;
} else if(str_keyword(&parse, "ttl")) {
e->match_ttl = true;
} else if(str_keyword(&parse, "DO")) {
e->match_do = true;
} else if(str_keyword(&parse, "noedns")) {
e->match_noedns = true;
} else if(str_keyword(&parse, "UDP")) {
e->match_transport = transport_udp;
} else if(str_keyword(&parse, "TCP")) {
e->match_transport = transport_tcp;
} else if(str_keyword(&parse, "serial")) {
e->match_serial = true;
if(*parse != '=' && *parse != ':')
error("expected = or : in MATCH: %s", line);
parse++;
e->ixfr_soa_serial = (uint32_t)strtol(parse, (char**)&parse, 10);
while(isspace((int)*parse))
parse++;
} else {
error("could not parse MATCH: '%s'", parse);
}
}
}
/** parse REPLY line */
static void replyline(char* line, ldns_pkt *reply)
{
char* parse = line;
while(*parse) {
if(isendline(*parse))
return;
/* opcodes */
if(str_keyword(&parse, "QUERY")) {
ldns_pkt_set_opcode(reply, LDNS_PACKET_QUERY);
} else if(str_keyword(&parse, "IQUERY")) {
ldns_pkt_set_opcode(reply, LDNS_PACKET_IQUERY);
} else if(str_keyword(&parse, "STATUS")) {
ldns_pkt_set_opcode(reply, LDNS_PACKET_STATUS);
} else if(str_keyword(&parse, "NOTIFY")) {
ldns_pkt_set_opcode(reply, LDNS_PACKET_NOTIFY);
} else if(str_keyword(&parse, "UPDATE")) {
ldns_pkt_set_opcode(reply, LDNS_PACKET_UPDATE);
/* rcodes */
} else if(str_keyword(&parse, "NOERROR")) {
ldns_pkt_set_rcode(reply, LDNS_RCODE_NOERROR);
} else if(str_keyword(&parse, "FORMERR")) {
ldns_pkt_set_rcode(reply, LDNS_RCODE_FORMERR);
} else if(str_keyword(&parse, "SERVFAIL")) {
ldns_pkt_set_rcode(reply, LDNS_RCODE_SERVFAIL);
} else if(str_keyword(&parse, "NXDOMAIN")) {
ldns_pkt_set_rcode(reply, LDNS_RCODE_NXDOMAIN);
} else if(str_keyword(&parse, "NOTIMPL")) {
ldns_pkt_set_rcode(reply, LDNS_RCODE_NOTIMPL);
} else if(str_keyword(&parse, "REFUSED")) {
ldns_pkt_set_rcode(reply, LDNS_RCODE_REFUSED);
} else if(str_keyword(&parse, "YXDOMAIN")) {
ldns_pkt_set_rcode(reply, LDNS_RCODE_YXDOMAIN);
} else if(str_keyword(&parse, "YXRRSET")) {
ldns_pkt_set_rcode(reply, LDNS_RCODE_YXRRSET);
} else if(str_keyword(&parse, "NXRRSET")) {
ldns_pkt_set_rcode(reply, LDNS_RCODE_NXRRSET);
} else if(str_keyword(&parse, "NOTAUTH")) {
ldns_pkt_set_rcode(reply, LDNS_RCODE_NOTAUTH);
} else if(str_keyword(&parse, "NOTZONE")) {
ldns_pkt_set_rcode(reply, LDNS_RCODE_NOTZONE);
/* flags */
} else if(str_keyword(&parse, "QR")) {
ldns_pkt_set_qr(reply, true);
} else if(str_keyword(&parse, "AA")) {
ldns_pkt_set_aa(reply, true);
} else if(str_keyword(&parse, "TC")) {
ldns_pkt_set_tc(reply, true);
} else if(str_keyword(&parse, "RD")) {
ldns_pkt_set_rd(reply, true);
} else if(str_keyword(&parse, "CD")) {
ldns_pkt_set_cd(reply, true);
} else if(str_keyword(&parse, "RA")) {
ldns_pkt_set_ra(reply, true);
} else if(str_keyword(&parse, "AD")) {
ldns_pkt_set_ad(reply, true);
} else if(str_keyword(&parse, "DO")) {
ldns_pkt_set_edns_udp_size(reply, 4096);
ldns_pkt_set_edns_do(reply, true);
} else {
error("could not parse REPLY: '%s'", parse);
}
}
}
/** parse ADJUST line */
static void adjustline(char* line, struct entry* e,
struct reply_packet* pkt)
{
char* parse = line;
while(*parse) {
if(isendline(*parse))
return;
if(str_keyword(&parse, "copy_id")) {
e->copy_id = true;
} else if(str_keyword(&parse, "copy_query")) {
e->copy_query = true;
} else if(str_keyword(&parse, "sleep=")) {
e->sleeptime = (unsigned int) strtol(parse, (char**)&parse, 10);
while(isspace((int)*parse))
parse++;
} else if(str_keyword(&parse, "packet_sleep=")) {
pkt->packet_sleep = (unsigned int) strtol(parse, (char**)&parse, 10);
while(isspace((int)*parse))
parse++;
} else {
error("could not parse ADJUST: '%s'", parse);
}
}
}
/** create new entry */
static struct entry* new_entry()
{
struct entry* e = LDNS_MALLOC(struct entry);
memset(e, 0, sizeof(*e));
e->match_opcode = false;
e->match_qtype = false;
e->match_qname = false;
e->match_subdomain = false;
e->match_all = false;
e->match_ttl = false;
e->match_do = false;
e->match_noedns = false;
e->match_serial = false;
e->ixfr_soa_serial = 0;
e->match_transport = transport_any;
e->reply_list = NULL;
e->copy_id = false;
e->copy_query = false;
e->sleeptime = 0;
e->next = NULL;
return e;
}
/**
* Converts a hex string to binary data
* @param hexstr: string of hex.
* @param len: is the length of the string
* @param buf: is the buffer to store the result in
* @param offset: is the starting position in the result buffer
* @param buf_len: is the length of buf.
* @return This function returns the length of the result
*/
static 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 {
fprintf(stderr, "Buffer too small in hexstr2bin");
}
}
}
}
return bufpos;
}
/** convert hex buffer to binary buffer */
static ldns_buffer *
data_buffer2wire(ldns_buffer *data_buffer)
{
ldns_buffer *wire_buffer = NULL;
int c;
/* stat hack
* 0 = normal
* 1 = comment (skip to end of line)
* 2 = unprintable character found, read binary data directly
*/
size_t data_buf_pos = 0;
int state = 0;
uint8_t *hexbuf;
int hexbufpos = 0;
size_t wirelen;
uint8_t *data_wire = (uint8_t *) ldns_buffer_begin(data_buffer);
uint8_t *wire = LDNS_XMALLOC(uint8_t, LDNS_MAX_PACKETLEN);
hexbuf = LDNS_XMALLOC(uint8_t, LDNS_MAX_PACKETLEN);
for (data_buf_pos = 0; data_buf_pos < ldns_buffer_position(data_buffer); data_buf_pos++) {
c = (int) data_wire[data_buf_pos];
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') )
{
if (hexbufpos >= LDNS_MAX_PACKETLEN) {
error("buffer overflow");
LDNS_FREE(hexbuf);
return 0;
}
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:
if (hexbufpos >= LDNS_MAX_PACKETLEN) {
error("buffer overflow");
LDNS_FREE(hexbuf);
return 0;
}
hexbuf[hexbufpos] = (uint8_t) c;
hexbufpos++;
break;
}
}
if (hexbufpos >= LDNS_MAX_PACKETLEN) {
/*verbose("packet size reached\n");*/
}
/* lenient mode: length must be multiple of 2 */
if (hexbufpos % 2 != 0) {
if (hexbufpos >= LDNS_MAX_PACKETLEN) {
error("buffer overflow");
LDNS_FREE(hexbuf);
return 0;
}
hexbuf[hexbufpos] = (uint8_t) '0';
hexbufpos++;
}
if (state < 2) {
wirelen = hexstr2bin((char *) hexbuf, hexbufpos, wire, 0, LDNS_MAX_PACKETLEN);
wire_buffer = ldns_buffer_new(wirelen);
ldns_buffer_new_frm_data(wire_buffer, wire, wirelen);
} else {
error("Incomplete hex data, not at byte boundary\n");
}
LDNS_FREE(wire);
LDNS_FREE(hexbuf);
return wire_buffer;
}
/** parse ORIGIN */
static void
get_origin(const char* name, int lineno, ldns_rdf** origin, char* parse)
{
/* snip off rest of the text so as to make the parse work in ldns */
char* end;
char store;
ldns_status status;
ldns_rdf_free(*origin);
*origin = NULL;
end=parse;
while(!isspace((int)*end) && !isendline(*end))
end++;
store = *end;
*end = 0;
verbose(3, "parsing '%s'\n", parse);
status = ldns_str2rdf_dname(origin, parse);
*end = store;
if (status != LDNS_STATUS_OK)
error("%s line %d:\n\t%s: %s", name, lineno,
ldns_get_errorstr_by_id(status), parse);
}
/* Reads one entry from file. Returns entry or NULL on error. */
struct entry*
read_entry(FILE* in, const char* name, int *lineno, uint32_t* default_ttl,
ldns_rdf** origin, ldns_rdf** prev_rr, int skip_whitespace)
{
struct entry* current = NULL;
char line[MAX_LINE];
char* parse;
ldns_pkt_section add_section = LDNS_SECTION_QUESTION;
struct reply_packet *cur_reply = NULL;
bool reading_hex = false;
ldns_buffer* hex_data_buffer = NULL;
while(fgets(line, (int)sizeof(line), in) != NULL) {
line[MAX_LINE-1] = 0;
parse = line;
(*lineno) ++;
while(isspace((int)*parse))
parse++;
/* test for keywords */
if(isendline(*parse))
continue; /* skip comment and empty lines */
if(str_keyword(&parse, "ENTRY_BEGIN")) {
if(current) {
error("%s line %d: previous entry does not ENTRY_END",
name, *lineno);
}
current = new_entry();
current->lineno = *lineno;
cur_reply = entry_add_reply(current);
continue;
} else if(str_keyword(&parse, "$ORIGIN")) {
get_origin(name, *lineno, origin, parse);
continue;
} else if(str_keyword(&parse, "$TTL")) {
*default_ttl = (uint32_t)atoi(parse);
continue;
}
/* working inside an entry */
if(!current) {
error("%s line %d: expected ENTRY_BEGIN but got %s",
name, *lineno, line);
}
if(str_keyword(&parse, "MATCH")) {
matchline(parse, current);
} else if(str_keyword(&parse, "REPLY")) {
replyline(parse, cur_reply->reply);
} else if(str_keyword(&parse, "ADJUST")) {
adjustline(parse, current, cur_reply);
} else if(str_keyword(&parse, "EXTRA_PACKET")) {
cur_reply = entry_add_reply(current);
} else if(str_keyword(&parse, "SECTION")) {
if(str_keyword(&parse, "QUESTION"))
add_section = LDNS_SECTION_QUESTION;
else if(str_keyword(&parse, "ANSWER"))
add_section = LDNS_SECTION_ANSWER;
else if(str_keyword(&parse, "AUTHORITY"))
add_section = LDNS_SECTION_AUTHORITY;
else if(str_keyword(&parse, "ADDITIONAL"))
add_section = LDNS_SECTION_ADDITIONAL;
else error("%s line %d: bad section %s", name, *lineno, parse);
} else if(str_keyword(&parse, "HEX_ANSWER_BEGIN")) {
hex_data_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
reading_hex = true;
} else if(str_keyword(&parse, "HEX_ANSWER_END")) {
if (!reading_hex) {
error("%s line %d: HEX_ANSWER_END read but no HEX_ANSWER_BEGIN keyword seen", name, *lineno);
}
reading_hex = false;
cur_reply->reply_from_hex = data_buffer2wire(hex_data_buffer);
ldns_buffer_free(hex_data_buffer);
hex_data_buffer = NULL;
} else if(str_keyword(&parse, "ENTRY_END")) {
if (hex_data_buffer)
ldns_buffer_free(hex_data_buffer);
return current;
} else if(reading_hex) {
ldns_buffer_printf(hex_data_buffer, line);
} else {
/* it must be a RR, parse and add to packet. */
ldns_rr* n = NULL;
ldns_status status;
char* rrstr = line;
if (skip_whitespace)
rrstr = parse;
if(add_section == LDNS_SECTION_QUESTION)
status = ldns_rr_new_question_frm_str(
&n, rrstr, *origin, prev_rr);
else status = ldns_rr_new_frm_str(&n, rrstr,
*default_ttl, *origin, prev_rr);
if(status != LDNS_STATUS_OK)
error("%s line %d:\n\t%s: %s", name, *lineno,
ldns_get_errorstr_by_id(status), rrstr);
ldns_pkt_push_rr(cur_reply->reply, add_section, n);
}
}
if (reading_hex) {
error("%s: End of file reached while still reading hex, "
"missing HEX_ANSWER_END\n", name);
}
if(current) {
error("%s: End of file reached while reading entry. "
"missing ENTRY_END\n", name);
}
return 0;
}
/* reads the canned reply file and returns a list of structs */
struct entry*
read_datafile(const char* name, int skip_whitespace)
{
struct entry* list = NULL;
struct entry* last = NULL;
struct entry* current = NULL;
FILE *in;
int lineno = 0;
uint32_t default_ttl = 0;
ldns_rdf* origin = NULL;
ldns_rdf* prev_rr = NULL;
int entry_num = 0;
if((in=fopen(name, "r")) == NULL) {
error("could not open file %s: %s", name, strerror(errno));
}
while((current = read_entry(in, name, &lineno, &default_ttl,
&origin, &prev_rr, skip_whitespace)))
{
if(last)
last->next = current;
else list = current;
last = current;
entry_num ++;
}
verbose(1, "%s: Read %d entries\n", prog_name, entry_num);
fclose(in);
ldns_rdf_deep_free(origin);
ldns_rdf_deep_free(prev_rr);
return list;
}
/** get qtype from rr */
static ldns_rr_type get_qtype(ldns_pkt* p)
{
if(!ldns_rr_list_rr(ldns_pkt_question(p), 0))
return 0;
return ldns_rr_get_type(ldns_rr_list_rr(ldns_pkt_question(p), 0));
}
/** returns owner from rr */
static ldns_rdf* get_owner(ldns_pkt* p)
{
if(!ldns_rr_list_rr(ldns_pkt_question(p), 0))
return NULL;
return ldns_rr_owner(ldns_rr_list_rr(ldns_pkt_question(p), 0));
}
/** get authority section SOA serial value */
static uint32_t get_serial(ldns_pkt* p)
{
ldns_rr *rr = ldns_rr_list_rr(ldns_pkt_authority(p), 0);
ldns_rdf *rdf;
uint32_t val;
if(!rr) return 0;
rdf = ldns_rr_rdf(rr, 2);
if(!rdf) return 0;
val = ldns_rdf2native_int32(rdf);
verbose(3, "found serial %u in msg. ", (int)val);
return val;
}
/** match two rr lists */
static int
match_list(ldns_rr_list* q, ldns_rr_list *p, bool mttl)
{
size_t i;
if(ldns_rr_list_rr_count(q) != ldns_rr_list_rr_count(p))
return 0;
for(i=0; i<ldns_rr_list_rr_count(q); i++)
{
if(ldns_rr_compare(ldns_rr_list_rr(q, i),
ldns_rr_list_rr(p, i)) != 0) {
verbose(3, "rr %d different", (int)i);
return 0;
}
if(mttl && ldns_rr_ttl(ldns_rr_list_rr(q, i)) !=
ldns_rr_ttl(ldns_rr_list_rr(p, i))) {
verbose(3, "rr %d ttl different", (int)i);
return 0;
}
}
return 1;
}
/** compare two booleans */
static int
cmp_bool(int x, int y)
{
if(!x && !y) return 0;
if(x && y) return 0;
if(!x) return -1;
return 1;
}
/** match all of the packet */
static int
match_all(ldns_pkt* q, ldns_pkt* p, bool mttl)
{
if(ldns_pkt_get_opcode(q) != ldns_pkt_get_opcode(p))
{ verbose(3, "allmatch: opcode different"); return 0;}
if(ldns_pkt_get_rcode(q) != ldns_pkt_get_rcode(p))
{ verbose(3, "allmatch: rcode different"); return 0;}
if(ldns_pkt_id(q) != ldns_pkt_id(p))
{ verbose(3, "allmatch: id different"); return 0;}
if(cmp_bool(ldns_pkt_qr(q), ldns_pkt_qr(p)) != 0)
{ verbose(3, "allmatch: qr different"); return 0;}
if(cmp_bool(ldns_pkt_aa(q), ldns_pkt_aa(p)) != 0)
{ verbose(3, "allmatch: aa different"); return 0;}
if(cmp_bool(ldns_pkt_tc(q), ldns_pkt_tc(p)) != 0)
{ verbose(3, "allmatch: tc different"); return 0;}
if(cmp_bool(ldns_pkt_rd(q), ldns_pkt_rd(p)) != 0)
{ verbose(3, "allmatch: rd different"); return 0;}
if(cmp_bool(ldns_pkt_cd(q), ldns_pkt_cd(p)) != 0)
{ verbose(3, "allmatch: cd different"); return 0;}
if(cmp_bool(ldns_pkt_ra(q), ldns_pkt_ra(p)) != 0)
{ verbose(3, "allmatch: ra different"); return 0;}
if(cmp_bool(ldns_pkt_ad(q), ldns_pkt_ad(p)) != 0)
{ verbose(3, "allmatch: ad different"); return 0;}
if(ldns_pkt_qdcount(q) != ldns_pkt_qdcount(p))
{ verbose(3, "allmatch: qdcount different"); return 0;}
if(ldns_pkt_ancount(q) != ldns_pkt_ancount(p))
{ verbose(3, "allmatch: ancount different"); return 0;}
if(ldns_pkt_nscount(q) != ldns_pkt_nscount(p))
{ verbose(3, "allmatch: nscount different"); return 0;}
if(ldns_pkt_arcount(q) != ldns_pkt_arcount(p))
{ verbose(3, "allmatch: arcount different"); return 0;}
if(!match_list(ldns_pkt_question(q), ldns_pkt_question(p), 0))
{ verbose(3, "allmatch: qd section different"); return 0;}
if(!match_list(ldns_pkt_answer(q), ldns_pkt_answer(p), mttl))
{ verbose(3, "allmatch: an section different"); return 0;}
if(!match_list(ldns_pkt_authority(q), ldns_pkt_authority(p), mttl))
{ verbose(3, "allmatch: ar section different"); return 0;}
if(!match_list(ldns_pkt_additional(q), ldns_pkt_additional(p), mttl))
{ verbose(3, "allmatch: ns section different"); return 0;}
return 1;
}
/* finds entry in list, or returns NULL */
struct entry*
find_match(struct entry* entries, ldns_pkt* query_pkt,
enum transport_type transport)
{
struct entry* p = entries;
ldns_pkt* reply = NULL;
for(p=entries; p; p=p->next) {
verbose(3, "comparepkt: ");
reply = p->reply_list->reply;
if(p->match_opcode && ldns_pkt_get_opcode(query_pkt) !=
ldns_pkt_get_opcode(reply)) {
verbose(3, "bad opcode\n");
continue;
}
if(p->match_qtype && get_qtype(query_pkt) != get_qtype(reply)) {
verbose(3, "bad qtype\n");
continue;
}
if(p->match_qname) {
if(!get_owner(query_pkt) || !get_owner(reply) ||
ldns_dname_compare(
get_owner(query_pkt), get_owner(reply)) != 0) {
verbose(3, "bad qname\n");
continue;
}
}
if(p->match_subdomain) {
if(!get_owner(query_pkt) || !get_owner(reply) ||
(ldns_dname_compare(get_owner(query_pkt),
get_owner(reply)) != 0 &&
!ldns_dname_is_subdomain(
get_owner(query_pkt), get_owner(reply))))
{
verbose(3, "bad subdomain\n");
continue;
}
}
if(p->match_serial && get_serial(query_pkt) != p->ixfr_soa_serial) {
verbose(3, "bad serial\n");
continue;
}
if(p->match_do && !ldns_pkt_edns_do(query_pkt)) {
verbose(3, "no DO bit set\n");
continue;
}
if(p->match_noedns && ldns_pkt_edns(query_pkt)) {
verbose(3, "bad; EDNS OPT present\n");
continue;
}
if(p->match_transport != transport_any && p->match_transport != transport) {
verbose(3, "bad transport\n");
continue;
}
if(p->match_all && !match_all(query_pkt, reply, p->match_ttl)) {
verbose(3, "bad allmatch\n");
continue;
}
verbose(3, "match!\n");
return p;
}
return NULL;
}
void
adjust_packet(struct entry* match, ldns_pkt* answer_pkt, ldns_pkt* query_pkt)
{
/* copy & adjust packet */
if(match->copy_id)
ldns_pkt_set_id(answer_pkt, ldns_pkt_id(query_pkt));
if(match->copy_query) {
ldns_rr_list* list = ldns_pkt_get_section_clone(query_pkt,
LDNS_SECTION_QUESTION);
ldns_rr_list_deep_free(ldns_pkt_question(answer_pkt));
ldns_pkt_set_question(answer_pkt, list);
}
if(match->sleeptime > 0) {
verbose(3, "sleeping for %d seconds\n", match->sleeptime);
#ifdef HAVE_SLEEP
sleep(match->sleeptime);
#else
Sleep(match->sleeptime * 1000);
#endif
}
}
/*
* Parses data buffer to a query, finds the correct answer
* and calls the given function for every packet to send.
*/
void
handle_query(uint8_t* inbuf, ssize_t inlen, struct entry* entries, int* count,
enum transport_type transport, void (*sendfunc)(uint8_t*, size_t, void*),
void* userdata, FILE* verbose_out)
{
ldns_status status;
ldns_pkt *query_pkt = NULL;
ldns_pkt *answer_pkt = NULL;
struct reply_packet *p;
ldns_rr *query_rr = NULL;
uint8_t *outbuf = NULL;
size_t answer_size = 0;
struct entry* entry = NULL;
ldns_rdf *stop_command = ldns_dname_new_frm_str("server.stop.");
status = ldns_wire2pkt(&query_pkt, inbuf, (size_t)inlen);
if (status != LDNS_STATUS_OK) {
verbose(1, "Got bad packet: %s\n", ldns_get_errorstr_by_id(status));
ldns_rdf_free(stop_command);
return;
}
query_rr = ldns_rr_list_rr(ldns_pkt_question(query_pkt), 0);
verbose(1, "query %d: id %d: %s %d bytes: ", ++(*count), (int)ldns_pkt_id(query_pkt),
(transport==transport_tcp)?"TCP":"UDP", (int)inlen);
if(verbose_out) ldns_rr_print(verbose_out, query_rr);
if(verbose_out) ldns_pkt_print(verbose_out, query_pkt);
if (ldns_rr_get_type(query_rr) == LDNS_RR_TYPE_TXT &&
ldns_rr_get_class(query_rr) == LDNS_RR_CLASS_CH &&
ldns_dname_compare(ldns_rr_owner(query_rr), stop_command) == 0) {
exit(0);
}
/* fill up answer packet */
entry = find_match(entries, query_pkt, transport);
if(!entry || !entry->reply_list) {
verbose(1, "no answer packet for this query, no reply.\n");
ldns_pkt_free(query_pkt);
ldns_rdf_free(stop_command);
return;
}
for(p = entry->reply_list; p; p = p->next)
{
verbose(3, "Answer pkt:\n");
if (p->reply_from_hex) {
/* try to parse the hex packet, if it can be
* parsed, we can use adjust rules. if not,
* send packet literally */
status = ldns_buffer2pkt_wire(&answer_pkt, p->reply_from_hex);
if (status == LDNS_STATUS_OK) {
adjust_packet(entry, answer_pkt, query_pkt);
if(verbose_out) ldns_pkt_print(verbose_out, answer_pkt);
status = ldns_pkt2wire(&outbuf, answer_pkt, &answer_size);
verbose(2, "Answer packet size: %u bytes.\n", (unsigned int)answer_size);
if (status != LDNS_STATUS_OK) {
verbose(1, "Error creating answer: %s\n", ldns_get_errorstr_by_id(status));
ldns_pkt_free(query_pkt);
ldns_rdf_free(stop_command);
return;
}
ldns_pkt_free(answer_pkt);
answer_pkt = NULL;
} else {
verbose(3, "Could not parse hex data (%s), sending hex data directly.\n", ldns_get_errorstr_by_id(status));
/* still try to adjust ID */
answer_size = ldns_buffer_capacity(p->reply_from_hex);
outbuf = LDNS_XMALLOC(uint8_t, answer_size);
memcpy(outbuf, ldns_buffer_begin(p->reply_from_hex), answer_size);
if(entry->copy_id) {
ldns_write_uint16(outbuf,
ldns_pkt_id(query_pkt));
}
}
} else {
answer_pkt = ldns_pkt_clone(p->reply);
adjust_packet(entry, answer_pkt, query_pkt);
if(verbose_out) ldns_pkt_print(verbose_out, answer_pkt);
status = ldns_pkt2wire(&outbuf, answer_pkt, &answer_size);
verbose(1, "Answer packet size: %u bytes.\n", (unsigned int)answer_size);
if (status != LDNS_STATUS_OK) {
verbose(1, "Error creating answer: %s\n", ldns_get_errorstr_by_id(status));
ldns_pkt_free(query_pkt);
ldns_rdf_free(stop_command);
return;
}
ldns_pkt_free(answer_pkt);
answer_pkt = NULL;
}
if(p->packet_sleep) {
verbose(3, "sleeping for next packet %d secs\n",
p->packet_sleep);
#ifdef HAVE_SLEEP
sleep(p->packet_sleep);
#else
Sleep(p->packet_sleep * 1000);
#endif
verbose(3, "wakeup for next packet "
"(slept %d secs)\n", p->packet_sleep);
}
sendfunc(outbuf, answer_size, userdata);
LDNS_FREE(outbuf);
outbuf = NULL;
answer_size = 0;
}
ldns_pkt_free(query_pkt);
ldns_rdf_free(stop_command);
}
/** delete the list of reply packets */
void delete_replylist(struct reply_packet* replist)
{
struct reply_packet *p=replist, *np;
while(p) {
np = p->next;
ldns_pkt_free(p->reply);
ldns_buffer_free(p->reply_from_hex);
free(p);
p=np;
}
}
void delete_entry(struct entry* list)
{
struct entry *p=list, *np;
while(p) {
np = p->next;
delete_replylist(p->reply_list);
free(p);
p = np;
}
}

View File

@ -43,7 +43,6 @@
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
#include <ldns/ldns.h>
#include <signal.h>
#include "util/log.h"
#include "util/locks.h"
@ -51,6 +50,10 @@
#include "util/data/msgencode.h"
#include "util/data/msgreply.h"
#include "util/data/msgparse.h"
#include "ldns/sbuffer.h"
#include "ldns/wire2str.h"
#include "ldns/str2wire.h"
#include <sys/time.h>
/** usage information for perf */
static void usage(char* nm)
@ -434,11 +437,10 @@ perfendstats(struct perfinfo* info)
for(i=0; i<(int)(sizeof(info->by_rcode)/sizeof(size_t)); i++)
{
if(info->by_rcode[i] > 0) {
char rc[16];
ldns_wire2str_rcode_buf(i, rc, sizeof(rc));
printf("%d(%5s): %u replies\n",
i, ldns_lookup_by_id(ldns_rcodes, i)?
ldns_lookup_by_id(ldns_rcodes,
i)->name:"??",
(unsigned)info->by_rcode[i]);
i, rc, (unsigned)info->by_rcode[i]);
}
}
}
@ -465,7 +467,6 @@ qlist_parse_line(ldns_buffer* buf, char* p)
int r;
int rec = 1, edns = 0;
struct query_info qinfo;
ldns_rdf* rdf;
nm[0] = 0; cl[0] = 0; tp[0] = 0; fl[0] = 0;
r = sscanf(p, " %1023s %1023s %1023s %1023s", nm, cl, tp, fl);
if(r != 3 && r != 4)
@ -483,11 +484,9 @@ qlist_parse_line(ldns_buffer* buf, char* p)
else if(fl[0] == 'E') edns = 1;
if((fl[0] == '+' || fl[0] == '-') && fl[1] == 'E')
edns = 1;
rdf = ldns_dname_new_frm_str(nm);
if(!rdf)
qinfo.qname = ldns_str2wire_dname(nm, &qinfo.qname_len);
if(!qinfo.qname)
return 0;
qinfo.qname = ldns_rdf_data(rdf);
qinfo.qname_len = ldns_rdf_size(rdf);
qinfo_query_encode(buf, &qinfo);
ldns_buffer_write_u16_at(buf, 0, 0); /* zero ID */
if(rec) LDNS_RD_SET(ldns_buffer_begin(buf));
@ -500,7 +499,7 @@ qlist_parse_line(ldns_buffer* buf, char* p)
ed.bits = EDNS_DO;
attach_edns_record(buf, &ed);
}
ldns_rdf_deep_free(rdf);
free(qinfo.qname);
return 1;
}

View File

@ -40,12 +40,13 @@
*/
#include "config.h"
#include <ldns/ldns.h>
#include "util/log.h"
#include "util/data/dname.h"
#include "util/data/msgparse.h"
#include "testcode/unitmain.h"
#include "testcode/readhex.h"
#include "ldns/sbuffer.h"
#include "ldns/parseutil.h"
/** usage information for pktview */
static void usage(char* argv[])

View File

@ -41,6 +41,8 @@
#include <ctype.h>
#include "testcode/readhex.h"
#include "util/log.h"
#include "ldns/sbuffer.h"
#include "ldns/parseutil.h"
/** skip whitespace */
static void

View File

@ -40,13 +40,13 @@
#ifndef TESTCODE_READHEX_H
#define TESTCODE_READHEX_H
#include <ldns/buffer.h>
struct ldns_buffer;
/**
* Helper to convert hex string to packet buffer.
* @param pkt: buffer to put result in.
* @param hex: string of hex data. Spaces and ';...' comments are skipped.
*/
void hex_to_buf(ldns_buffer* pkt, const char* hex);
void hex_to_buf(struct ldns_buffer* pkt, const char* hex);
#endif /* TESTCODE_READHEX_H */

View File

@ -42,12 +42,15 @@
#include "config.h"
/* for strtod prototype */
#include <math.h>
#include <ctype.h>
#include <time.h>
#include "util/log.h"
#include "util/net_help.h"
#include "util/config_file.h"
#include "testcode/replay.h"
#include "testcode/ldns-testpkts.h"
#include "testcode/testpkts.h"
#include "testcode/fake_event.h"
#include "ldns/str2wire.h"
/** max length of lines in file */
#define MAX_LINE_LEN 10240
@ -138,16 +141,15 @@ strip_end_white(char* p)
* @param remain: Rest of line (after RANGE keyword).
* @param in: file to read from.
* @param name: name to print in errors.
* @param lineno: incremented as lines are read.
* @param pstate: read state structure with
* with lineno : incremented as lines are read.
* ttl, origin, prev for readentry.
* @param line: line buffer.
* @param ttl: for readentry
* @param or: for readentry
* @param prev: for readentry
* @return: range object to add to list, or NULL on error.
*/
static struct replay_range*
replay_range_read(char* remain, FILE* in, const char* name, int* lineno,
char* line, uint32_t* ttl, ldns_rdf** or, ldns_rdf** prev)
replay_range_read(char* remain, FILE* in, const char* name,
struct ldns_file_parse_state* pstate, char* line)
{
struct replay_range* rng = (struct replay_range*)malloc(
sizeof(struct replay_range));
@ -166,7 +168,7 @@ replay_range_read(char* remain, FILE* in, const char* name, int* lineno,
/* read entries */
pos = ftello(in);
while(fgets(line, MAX_LINE_LEN-1, in)) {
(*lineno)++;
pstate->lineno++;
parse = line;
while(isspace((int)*parse))
parse++;
@ -180,7 +182,7 @@ replay_range_read(char* remain, FILE* in, const char* name, int* lineno,
strip_end_white(parse);
if(!extstrtoaddr(parse, &rng->addr, &rng->addrlen)) {
log_err("Line %d: could not read ADDRESS: %s",
*lineno, parse);
pstate->lineno, parse);
free(rng);
return NULL;
}
@ -191,11 +193,11 @@ replay_range_read(char* remain, FILE* in, const char* name, int* lineno,
return rng;
}
/* set position before line; read entry */
(*lineno)--;
pstate->lineno--;
fseeko(in, pos, SEEK_SET);
entry = read_entry(in, name, lineno, ttl, or, prev, 1);
entry = read_entry(in, name, pstate, 1);
if(!entry)
fatal_exit("%d: bad entry", *lineno);
fatal_exit("%d: bad entry", pstate->lineno);
entry->next = NULL;
if(last)
last->next = entry;
@ -258,15 +260,13 @@ read_assign_step(char* remain, struct replay_moment* mom)
* @param remain: Rest of line (after STEP keyword).
* @param in: file to read from.
* @param name: name to print in errors.
* @param lineno: incremented as lines are read.
* @param ttl: for readentry
* @param or: for readentry
* @param prev: for readentry
* @param pstate: with lineno, ttl, origin, prev for parse state.
* lineno is incremented.
* @return: range object to add to list, or NULL on error.
*/
static struct replay_moment*
replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
uint32_t* ttl, ldns_rdf** or, ldns_rdf** prev)
replay_moment_read(char* remain, FILE* in, const char* name,
struct ldns_file_parse_state* pstate)
{
struct replay_moment* mom = (struct replay_moment*)malloc(
sizeof(struct replay_moment));
@ -276,7 +276,7 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
return NULL;
memset(mom, 0, sizeof(*mom));
if(sscanf(remain, " %d%n", &mom->time_step, &skip) != 1) {
log_err("%d: cannot read number: %s", *lineno, remain);
log_err("%d: cannot read number: %s", pstate->lineno, remain);
free(mom);
return NULL;
}
@ -322,7 +322,7 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
remain[strlen(remain)-1] = 0;
mom->autotrust_id = strdup(remain);
if(!mom->autotrust_id) fatal_exit("out of memory");
read_file_content(in, lineno, mom);
read_file_content(in, &pstate->lineno, mom);
} else if(parse_keyword(&remain, "ERROR")) {
mom->evt_type = repevt_error;
} else if(parse_keyword(&remain, "TRAFFIC")) {
@ -357,7 +357,7 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
if(!mom->string) fatal_exit("out of memory");
if(!mom->variable) fatal_exit("out of memory");
} else {
log_err("%d: unknown event type %s", *lineno, remain);
log_err("%d: unknown event type %s", pstate->lineno, remain);
free(mom);
return NULL;
}
@ -370,7 +370,7 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
remain[strlen(remain)-1] = 0;
if(!extstrtoaddr(remain, &mom->addr, &mom->addrlen)) {
log_err("line %d: could not parse ADDRESS: %s",
*lineno, remain);
pstate->lineno, remain);
free(mom);
return NULL;
}
@ -381,7 +381,7 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
sec = strtod(remain, &remain);
if(sec == 0. && errno != 0) {
log_err("line %d: could not parse ELAPSE: %s (%s)",
*lineno, remain, strerror(errno));
pstate->lineno, remain, strerror(errno));
free(mom);
return NULL;
}
@ -393,7 +393,7 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
}
if(readentry) {
mom->match = read_entry(in, name, lineno, ttl, or, prev, 1);
mom->match = read_entry(in, name, pstate, 1);
if(!mom->match) {
free(mom);
return NULL;
@ -432,13 +432,15 @@ replay_scenario_read(FILE* in, const char* name, int* lineno)
char line[MAX_LINE_LEN];
char *parse;
struct replay_scenario* scen = NULL;
uint32_t ttl = 3600;
ldns_rdf* or = NULL;
ldns_rdf* prev = NULL;
struct ldns_file_parse_state pstate;
line[MAX_LINE_LEN-1]=0;
memset(&pstate, 0, sizeof(pstate));
pstate.default_ttl = 3600;
pstate.lineno = *lineno;
while(fgets(line, MAX_LINE_LEN-1, in)) {
parse=line;
pstate.lineno++;
(*lineno)++;
while(isspace((int)*parse))
parse++;
@ -456,16 +458,18 @@ replay_scenario_read(FILE* in, const char* name, int* lineno)
fatal_exit("%d: expected SCENARIO", *lineno);
if(parse_keyword(&parse, "RANGE_BEGIN")) {
struct replay_range* newr = replay_range_read(parse,
in, name, lineno, line, &ttl, &or, &prev);
in, name, &pstate, line);
if(!newr)
fatal_exit("%d: bad range", *lineno);
fatal_exit("%d: bad range", pstate.lineno);
*lineno = pstate.lineno;
newr->next_range = scen->range_list;
scen->range_list = newr;
} else if(parse_keyword(&parse, "STEP")) {
struct replay_moment* mom = replay_moment_read(parse,
in, name, lineno, &ttl, &or, &prev);
in, name, &pstate);
if(!mom)
fatal_exit("%d: bad moment", *lineno);
fatal_exit("%d: bad moment", pstate.lineno);
*lineno = pstate.lineno;
if(scen->mom_last &&
scen->mom_last->time_step >= mom->time_step)
fatal_exit("%d: time goes backwards", *lineno);
@ -481,13 +485,9 @@ replay_scenario_read(FILE* in, const char* name, int* lineno)
p = p->mom_next;
}
log_info("Scenario has %d steps", num);
ldns_rdf_deep_free(or);
ldns_rdf_deep_free(prev);
return scen;
}
}
ldns_rdf_deep_free(or);
ldns_rdf_deep_free(prev);
replay_scenario_delete(scen);
return NULL;
}

View File

@ -129,7 +129,7 @@
#ifndef TESTCODE_REPLAY_H
#define TESTCODE_REPLAY_H
#include "util/netevent.h"
#include "testcode/ldns-testpkts.h"
#include "testcode/testpkts.h"
#include "util/rbtree.h"
struct replay_answer;
struct replay_moment;
@ -138,6 +138,7 @@ struct fake_pending;
struct fake_timer;
struct replay_var;
struct infra_cache;
struct ldns_buffer;
/**
* A replay scenario.
@ -217,12 +218,6 @@ struct replay_moment {
/** length of addr, if 0, then any address will do */
socklen_t addrlen;
/** what pending query should timeout or is answered. or
* NULL for last sent query.
* Unused at this time.
*/
ldns_rr* qname;
/** macro name, for assign. */
char* variable;
/** string argument, for assign. */
@ -318,7 +313,7 @@ struct replay_runtime {
*/
struct fake_pending {
/** what is important only that we remember the query, copied here. */
ldns_buffer* buffer;
struct ldns_buffer* buffer;
/** and to what address this is sent to. */
struct sockaddr_storage addr;
/** len of addr */
@ -339,7 +334,8 @@ struct fake_pending {
/** next in pending list */
struct fake_pending* next;
/** the buffer parsed into a ldns_pkt */
ldns_pkt* pkt;
uint8_t* pkt;
size_t pkt_len;
/** by what transport was the query sent out */
enum transport_type transport;
/** if this is a serviced query */
@ -357,7 +353,8 @@ struct replay_answer {
/** reply information */
struct comm_reply repinfo;
/** the answer preparsed as ldns pkt */
ldns_pkt* pkt;
uint8_t* pkt;
size_t pkt_len;
};
/**

View File

@ -41,9 +41,9 @@
*/
#include "config.h"
#include <ldns/ldns.h>
#include "util/log.h"
#include "util/config_file.h"
#include "util/net_help.h"
#include <assert.h>
#define DNSKEY_BIT_ZSK 0x0100
/**
* Key settings
@ -74,12 +74,47 @@ usage()
exit(1);
}
static time_t
convert_timeval(const char* str)
{
time_t t;
struct tm tm;
memset(&tm, 0, sizeof(tm));
if(strlen(str) < 14)
return 0;
if(sscanf(str, "%4d%2d%2d%2d%2d%2d", &tm.tm_year, &tm.tm_mon,
&tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6)
return 0;
tm.tm_year -= 1900;
tm.tm_mon--;
/* Check values */
if (tm.tm_year < 70) return 0;
if (tm.tm_mon < 0 || tm.tm_mon > 11) return 0;
if (tm.tm_mday < 1 || tm.tm_mday > 31) return 0;
if (tm.tm_hour < 0 || tm.tm_hour > 23) return 0;
if (tm.tm_min < 0 || tm.tm_min > 59) return 0;
if (tm.tm_sec < 0 || tm.tm_sec > 59) return 0;
/* call ldns conversion function */
t = ldns_mktime_from_utc(&tm);
return t;
}
static void fatal_exit(const char* format, ...)
{
va_list args;
va_start(args, format);
printf("fatal exit: ");
vprintf(format, args);
va_end(args);
exit(1);
}
/** read expi ince keytag owner from cmdline */
static void
parse_cmdline(char *argv[], struct keysets* s)
{
s->expi = cfg_convert_timeval(argv[1]);
s->incep = cfg_convert_timeval(argv[2]);
s->expi = convert_timeval(argv[1]);
s->incep = convert_timeval(argv[2]);
s->keytag = (uint16_t)atoi(argv[3]);
s->owner = argv[4];
s->flags = DNSKEY_BIT_ZSK; /* to enforce signing */
@ -118,7 +153,7 @@ read_keys(int num, char* names[], struct keysets* set)
ldns_key_set_flags(k, set->flags);
ldns_key_set_keytag(k, set->keytag);
b = ldns_key_list_push_key(keys, k);
log_assert(b);
assert(b);
}
return keys;
}
@ -151,7 +186,7 @@ read_rrs(FILE* in)
fatal_exit("parse error in line %d: %s", line_nr,
ldns_get_errorstr_by_id(s));
b = ldns_rr_list_push_rr(list, rr);
log_assert(b);
assert(b);
}
printf("read %d lines\n", line_nr);
@ -185,7 +220,7 @@ process_keys(int argc, char* argv[])
ldns_rr_list* rrs;
ldns_key_list* keys;
struct keysets settings;
log_assert(argc == 6);
assert(argc == 6);
parse_cmdline(argv, &settings);
keys = read_keys(1, argv+5, &settings);
@ -208,7 +243,7 @@ process_nsec3(int argc, char* argv[])
if(status != LDNS_STATUS_OK)
fatal_exit("Could not parse salt %s: %s", argv[5],
ldns_get_errorstr_by_id(status));
log_assert(argc == 6);
assert(argc == 6);
while(fgets(line, (int)sizeof(line), stdin)) {
if(strlen(line) > 0)
line[strlen(line)-1] = 0; /* remove trailing newline */
@ -237,7 +272,6 @@ process_nsec3(int argc, char* argv[])
/** main program */
int main(int argc, char* argv[])
{
log_init(NULL, 0, NULL);
if(argc != 6) {
usage();
}

View File

@ -43,7 +43,6 @@
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
#include <ldns/ldns.h>
#include <signal.h>
#include "util/locks.h"
#include "util/log.h"
@ -52,6 +51,11 @@
#include "util/data/msgparse.h"
#include "util/data/msgreply.h"
#include "util/data/dname.h"
#include "ldns/sbuffer.h"
#include "ldns/str2wire.h"
#include "ldns/wire2str.h"
#include <openssl/ssl.h>
#include <openssl/rand.h>
#include <openssl/err.h>
#ifndef PF_INET6
@ -112,18 +116,13 @@ write_q(int fd, int udp, SSL* ssl, ldns_buffer* buf, uint16_t id,
const char* strname, const char* strtype, const char* strclass)
{
struct query_info qinfo;
ldns_rdf* rdf;
uint16_t len;
/* qname */
rdf = ldns_dname_new_frm_str(strname);
if(!rdf) {
qinfo.qname = ldns_str2wire_dname(strname, &qinfo.qname_len);
if(!qinfo.qname) {
printf("cannot parse query name: '%s'\n", strname);
exit(1);
}
qinfo.qname = memdup(ldns_rdf_data(rdf), ldns_rdf_size(rdf));
if(!qinfo.qname) fatal_exit("out of memory");
(void)dname_count_size_labels(qinfo.qname, &qinfo.qname_len);
ldns_rdf_deep_free(rdf);
/* qtype and qclass */
qinfo.qtype = ldns_get_rr_type_by_name(strtype);
@ -192,9 +191,8 @@ write_q(int fd, int udp, SSL* ssl, ldns_buffer* buf, uint16_t id,
static void
recv_one(int fd, int udp, SSL* ssl, ldns_buffer* buf)
{
char* pktstr;
uint16_t len;
ldns_pkt* pkt;
ldns_status status;
if(!udp) {
if(ssl) {
if(SSL_read(ssl, (void*)&len, (int)sizeof(len)) <= 0) {
@ -256,15 +254,18 @@ recv_one(int fd, int udp, SSL* ssl, ldns_buffer* buf)
printf("\nnext received packet\n");
log_buf(0, "data", buf);
status = ldns_wire2pkt(&pkt, ldns_buffer_begin(buf), len);
if(status != LDNS_STATUS_OK) {
printf("could not parse incoming packet: %s\n",
ldns_get_errorstr_by_id(status));
log_buf(0, "data was", buf);
exit(1);
pktstr = ldns_wire2str_pkt(ldns_buffer_begin(buf), len);
printf("%s", pktstr);
free(pktstr);
}
static int get_random(void)
{
int r;
if (RAND_bytes((unsigned char*)&r, (int)sizeof(r)) == 1) {
return r;
}
ldns_pkt_print(stdout, pkt);
ldns_pkt_free(pkt);
return (int)random();
}
/** send the TCP queries and print answers */
@ -305,7 +306,7 @@ send_em(const char* svr, int udp, int usessl, int noanswer, int num, char** qs)
}
for(i=0; i<num; i+=3) {
printf("\nNext query is %s %s %s\n", qs[i], qs[i+1], qs[i+2]);
write_q(fd, udp, ssl, buf, ldns_get_random(), qs[i],
write_q(fd, udp, ssl, buf, (uint16_t)get_random(), qs[i],
qs[i+1], qs[i+2]);
/* print at least one result */
if(!noanswer)

View File

@ -39,11 +39,13 @@
*/
#include "config.h"
#include "testcode/ldns-testpkts.h"
#include "testcode/testpkts.h"
#include "testcode/replay.h"
#include "testcode/fake_event.h"
#include "daemon/remote.h"
#include "util/config_file.h"
#include "ldns/keyraw.h"
#include <ctype.h>
/** signal that this is a testbound compile */
#define unbound_testbound 1

1427
testcode/testpkts.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
* ldns-testpkts. Data file parse for test packets, and query matching.
* testpkts. Data file parse for test packets, and query matching.
*
* Data storage for specially crafted replies for testing purposes.
*
@ -7,8 +7,10 @@
* See the file LICENSE for the license
*/
#ifndef LDNS_TESTPKTS_H
#define LDNS_TESTPKTS_H
#ifndef TESTPKTS_H
#define TESTPKTS_H
struct ldns_buffer;
struct ldns_file_parse_state;
/**
* \file
@ -131,8 +133,6 @@ ENTRY_END
void verbose(int level, char* format, ...); output function.
*/
#include <ldns/ldns.h>
/** Type of transport, since some entries match based on UDP or TCP of query */
enum transport_type {transport_any = 0, transport_udp, transport_tcp };
@ -141,9 +141,11 @@ struct reply_packet {
/** next in list of reply packets, for TCP multiple pkts on wire */
struct reply_packet* next;
/** the reply pkt */
ldns_pkt* reply;
uint8_t* reply_pkt;
/** length of reply pkt */
size_t reply_len;
/** or reply pkt in hex if not parsable */
ldns_buffer* reply_from_hex;
struct ldns_buffer* reply_from_hex;
/** seconds to sleep before giving packet */
unsigned int packet_sleep;
};
@ -154,23 +156,23 @@ struct entry {
/* match */
/* How to match an incoming query with this canned reply */
/** match query opcode with answer opcode */
bool match_opcode;
uint8_t match_opcode;
/** match qtype with answer qtype */
bool match_qtype;
uint8_t match_qtype;
/** match qname with answer qname */
bool match_qname;
uint8_t match_qname;
/** match qname as subdomain of answer qname */
bool match_subdomain;
uint8_t match_subdomain;
/** match SOA serial number, from auth section */
bool match_serial;
uint8_t match_serial;
/** match all of the packet */
bool match_all;
uint8_t match_all;
/** match ttls in the packet */
bool match_ttl;
uint8_t match_ttl;
/** match DO bit */
bool match_do;
uint8_t match_do;
/** match absence of EDNS OPT record in query */
bool match_noedns;
uint8_t match_noedns;
/** match query serial with this value. */
uint32_t ixfr_soa_serial;
/** match on UDP/TCP */
@ -181,9 +183,9 @@ struct entry {
/** how to adjust the reply packet */
/** copy over the ID from the query into the answer */
bool copy_id;
uint8_t copy_id;
/** copy the query nametypeclass from query into the answer */
bool copy_query;
uint8_t copy_query;
/** in seconds */
unsigned int sleeptime;
@ -211,32 +213,39 @@ void delete_entry(struct entry* list);
* Read one entry from the data file.
* @param in: file to read from. Filepos must be at the start of a new line.
* @param name: name of the file for prettier errors.
* @param lineno: line number in file, incremented as lines are read.
* for prettier errors.
* @param default_ttl: on first call set to default TTL for entries,
* later it stores the $TTL value last seen. Try 3600 first call.
* @param origin: domain name for origin appending. Can be &NULL on first call.
* later it stores the $ORIGIN value last seen. Often &NULL or the zone
* name on first call.
* @param prev_rr: previous rr name for correcter parsing. &NULL on first call.
* @param pstate: file parse state with lineno, default_ttl,
* oirigin and prev_rr name.
* @param skip_whitespace: skip leftside whitespace.
* @return: The entry read (malloced) or NULL if no entry could be read.
*/
struct entry* read_entry(FILE* in, const char* name, int *lineno,
uint32_t* default_ttl, ldns_rdf** origin, ldns_rdf** prev_rr,
int skip_whitespace);
struct entry* read_entry(FILE* in, const char* name,
struct ldns_file_parse_state* pstate, int skip_whitespace);
/**
* finds entry in list, or returns NULL.
*/
struct entry* find_match(struct entry* entries, ldns_pkt* query_pkt,
enum transport_type transport);
struct entry* find_match(struct entry* entries, uint8_t* query_pkt,
size_t query_pkt_len, enum transport_type transport);
/**
* copy & adjust packet
* match two packets, all must match
* @param q: packet 1
* @param qlen: length of q.
* @param p: packet 2
* @param plen: length of p.
* @param mttl: if true, ttls must match, if false, ttls do not need to match
* @param noloc: if true, rrs may be reordered in their packet-section.
* rrs are then matches without location of the rr being important.
* @return true if matched.
*/
void adjust_packet(struct entry* match, ldns_pkt* answer_pkt,
ldns_pkt* query_pkt);
int match_all(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl,
int noloc);
/**
* copy & adjust packet, mallocs a copy.
*/
void adjust_packet(struct entry* match, uint8_t** answer_pkt,
size_t* answer_pkt_len, uint8_t* query_pkt, size_t query_pkt_len);
/**
* Parses data buffer to a query, finds the correct answer
@ -256,4 +265,4 @@ void handle_query(uint8_t* inbuf, ssize_t inlen, struct entry* entries,
void (*sendfunc)(uint8_t*, size_t, void*), void* userdata,
FILE* verbose_out);
#endif /* LDNS_TESTPKTS_H */
#endif /* TESTPKTS_H */

View File

@ -39,11 +39,12 @@
*/
#include "config.h"
#include <ldns/rr.h>
#include "util/log.h"
#include "util/data/dname.h"
#include "testcode/unitmain.h"
#include "validator/val_anchor.h"
#include "ldns/sbuffer.h"
#include "ldns/rrdef.h"
/** test empty set */
static void

View File

@ -39,25 +39,24 @@
*/
#include "config.h"
#include <ldns/dname.h>
#include <ldns/host2wire.h>
#include "util/log.h"
#include "testcode/unitmain.h"
#include "util/data/dname.h"
#include "ldns/sbuffer.h"
#include "ldns/str2wire.h"
/** put dname into buffer */
static ldns_buffer*
dname_to_buf(ldns_buffer* b, const char* str)
{
ldns_rdf* rdf;
ldns_status status;
int e;
size_t len = ldns_buffer_capacity(b);
ldns_buffer_clear(b);
rdf = ldns_dname_new_frm_str(str);
status = ldns_dname2buffer_wire(b, rdf);
if(status != LDNS_STATUS_OK)
e = ldns_str2wire_dname_buf(str, ldns_buffer_begin(b), &len);
if(e != 0)
fatal_exit("%s ldns: %s", __func__,
ldns_get_errorstr_by_id(status));
ldns_rdf_deep_free(rdf);
ldns_get_errorstr_parse(e));
ldns_buffer_set_position(b, len);
ldns_buffer_flip(b);
return b;
}

View File

@ -61,7 +61,8 @@
#include "nss.h"
#endif
#include <ldns/ldns.h>
#include "ldns/rrdef.h"
#include "ldns/keyraw.h"
#include "util/log.h"
#include "testcode/unitmain.h"

View File

@ -39,7 +39,7 @@
*/
#include "config.h"
#include <ldns/ldns.h>
#include <sys/time.h>
#include "util/log.h"
#include "testcode/unitmain.h"
#include "util/data/msgparse.h"
@ -50,6 +50,10 @@
#include "util/regional.h"
#include "util/net_help.h"
#include "testcode/readhex.h"
#include "testcode/testpkts.h"
#include "ldns/sbuffer.h"
#include "ldns/str2wire.h"
#include "ldns/wire2str.h"
/** verbose message parse unit test */
static int vbmp = 0;
@ -62,122 +66,10 @@ static int check_rrsigs = 0;
/** do not check buffer sameness */
static int check_nosameness = 0;
/** match two rr lists */
static int
match_list(ldns_rr_list* q, ldns_rr_list *p)
{
size_t i;
if(ldns_rr_list_rr_count(q) != ldns_rr_list_rr_count(p)) {
verbose(3, "rrlistcount different %d %d",
(int)ldns_rr_list_rr_count(q),
(int)ldns_rr_list_rr_count(p));
return 0;
}
for(i=0; i<ldns_rr_list_rr_count(q); i++)
{
if(matches_nolocation) {
if(!ldns_rr_list_contains_rr(p, ldns_rr_list_rr(q, i)))
{
verbose(3, "rr %u not found", (unsigned)i);
return 0;
}
} else {
if(ldns_rr_compare(ldns_rr_list_rr(q, i),
ldns_rr_list_rr(p, i)) != 0) {
verbose(3, "rr %u different", (unsigned)i);
return 0;
}
/* and check the ttl */
if(ldns_rr_ttl(ldns_rr_list_rr(q, i)) !=
ldns_rr_ttl(ldns_rr_list_rr(p, i))) {
verbose(3, "rr %u ttl different", (unsigned)i);
return 0;
}
}
}
return 1;
}
/** match edns sections */
static int
match_edns(ldns_pkt* q, ldns_pkt* p)
{
if(ldns_pkt_edns_udp_size(q) != ldns_pkt_edns_udp_size(p))
return 0;
if(ldns_pkt_edns_extended_rcode(q) != ldns_pkt_edns_extended_rcode(p))
return 0;
if(ldns_pkt_edns_version(q) != ldns_pkt_edns_version(p))
return 0;
if(ldns_pkt_edns_do(q) != ldns_pkt_edns_do(p))
return 0;
if(ldns_pkt_edns_z(q) != ldns_pkt_edns_z(p))
return 0;
if(ldns_rdf_compare(ldns_pkt_edns_data(q), ldns_pkt_edns_data(p)) != 0)
return 0;
return 1;
}
/** compare two booleans */
static int
cmp_bool(int x, int y)
{
if(!x && !y) return 0;
if(x && y) return 0;
if(!x) return -1;
return 1;
}
/** match all of the packet */
static int
match_all(ldns_pkt* q, ldns_pkt* p)
{
if(ldns_pkt_get_opcode(q) != ldns_pkt_get_opcode(p))
{ verbose(3, "allmatch: opcode different"); return 0;}
if(ldns_pkt_get_rcode(q) != ldns_pkt_get_rcode(p))
{ verbose(3, "allmatch: rcode different"); return 0;}
if(ldns_pkt_id(q) != ldns_pkt_id(p))
{ verbose(3, "allmatch: id different"); return 0;}
if(cmp_bool(ldns_pkt_qr(q), ldns_pkt_qr(p)) != 0)
{ verbose(3, "allmatch: qr different"); return 0;}
if(cmp_bool(ldns_pkt_aa(q), ldns_pkt_aa(p)) != 0)
{ verbose(3, "allmatch: aa different"); return 0;}
if(cmp_bool(ldns_pkt_tc(q), ldns_pkt_tc(p)) != 0)
{ verbose(3, "allmatch: tc different"); return 0;}
if(cmp_bool(ldns_pkt_rd(q), ldns_pkt_rd(p)) != 0)
{ verbose(3, "allmatch: rd different"); return 0;}
if(cmp_bool(ldns_pkt_cd(q), ldns_pkt_cd(p)) != 0)
{ verbose(3, "allmatch: cd different"); return 0;}
if(cmp_bool(ldns_pkt_ra(q), ldns_pkt_ra(p)) != 0)
{ verbose(3, "allmatch: ra different"); return 0;}
if(cmp_bool(ldns_pkt_ad(q), ldns_pkt_ad(p)) != 0)
{ verbose(3, "allmatch: ad different"); return 0;}
if(ldns_pkt_qdcount(q) != ldns_pkt_qdcount(p))
{ verbose(3, "allmatch: qdcount different"); return 0;}
if(ldns_pkt_ancount(q) != ldns_pkt_ancount(p))
{ verbose(3, "allmatch: ancount different"); return 0;}
if(ldns_pkt_nscount(q) != ldns_pkt_nscount(p))
{ verbose(3, "allmatch: nscount different"); return 0;}
if(ldns_pkt_arcount(q) != ldns_pkt_arcount(p))
{ verbose(3, "allmatch: arcount different"); return 0;}
if(!match_list(ldns_pkt_question(q), ldns_pkt_question(p)))
{ verbose(3, "allmatch: qd section different"); return 0;}
if(!match_list(ldns_pkt_answer(q), ldns_pkt_answer(p)))
{ verbose(3, "allmatch: an section different"); return 0;}
if(!match_list(ldns_pkt_authority(q), ldns_pkt_authority(p)))
{ verbose(3, "allmatch: ns section different"); return 0;}
if(!match_list(ldns_pkt_additional(q), ldns_pkt_additional(p)))
{ verbose(3, "allmatch: ar section different"); return 0;}
if(!match_edns(q, p))
{ verbose(3, "edns different."); return 0;}
return 1;
}
/** see if buffers contain the same packet */
static int
test_buffers(ldns_buffer* pkt, ldns_buffer* out)
{
ldns_pkt* p1=0, *p2=0;
ldns_status s1, s2;
/* check binary same */
if(ldns_buffer_limit(pkt) == ldns_buffer_limit(out) &&
memcmp(ldns_buffer_begin(pkt), ldns_buffer_begin(out),
@ -210,32 +102,42 @@ test_buffers(ldns_buffer* pkt, ldns_buffer* out)
}
}
}
/* check if it 'means the same' */
s1 = ldns_buffer2pkt_wire(&p1, pkt);
s2 = ldns_buffer2pkt_wire(&p2, out);
if(vbmp) {
char* s1, *s2;
log_buf(0, "orig in hex", pkt);
log_buf(0, "unbound out in hex", out);
printf("\npacket from unbound (%d):\n",
(int)ldns_buffer_limit(out));
ldns_pkt_print(stdout, p2);
s1 = ldns_wire2str_pkt(ldns_buffer_begin(out),
ldns_buffer_limit(out));
printf("%s\n", s1?s1:"null");
free(s1);
printf("\npacket original (%d):\n",
(int)ldns_buffer_limit(pkt));
ldns_pkt_print(stdout, p1);
s2 = ldns_wire2str_pkt(ldns_buffer_begin(pkt),
ldns_buffer_limit(pkt));
printf("%s\n", s2?s2:"null");
free(s2);
printf("\n");
}
if(s1 != s2) {
/* oops! */
printf("input ldns parse: %s, output ldns parse: %s.\n",
ldns_get_errorstr_by_id(s1),
ldns_get_errorstr_by_id(s2));
unit_assert(0);
/* if it had two EDNS sections, skip comparison */
if(1) {
char* s = ldns_wire2str_pkt(ldns_buffer_begin(pkt),
ldns_buffer_limit(pkt));
char* e1 = strstr(s, "; EDNS:");
if(e1 && strstr(e1+4, "; EDNS:")) {
free(s);
return 0;
}
free(s);
}
/* compare packets */
unit_assert(match_all(p1, p2));
ldns_pkt_free(p1);
ldns_pkt_free(p2);
unit_assert(match_all(ldns_buffer_begin(pkt), ldns_buffer_limit(pkt),
ldns_buffer_begin(out), ldns_buffer_limit(out), 1,
matches_nolocation));
return 0;
}
@ -243,16 +145,20 @@ test_buffers(ldns_buffer* pkt, ldns_buffer* out)
static void
checkformerr(ldns_buffer* pkt)
{
ldns_pkt* p;
ldns_status status = ldns_buffer2pkt_wire(&p, pkt);
if(vbmp) printf("formerr, ldns parse is: %s\n",
ldns_get_errorstr_by_id(status));
if(status == LDNS_STATUS_OK) {
int status = 0;
char* s = ldns_wire2str_pkt(ldns_buffer_begin(pkt),
ldns_buffer_limit(pkt));
if(!s) fatal_exit("out of memory");
if(strstr(s, "Error")) status = 1;
if(strstr(s, "error")) status = 1;
if(status == 0) {
printf("Formerr, but ldns gives packet:\n");
ldns_pkt_print(stdout, p);
printf("%s\n", s);
free(s);
exit(1);
}
unit_assert(status != LDNS_STATUS_OK);
free(s);
unit_assert(status != 0);
}
/** performance test message encoding */
@ -311,8 +217,9 @@ perftestpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out,
flags = ntohs(flags);
ret = reply_info_parse(pkt, alloc, &qi, &rep, region, &edns);
if(ret != 0) {
if(vbmp) printf("parse code %d: %s\n", ret,
ldns_lookup_by_id(ldns_rcodes, ret)->name);
char rbuf[16];
ldns_wire2str_rcode_buf(ret, rbuf, sizeof(rbuf));
if(vbmp) printf("parse code %d: %s\n", ret, rbuf);
if(ret == LDNS_RCODE_FORMERR)
checkformerr(pkt);
unit_assert(ret != LDNS_RCODE_SERVFAIL);
@ -325,37 +232,44 @@ perftestpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out,
regional_destroy(region);
}
/** print packed rrset */
static void
print_rrset(struct ub_packed_rrset_key* rrset)
{
struct packed_rrset_data* d = (struct packed_rrset_data*)rrset->
entry.data;
char buf[65535];
size_t i;
for(i=0; i<d->count+d->rrsig_count; i++) {
if(!packed_rr_to_string(rrset, i, 0, buf, sizeof(buf)))
printf("failedtoconvert %d\n", (int)i);
else
printf("%s\n", buf);
}
}
/** debug print a packet that failed */
static void
print_packet_rrsets(struct query_info* qinfo, struct reply_info* rep)
{
size_t i;
ldns_rr_list* l;
ldns_buffer* buf = ldns_buffer_new(65536);
log_query_info(0, "failed query", qinfo);
printf(";; ANSWER SECTION (%d rrsets)\n", (int)rep->an_numrrsets);
for(i=0; i<rep->an_numrrsets; i++) {
l = packed_rrset_to_rr_list(rep->rrsets[i], buf);
printf("; rrset %d\n", (int)i);
ldns_rr_list_print(stdout, l);
ldns_rr_list_deep_free(l);
print_rrset(rep->rrsets[i]);
}
printf(";; AUTHORITY SECTION (%d rrsets)\n", (int)rep->ns_numrrsets);
for(i=rep->an_numrrsets; i<rep->an_numrrsets+rep->ns_numrrsets; i++) {
l = packed_rrset_to_rr_list(rep->rrsets[i], buf);
printf("; rrset %d\n", (int)i);
ldns_rr_list_print(stdout, l);
ldns_rr_list_deep_free(l);
print_rrset(rep->rrsets[i]);
}
printf(";; ADDITIONAL SECTION (%d rrsets)\n", (int)rep->ar_numrrsets);
for(i=rep->an_numrrsets+rep->ns_numrrsets; i<rep->rrset_count; i++) {
l = packed_rrset_to_rr_list(rep->rrsets[i], buf);
printf("; rrset %d\n", (int)i);
ldns_rr_list_print(stdout, l);
ldns_rr_list_deep_free(l);
print_rrset(rep->rrsets[i]);
}
printf(";; packet end\n");
ldns_buffer_free(buf);
}
/** check that there is no data element that matches the RRSIG */
@ -417,8 +331,9 @@ testpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out,
flags = ntohs(flags);
ret = reply_info_parse(pkt, alloc, &qi, &rep, region, &edns);
if(ret != 0) {
if(vbmp) printf("parse code %d: %s\n", ret,
ldns_lookup_by_id(ldns_rcodes, ret)->name);
char rbuf[16];
ldns_wire2str_rcode_buf(ret, rbuf, sizeof(rbuf));
if(vbmp) printf("parse code %d: %s\n", ret, rbuf);
if(ret == LDNS_RCODE_FORMERR) {
unit_assert(!check_formerr_gone);
checkformerr(pkt);

View File

@ -45,6 +45,7 @@
#include "util/data/dname.h"
#include "testcode/unitmain.h"
#include "validator/val_neg.h"
#include "ldns/rrdef.h"
/** verbose unit test for negative cache */
static int negverbose = 0;

View File

@ -46,7 +46,7 @@
#include "validator/val_nsec.h"
#include "validator/val_nsec3.h"
#include "validator/validator.h"
#include "testcode/ldns-testpkts.h"
#include "testcode/testpkts.h"
#include "util/data/msgreply.h"
#include "util/data/msgparse.h"
#include "util/data/dname.h"
@ -56,6 +56,10 @@
#include "util/net_help.h"
#include "util/module.h"
#include "util/config_file.h"
#include "ldns/sbuffer.h"
#include "ldns/keyraw.h"
#include "ldns/str2wire.h"
#include "ldns/wire2str.h"
/** verbose signature test */
static int vsig = 0;
@ -68,20 +72,10 @@ entry_to_buf(struct entry* e, ldns_buffer* pkt)
if(e->reply_list->reply_from_hex) {
ldns_buffer_copy(pkt, e->reply_list->reply_from_hex);
} else {
ldns_status status;
size_t answer_size;
uint8_t* ans = NULL;
status = ldns_pkt2wire(&ans, e->reply_list->reply,
&answer_size);
if(status != LDNS_STATUS_OK) {
log_err("could not create reply: %s",
ldns_get_errorstr_by_id(status));
fatal_exit("error in test");
}
ldns_buffer_clear(pkt);
ldns_buffer_write(pkt, ans, answer_size);
ldns_buffer_write(pkt, e->reply_list->reply_pkt,
e->reply_list->reply_len);
ldns_buffer_flip(pkt);
free(ans);
}
}
@ -102,8 +96,9 @@ entry_to_repinfo(struct entry* e, struct alloc_cache* alloc,
ret = reply_info_parse(pkt, alloc, qi, rep, region, &edns);
lock_quick_unlock(&alloc->lock);
if(ret != 0) {
printf("parse code %d: %s\n", ret,
ldns_lookup_by_id(ldns_rcodes, ret)->name);
char rcode[16];
ldns_wire2str_rcode_buf(ret, rcode, sizeof(rcode));
printf("parse code %d: %s\n", ret, rcode);
unit_assert(ret != 0);
}
}
@ -216,9 +211,10 @@ verifytest_entry(struct entry* e, struct alloc_cache* alloc,
regional_free_all(region);
if(vsig) {
printf("verifying pkt:\n");
ldns_pkt_print(stdout, e->reply_list->reply);
printf("\n");
char* s = ldns_wire2str_pkt(e->reply_list->reply_pkt,
e->reply_list->reply_len);
printf("verifying pkt:\n%s\n", s?s:"outofmemory");
free(s);
}
entry_to_repinfo(e, alloc, region, pkt, &qinfo, &rep);
@ -254,9 +250,10 @@ dstest_entry(struct entry* e, struct alloc_cache* alloc,
regional_free_all(region);
if(vsig) {
printf("verifying DS-DNSKEY match:\n");
ldns_pkt_print(stdout, e->reply_list->reply);
printf("\n");
char* s = ldns_wire2str_pkt(e->reply_list->reply_pkt,
e->reply_list->reply_len);
printf("verifying DS-DNSKEY match:\n%s\n", s?s:"outofmemory");
free(s);
}
entry_to_repinfo(e, alloc, region, pkt, &qinfo, &rep);
ds = find_rrset_type(rep, LDNS_RR_TYPE_DS);
@ -427,9 +424,10 @@ nsec3_hash_test_entry(struct entry* e, rbtree_t* ct,
uint8_t* qname;
if(vsig) {
printf("verifying NSEC3 hash:\n");
ldns_pkt_print(stdout, e->reply_list->reply);
printf("\n");
char* s = ldns_wire2str_pkt(e->reply_list->reply_pkt,
e->reply_list->reply_len);
printf("verifying NSEC3 hash:\n%s\n", s?s:"outofmemory");
free(s);
}
entry_to_repinfo(e, alloc, region, buf, &qinfo, &rep);
nsec3 = find_rrset_type(rep, LDNS_RR_TYPE_NSEC3);

View File

@ -129,7 +129,7 @@ ENTRY_END
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AD NOERROR
REPLY QR RD RA AD DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER

View File

@ -128,7 +128,7 @@ ENTRY_END
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AD NOERROR
REPLY QR RD RA AD DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER

View File

@ -149,7 +149,7 @@ ENTRY_END
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA SERVFAIL
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER

View File

@ -136,7 +136,7 @@ ENTRY_END
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA SERVFAIL
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER

View File

@ -131,7 +131,7 @@ ENTRY_END
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AD NOERROR
REPLY QR RD RA AD DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER

View File

@ -128,7 +128,7 @@ ENTRY_END
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AD NOERROR
REPLY QR RD RA AD DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER

View File

@ -154,7 +154,7 @@ ENTRY_END
STEP 30 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA SERVFAIL
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER

View File

@ -154,7 +154,7 @@ ENTRY_END
STEP 30 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA SERVFAIL
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER

View File

@ -138,7 +138,7 @@ ENTRY_END
STEP 30 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER

View File

@ -99,7 +99,7 @@ ENTRY_END
STEP 30 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER

View File

@ -120,7 +120,7 @@ ENTRY_END
STEP 30 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER

View File

@ -299,7 +299,7 @@ ENTRY_END
STEP 43 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AD NOERROR
REPLY QR RD RA AD DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER

View File

@ -265,7 +265,7 @@ ENTRY_END
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AD NOERROR
REPLY QR RD RA AD DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
@ -292,7 +292,7 @@ ENTRY_END
STEP 40 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD CD RA NOERROR
REPLY QR RD CD RA DO NOERROR
SECTION QUESTION
ns.blabla.com. IN AAAA
SECTION ANSWER

View File

@ -475,7 +475,7 @@ ENTRY_END
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AD NOERROR
REPLY QR RD RA AD DO NOERROR
SECTION QUESTION
www.sub.example.com. IN A
SECTION ANSWER
@ -495,7 +495,7 @@ ENTRY_END
STEP 40 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD CD RA NOERROR
REPLY QR RD CD RA DO NOERROR
SECTION QUESTION
ns.blabla.com. IN AAAA
SECTION ANSWER

View File

@ -385,7 +385,7 @@ ENTRY_END
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AD NOERROR
REPLY QR RD RA AD DO NOERROR
SECTION QUESTION
www.sub.example.com. IN A
SECTION ANSWER
@ -405,7 +405,7 @@ ENTRY_END
STEP 40 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD CD RA NOERROR
REPLY QR RD CD RA DO NOERROR
SECTION QUESTION
ns.blabla.com. IN AAAA
SECTION ANSWER

View File

@ -577,7 +577,7 @@ ENTRY_END
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA SERVFAIL
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
www.sub.example.com. IN A
SECTION ANSWER
@ -594,7 +594,7 @@ ENTRY_END
STEP 120 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA SERVFAIL
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
ftp.sub.example.com. IN A
SECTION ANSWER
@ -614,7 +614,7 @@ ENTRY_END
STEP 220 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AD NOERROR
REPLY QR RD RA AD DO NOERROR
SECTION QUESTION
www.sub.example.com. IN A
SECTION ANSWER

View File

@ -418,7 +418,7 @@ ENTRY_END
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AD NOERROR
REPLY QR RD RA AD DO NOERROR
SECTION QUESTION
www.sub.sub.example.com. IN A
SECTION ANSWER
@ -438,7 +438,7 @@ ENTRY_END
STEP 40 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD CD RA NOERROR
REPLY QR RD CD RA DO NOERROR
SECTION QUESTION
ns.blabla.com. IN AAAA
SECTION ANSWER

View File

@ -559,7 +559,7 @@ ENTRY_END
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA SERVFAIL
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
www.sub.example.com. IN A
SECTION ANSWER
@ -576,7 +576,7 @@ ENTRY_END
STEP 120 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA SERVFAIL
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
ftp.sub.example.com. IN A
SECTION ANSWER
@ -596,7 +596,7 @@ ENTRY_END
STEP 220 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AD NOERROR
REPLY QR RD RA AD DO NOERROR
SECTION QUESTION
www.sub.example.com. IN A
SECTION ANSWER

View File

@ -265,7 +265,7 @@ ENTRY_END
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AD NOERROR
REPLY QR RD RA AD DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
@ -292,7 +292,7 @@ ENTRY_END
STEP 40 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD CD RA NOERROR
REPLY QR RD CD RA DO NOERROR
SECTION QUESTION
ns.blabla.com. IN AAAA
SECTION ANSWER

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