Commit 843960c1 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰
Browse files

[master] Merge branch 'trac3421' ('host' removed from examples)

Conflicts:
	ChangeLog
parents 0f67ccb1 aeea893f
822. [build] tomek
'host' program was removed from examples.
(Trac #3421, git aeea893fb1c52d20258929a62a59ae2e7bd12e3d)
821. [bug] marcin
DHCP servers no longer log an error when Interface Manager fails to
receive a packet as a result of signal being received.
......
ACLOCAL_AMFLAGS = -I m4macros -I examples/m4 ${ACLOCAL_FLAGS}
ACLOCAL_AMFLAGS = -I m4macros ${ACLOCAL_FLAGS}
# ^^^^^^^^ This has to be the first line and cannot come later in this
# Makefile.am due to some bork in some versions of autotools.
......
......@@ -101,8 +101,7 @@ fi
# Linker options
# check -R, "-Wl,-R" or -rpath (we share the AX function defined in
# examples/m4)
# check -R, "-Wl,-R" or -rpath
AX_ISC_RPATH
# Compiler dependent settings: define some mandatory CXXFLAGS here.
......
If using git (not the tarball), build the "configure" file:
autoreconf --install
To then build from source:
./configure
make
You may have to specify the location of BIND 10 header files and
library objects. See configure options by ./configure --help.
SUBDIRS = host
# Make sure macros under m4 will be included
ACLOCAL_AMFLAGS = -I m4
This is the top directory for sample programs that can be developed
using public BIND 10 libraries outside of the BIND 10 project. It's
intended to be built with installed BIND 10 header files and library
using public Kea libraries outside of the Kea project. It's
intended to be built with installed Kea header files and library
objects, so it's not a target of the main build tree, and does not
refer to any other part of the BIND 10 source tree that contains
refer to any other part of the Kea source tree that contains
this directory.
On the top (sub) directory (where this README file is stored), we
provide a sample configure.ac and Makefile.am files for GNU automake
environments with helper autoconf macros to detect the availability and
location of BIND 10 header files and library objects.
location of Kea header files and library objects.
You can use the configure.ac and Makefile.am files with macros under
the "m4" subdirectory as a template for your own project. The key is
to call the AX_ISC_BIND10 function (as the sample configure.ac does)
from your configure.ac. Then it will check the availability of
necessary stuff and set some corresponding AC variables. You can then
use the resulting variables in your Makefile.in or Makefile.am.
If you use automake, don't forget adding the following line to the top
level Makefile.am:
ACLOCAL_AMFLAGS = -I m4
This is necessary to incorporate the helper macro definitions.
If you don't use automake but autoconf, make sure to add the following
to the configure.ac file:
sinclude(m4/ax_boost_include.m4)
sinclude(m4/ax_isc_bind10.m4)
(and same for other m4 files as they are added under m4/)
On some systems, especially if you have installed the BIND 10
libraries in an uncommon path, programs linked with the BIND 10
library may not work at run time due to the "missing" shared library.
Normally, you should be able to avoid this problem by making sure
to invoking the program explicitly specifying the path to the library,
e.g., "LD_LIBRARY_PATH=/usr/local/lib/bind10 ./my_bind10_app", or
you may not even notice the issue if you have installed BIND 10
library in a common library path on your system (sometimes you may
still need to run ldconfig(8) beforehand). Another option is to embed
the path to the library in your program. While this approach is
controversial, and some people rather choose the alternatives, we
provide a helper tool in case you want to use this option: see the
lines using BIND10_RPATH in the sample configure.ac file of this
directory.
This directory is currently empty, but we expect to move example
code here soon.
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.59])
AC_INIT(bind10-examples, 20120817, bind10-dev@isc.org)
AC_CONFIG_SRCDIR([README])
AM_INIT_AUTOMAKE
AC_CONFIG_HEADERS([config.h])
# Checks for programs.
AC_PROG_CXX
AC_LANG([C++])
# Checks for BIND 10 headers and libraries
AX_ISC_BIND10
# We use -R option etc so the resulting program will be more likekly to
# "just work" by default. Embedding a specific library path is a controversial
# practice, though; if you don't like it you can remove the following setting,
# or use the --disable-rpath option.
if test "x$BIND10_RPATH" != "x"; then
LDFLAGS="$LDFLAGS $BIND10_RPATH"
fi
# For the example host program, we require some socket API library
# and the BIND 10 DNS library.
# In practice, these are specific to Solaris, but wouldn't do any harm for
# others except for the checking overhead.
AC_SEARCH_LIBS(inet_pton, [nsl])
AC_SEARCH_LIBS(recvfrom, [socket])
if test "x$BIND10_DNS_LIB" = "x"; then
AC_MSG_ERROR([unable to find BIND 10 DNS library needed to build 'host'])
fi
# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
AC_CONFIG_FILES([Makefile
host/Makefile])
AC_OUTPUT
AM_CPPFLAGS = $(BOOST_CPPFLAGS) $(BIND10_CPPFLAGS)
bin_PROGRAMS = b10-host
b10_host_SOURCES = host.cc
b10_host_LDFLAGS = ${BIND10_LDFLAGS}
b10_host_LDADD = ${BIND10_DNS_LIB}
Rewriting host(1) in C++ from scratch using BIND 10's libdns++.
The bugs and incompatibilities are listed in the manual page
and in the source code.
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "&#8212;">]>
<!--
- Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-->
<!-- $Id$ -->
<refentry>
<refentryinfo>
<date>May 4, 2011</date>
</refentryinfo>
<refmeta>
<refentrytitle>b10-host</refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo>BIND10</refmiscinfo>
</refmeta>
<refnamediv>
<refname>b10-host</refname>
<refpurpose>DNS lookup utility</refpurpose>
</refnamediv>
<docinfo>
<copyright>
<year>2011</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
</docinfo>
<refsynopsisdiv>
<cmdsynopsis>
<command>b10-host</command>
<arg><option>-a</option></arg>
<arg><option>-c <replaceable>class</replaceable></option></arg>
<arg><option>-d</option></arg>
<arg><option>-p <replaceable>port</replaceable></option></arg>
<arg><option>-r</option></arg>
<arg><option>-t <replaceable>type</replaceable></option></arg>
<arg><option>-v</option></arg>
<arg><replaceable>name</replaceable></arg>
<arg><option><replaceable>server</replaceable></option></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>DESCRIPTION</title>
<para>
The <command>b10-host</command> utility does DNS lookups.
Its initial goal is to be a
<citerefentry><refentrytitle>host</refentrytitle>
<manvolnum>1</manvolnum></citerefentry>
clone, but also add a few features useful for BIND 10 development
testing.
</para>
<para>
By default, it looks up the A, AAAA, and MX record sets for the
<replaceable>name</replaceable>.
Optionally, you may select a name server to query against by adding
the <replaceable>server</replaceable> argument.
</para>
</refsect1>
<refsect1>
<title>OPTIONS</title>
<para>The arguments are as follows:</para>
<variablelist>
<varlistentry>
<term><option>-a</option></term>
<listitem><para>
Enable verbose mode and do a query for type ANY.
(If the <option>-t</option> option is also set, then the
ANY query is not done, but it still uses verbose mode.)
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-c <replaceable>class</replaceable></option></term>
<listitem><para>
Define the class for the query.
The default is IN (Internet).
<!-- TODO: bug if class is unknown causes seg fault and possible core dump -->
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-d</option></term>
<listitem><para>
Enable verbose output mode, including elapsed time in
milliseconds.
Verbose mode shows the header, question, answer, authority,
and additional sections (if provided).
(Same as <option>-v</option>.)
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-p <replaceable>port</replaceable></option></term>
<listitem><para>
Select an alternative port for the query.
This may be a number or a service name.
The default is 53 (domain).
This is not a standard feature of
<citerefentry><refentrytitle>host</refentrytitle>
<manvolnum>1</manvolnum></citerefentry>.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-r</option></term>
<listitem><para>
Disable recursive processing by not setting the
Recursion Desired flag in the query.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-t <replaceable>type</replaceable></option></term>
<listitem><para>
Select a specific resource record type for the query.
By default, it looks up the A, AAAA, and MX record sets.
<!-- TODO: bug if class is unknown causes seg fault and possible core dump -->
(This overrides the <option>-a</option> option.)
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-v</option></term>
<listitem><para>
Same as <option>-d</option> option.
</para></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>COMPATIBILITY / BUGS</title>
<para>
<command>b10-host</command> does not do reverse lookups by
default yet (by detecting if name is a IPv4 or IPv6 address).
</para>
<para>
Unknown <option>-c</option> class or <option>-t</option> type
causes <command>b10-host</command> to Abort.
</para>
<para>
Not all types are supported yet for formatting.
Not all switches are supported yet.
</para>
<para>
It doesn't use <filename>/etc/resolv.conf</filename> at this time.
The default name server used is 127.0.0.1.
</para>
<para>
<option>-p</option> is not a standard feature.
</para>
</refsect1>
<refsect1>
<title>HISTORY</title>
<para>
The C++ version of <command>b10-host</command> was started in
October 2009 by Jeremy C. Reed of ISC.
Its usage and output were based on the standard <command>host</command>
command.
</para>
</refsect1>
</refentry><!--
- Local variables:
- mode: sgml
- End:
-->
// Copyright (C) 2010-2011 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
// host rewritten in C++ using Kea DNS library
#include <arpa/inet.h>
#include <netdb.h> // for getaddrinfo
#include <sys/time.h> // for gettimeofday
#include <sys/socket.h> // networking functions and definitions on FreeBSD
#include <unistd.h>
#include <string>
#include <iostream>
#include <util/buffer.h>
#include <dns/name.h>
#include <dns/message.h>
#include <dns/messagerenderer.h>
#include <dns/opcode.h>
#include <dns/rcode.h>
#include <dns/rrclass.h>
#include <dns/rrtype.h>
#include <dns/rrset.h>
#include <dns/message.h>
using namespace std;
using namespace isc::dns;
using namespace isc::util;
namespace {
char* dns_type = NULL; // not set, so A, AAAA, MX
const char* server = "127.0.0.1";
const char* server_port = "53";
const char* dns_class = "IN";
bool verbose = false;
bool dns_any = false;
int first_time = 1;
bool recursive_bit = true;
struct timeval before_time, after_time;
int
host_lookup(const char* const name, const char* const dns_class,
const char* const type, bool any) {
Message msg(Message::RENDER);
msg.setQid(0); // does this matter?
// TODO: add switch for this
msg.setOpcode(Opcode::QUERY());
msg.setRcode(Rcode::NOERROR());
if (recursive_bit) {
msg.setHeaderFlag(Message::HEADERFLAG_RD); // set recursive bit
}
msg.addQuestion(Question(Name(name),
RRClass(dns_class),
any ? RRType::ANY() : RRType(type))); // if NULL then:
MessageRenderer renderer;
msg.toWire(renderer);
struct addrinfo hints, *res;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = 0; // not using AI_NUMERICHOST in case to bootstrap
if (getaddrinfo(server, server_port, &hints, &res) != 0) {
cerr << "address/port conversion for " << server << ":"
<< server_port << " failed" << endl;
return (1);
}
if (verbose) {
cout << "Trying \"" << name << "\"\n";
}
if (verbose && first_time) {
// this is only output the first time
first_time = 0;
cout << "Using domain server:\n";
cout << "Name: " << server << "\n";
// TODO: I guess I have to do a lookup to get that address and aliases
// too
//cout << "Address: " << address << "\n" ;
//cout << "Aliases: " << server << "\n";
}
int s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (s < 0) {
cerr << "failed to open socket" << endl;
return (1);
}
if (verbose) {
gettimeofday(&before_time, NULL);
}
sendto(s, renderer.getData(), renderer.getLength(), 0, res->ai_addr,
res->ai_addrlen);
struct sockaddr_storage ss;
struct sockaddr* sa;
socklen_t sa_len;
sa_len = sizeof(ss);
sa = static_cast<struct sockaddr*>((void*)&ss);
char recvbuf[4096];
int cc;
if ((cc = recvfrom(s, recvbuf, sizeof(recvbuf), 0, sa, &sa_len)) > 0) {
try {
Message rmsg(Message::PARSE);
InputBuffer ibuffer(recvbuf, cc);
rmsg.fromWire(ibuffer);
if (!verbose) {
string description = "";
for (RRsetIterator it =
rmsg.beginSection(Message::SECTION_ANSWER);
it != rmsg.endSection(Message::SECTION_ANSWER);
++it) {
if ((*it)->getType() == RRType::A()) {
description = "has address";
}
else if ((*it)->getType() == RRType::AAAA()) {
description = "has IPv6 address";
}
else if ((*it)->getType() == RRType::MX()) {
description = "mail is handled by";
}
else if ((*it)->getType() == RRType::TXT()) {
description = "descriptive text";
}
RdataIteratorPtr rit = (*it)->getRdataIterator();
for (; !rit->isLast(); rit->next()) {
// instead of using my name, maybe use returned label?
cout << name << " " << description << " " <<
(*rit).getCurrent().toText() << endl;
}
}
} else {
gettimeofday(&after_time, NULL);
// HEADER and QUESTION, ANSWER, AUTHORITY, and ADDITIONAL
std::cout << rmsg.toText() << std::endl;
if (before_time.tv_usec > after_time.tv_usec) {
after_time.tv_usec += 1000000;
--after_time.tv_sec;
}
int elapsed_time =
(after_time.tv_sec - before_time.tv_sec)
+ ((after_time.tv_usec - before_time.tv_usec))/1000;
// TODO: if NXDOMAIN, host(1) doesn't show HEADER
// Host hsdjkfhksjhdfkj not found: 3(NXDOMAIN)
// TODO: test if NXDOMAIN
std::cout << "Received " << cc <<
" bytes in " << elapsed_time << " ms\n";
// TODO: " bytes from 127.0.0.1#53 in 0 ms
} //verbose
/*
TODO: handle InvalidRRClass
TODO: handle invalid type exception
} catch (InvalidType ivt) {
std::cerr << "invalid type:" << ivt.what();
*/
} catch (const exception& ex) {
std::cerr << "parse failed for " <<
string(name) << "/" << type << ": " << ex.what() << std::endl;
} catch (...) {
std::cerr << "parse failed for " << string(name) << "/" << type;
}
}
freeaddrinfo(res);
return (0);
} // host_lookup()
}
int
main(int argc, char* argv[]) {
int c;
while ((c = getopt(argc, argv, "ac:dp:rt:v")) != -1)
switch (c) {
case 'a':
dns_any = true;
verbose = true;
break;
case 'c':
dns_class = optarg;
break;
// p for port is a non-standard switch
case 'p':
server_port = optarg;
break;
case 'r':
recursive_bit = false;
break;
case 't':
dns_type = optarg;
break;
case 'd':
// drop through to v, because debug and verbose are equivalent
case 'v':
verbose = true;
break;
}
argc -= optind;
argv += optind;
if (argc < 1) {
cout << "Usage: host [-adrv] [-c class] [-p port] [-t type] hostname [server]\n";
exit(1);
}
if (argc >= 2) {
server = argv[1];
}
if (dns_type == NULL) {
host_lookup(argv[0], dns_class, "A", dns_any);
// TODO: don't do next if A doesn't exist
host_lookup(argv[0], dns_class, "AAAA", dns_any);
host_lookup(argv[0], dns_class, "MX", dns_any);
} else {
// -t overrides -a, regardless of order
host_lookup(argv[0], dns_class, dns_type, false);
}
return (0);
}
dnl @synopsis AX_BOOST_INCLUDE
dnl
dnl Test for the Boost C++ header files
dnl
dnl If no path to the installed boost header files is given via the
dnl --with-boost-include option, the macro searchs under
dnl /usr/local /usr/pkg /opt /opt/local directories.
dnl
dnl This macro calls:
dnl
dnl AC_SUBST(BOOST_CPPFLAGS)
dnl
AC_DEFUN([AX_BOOST_INCLUDE], [
AC_LANG_SAVE
AC_LANG([C++])
#
# Configure Boost header path
#
# If explicitly specified, use it.
AC_ARG_WITH([boost-include],
AS_HELP_STRING([--with-boost-include=PATH],
[specify exact directory for Boost headers]),