First attempt to do IPv6 on the resolver

Initial
Stephane Bortzmeyer 20 years ago
parent ccc43a77fe
commit 1abc617ba3

@ -1,11 +1,12 @@
/*
* DNS plugin.
* $Id$
* DNS plugin. $Id$
*/
#define IN_PLUGIN
#include "../../echoping.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
@ -32,45 +33,43 @@ boolean no_recurse = FALSE;
* strings. *
****************************************************************/
int
nsError (error, domain)
nsError(error, domain)
int error;
char *domain;
{
switch (error)
{
switch (error) {
case HOST_NOT_FOUND:
err_ret ("Unknown domain: %s\n", domain);
err_ret("Unknown domain: %s\n", domain);
return -1;
case NO_DATA:
err_ret ("No records for %s in the Answer section\n", domain);
err_ret("No records for %s in the Answer section\n", domain);
return -1;
case TRY_AGAIN:
err_ret ("No response for query\n");
err_ret("No response for query\n");
return -2;
default:
err_ret ("Unexpected error\n");
err_ret("Unexpected error\n");
return -1;
}
}
void
dns_usage (const char *msg)
dns_usage(const char *msg)
{
if (msg)
{
fprintf (stderr, "Error: %s\n", msg);
if (msg) {
fprintf(stderr, "Error: %s\n", msg);
}
poptPrintUsage (dns_poptcon, stderr, 0);
fprintf (stderr, " request\n");
exit (1);
poptPrintUsage(dns_poptcon, stderr, 0);
fprintf(stderr, " request\n");
exit(1);
}
char *
init (const int argc, const char **argv)
init(const int argc, const char **argv)
{
int value;
char *hostname;
char *msg = malloc (256);
char *msg = malloc(256);
char *type_name, *upper_type_name = NULL;
/* popt variables */
struct poptOption options[] = {
@ -85,103 +84,122 @@ init (const int argc, const char **argv)
"no-recurse"},
POPT_AUTOHELP POPT_TABLEEND
};
dns_poptcon = poptGetContext (NULL, argc,
dns_poptcon = poptGetContext(NULL, argc,
argv, options, POPT_CONTEXT_KEEP_FIRST);
while ((value = poptGetNextOpt (dns_poptcon)) > 0)
{
if (value < -1)
{
sprintf (msg, "%s: %s",
poptBadOption (dns_poptcon, POPT_BADOPTION_NOALIAS),
poptStrerror (value));
dns_usage (msg);
while ((value = poptGetNextOpt(dns_poptcon)) > 0) {
if (value < -1) {
sprintf(msg, "%s: %s",
poptBadOption(dns_poptcon, POPT_BADOPTION_NOALIAS),
poptStrerror(value));
dns_usage(msg);
}
}
hostname = (char *) poptGetArg (dns_poptcon); /* Not used */
request = (char *) poptGetArg (dns_poptcon);
hostname = (char *)poptGetArg(dns_poptcon); /* Not used */
request = (char *)poptGetArg(dns_poptcon);
if (request == NULL)
dns_usage ("Mandatory request missing");
if ((type_name == NULL) || !strcmp (type_name, ""))
dns_usage("Mandatory request missing");
if ((type_name == NULL) || !strcmp(type_name, ""))
type = T_A;
else
{
upper_type_name = to_upper (type_name);
/* TODO: a better algorithm. Use dns_rdatatype_fromtext in BIND ? */
if (!strcmp (upper_type_name, "A"))
else {
upper_type_name = to_upper(type_name);
/*
* TODO: a better algorithm. Use dns_rdatatype_fromtext in
* BIND ?
*/
if (!strcmp(upper_type_name, "A"))
type = T_A;
else if (!strcmp (upper_type_name, "AAAA"))
else if (!strcmp(upper_type_name, "AAAA"))
type = T_AAAA;
else if (!strcmp (upper_type_name, "NS"))
else if (!strcmp(upper_type_name, "NS"))
type = T_NS;
else if (!strcmp (upper_type_name, "SOA"))
else if (!strcmp(upper_type_name, "SOA"))
type = T_SOA;
else if (!strcmp (upper_type_name, "MX"))
else if (!strcmp(upper_type_name, "MX"))
type = T_MX;
else if (!strcmp (upper_type_name, "SRV"))
else if (!strcmp(upper_type_name, "SRV"))
type = T_SRV;
else if (!strcmp (upper_type_name, "CNAME"))
else if (!strcmp(upper_type_name, "CNAME"))
type = T_CNAME;
else if (!strcmp (upper_type_name, "PTR"))
else if (!strcmp(upper_type_name, "PTR"))
type = T_PTR;
else if (!strcmp (upper_type_name, "TXT"))
else if (!strcmp(upper_type_name, "TXT"))
type = T_TXT;
else
dns_usage ("Unknown type");
dns_usage("Unknown type");
}
return "domain";
}
void
start (struct addrinfo *res)
start(struct addrinfo * res)
{
struct sockaddr name_server_sockaddr;
struct sockaddr_in name_server_sockaddr_in;
struct sockaddr_in6 name_server_sockaddr_in6;
name_server = *res;
name_server_sockaddr = *name_server.ai_addr;
if (name_server_sockaddr.sa_family == AF_INET) {
/* Converts a generic sockaddr to an IPv4 sockaddr_in */
(void) memcpy ((void *) &name_server_sockaddr_in, &name_server_sockaddr,
sizeof (struct sockaddr));
if (res_init () < 0)
err_sys ("res_init");
_res.nsaddr_list[0] = name_server_sockaddr_in; /* TODO: and IPv6? We now if we have _res_ext (xBSD) so we should use HAVE_RES_EXT here */
(void)memcpy((void *)&name_server_sockaddr_in, &name_server_sockaddr,
sizeof(struct sockaddr));
} else if (name_server_sockaddr.sa_family == AF_INET6) {
#ifdef HAVE_RES_EXT
/* Converts a generic sockaddr to an IPv6 sockaddr_in6 */
(void)memcpy((void *)&name_server_sockaddr_in6, &name_server_sockaddr,
sizeof(struct sockaddr));
#else
err_quit("IPv6 name servers not supported on this platform, may be you should use the -4 option");
#endif
} else {
err_quit("Unknown family for address of the server");
}
if (res_init() < 0)
err_sys("res_init");
if (name_server_sockaddr.sa_family == AF_INET) {
_res.nsaddr_list[0] = name_server_sockaddr_in;
} else if (name_server_sockaddr.sa_family == AF_INET6) {
#ifdef HAVE_RES_EXT
(void)memcpy(_res_ext.nsaddr_list, &name_server_sockaddr_in6, sizeof(struct sockaddr_in6));
#endif
}
_res.nscount = 1;
_res.options &= ~(RES_DNSRCH | RES_DEFNAMES | RES_NOALIASES);
if (use_tcp)
{
if (use_tcp) {
_res.options |= RES_USEVC;
}
if (no_recurse)
{
if (no_recurse) {
_res.options &= ~RES_RECURSE;
}
}
int
execute ()
execute()
{
union
{
union {
HEADER hdr; /* defined in resolv.h */
u_char buf[PACKETSZ]; /* defined in arpa/nameser.h */
} response; /* response buffers */
int response_length; /* buffer length */
if ((response_length = res_query (request, /* the domain we care about */
if ((response_length = res_query(request, /* the domain we care
* about */
C_IN, /* Internet class records */
type, (u_char *) & response, /*response buffer */
sizeof (response))) /*buffer size */
< 0)
{ /*If negative */
nsError (h_errno, request); /* report the error */
type, (u_char *) & response, /* response buffer */
sizeof(response))) /* buffer size */
<0) { /* If negative */
nsError(h_errno, request); /* report the error */
if (h_errno == TRY_AGAIN)
return -1; /* More luck next time? */
else
return -2; /* Give in */
}
/* TODO: better analysis of the replies. For instance, replies can be in the authority section (delegation info) */
/*
* TODO: better analysis of the replies. For instance, replies can be
* in the authority section (delegation info)
*/
return 0;
}
void
terminate ()
terminate()
{
}

Loading…
Cancel
Save