2353. [func] Add support for Name Server ID (RFC 5001).
'dig +nsid' requests NSID from server.
'request-nsid yes;' causes recursive server to send
NSID requests to upstream servers. Server responds
to NSID requests with the string configured by
'server-id' option. [RT #17091]
This commit is contained in:
@@ -49,7 +49,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: nameser.h,v 1.8 2005/04/27 04:56:16 sra Exp $
|
||||
* $Id: nameser.h,v 1.8.672.1 2008/04/03 02:12:21 marka Exp $
|
||||
*/
|
||||
|
||||
#ifndef _ARPA_NAMESER_H_
|
||||
@@ -427,9 +427,10 @@ typedef enum __ns_cert_types {
|
||||
#define NS_NXT_MAX 127
|
||||
|
||||
/*%
|
||||
* EDNS0 extended flags, host order.
|
||||
* EDNS0 extended flags and option codes, host order.
|
||||
*/
|
||||
#define NS_OPT_DNSSEC_OK 0x8000U
|
||||
#define NS_OPT_NSID 3
|
||||
|
||||
/*%
|
||||
* Inline versions of get/put short/long. Pointer is advanced.
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
/*%
|
||||
* @(#)resolv.h 8.1 (Berkeley) 6/2/93
|
||||
* $Id: resolv.h,v 1.23 2005/08/25 04:41:46 marka Exp $
|
||||
* $Id: resolv.h,v 1.23.564.1 2008/04/03 02:12:21 marka Exp $
|
||||
*/
|
||||
|
||||
#ifndef _RESOLV_H_
|
||||
@@ -250,6 +250,7 @@ union res_sockaddr_union {
|
||||
#define RES_NOCHECKNAME 0x00008000 /*%< do not check names for sanity. */
|
||||
#define RES_KEEPTSIG 0x00010000 /*%< do not strip TSIG records */
|
||||
#define RES_BLAST 0x00020000 /*%< blast all recursive servers */
|
||||
#define RES_NSID 0x00040000 /*%< request name server ID */
|
||||
#define RES_NOTLDQUERY 0x00100000 /*%< don't unqualified name as a tld */
|
||||
#define RES_USE_DNSSEC 0x00200000 /*%< use DNSSEC using OK bit in OPT */
|
||||
/* #define RES_DEBUG2 0x00400000 */ /* nslookup internal */
|
||||
@@ -396,6 +397,7 @@ extern const struct res_sym __p_rcode_syms[];
|
||||
#define sym_ntos __sym_ntos
|
||||
#define sym_ston __sym_ston
|
||||
#define res_nopt __res_nopt
|
||||
#define res_nopt_rdata __res_nopt_rdata
|
||||
#define res_ndestroy __res_ndestroy
|
||||
#define res_nametoclass __res_nametoclass
|
||||
#define res_nametotype __res_nametotype
|
||||
@@ -482,6 +484,8 @@ int res_findzonecut2 __P((res_state, const char *, ns_class, int,
|
||||
union res_sockaddr_union *, int));
|
||||
void res_nclose __P((res_state));
|
||||
int res_nopt __P((res_state, int, u_char *, int, int));
|
||||
int res_nopt_rdata __P((res_state, int, u_char *, int, u_char *,
|
||||
u_short, u_short, u_char *));
|
||||
void res_send_setqhook __P((res_send_qhook));
|
||||
void res_send_setrhook __P((res_send_rhook));
|
||||
int __res_vinit __P((res_state, int));
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
|
||||
static const char rcsid[] = "$Id: res_debug.c,v 1.15 2005/07/28 06:51:50 marka Exp $";
|
||||
static const char rcsid[] = "$Id: res_debug.c,v 1.15.574.1 2008/04/03 02:12:21 marka Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "port_before.h"
|
||||
@@ -189,10 +189,56 @@ do_section(const res_state statp,
|
||||
p_type(ns_rr_type(rr)),
|
||||
p_class(ns_rr_class(rr)));
|
||||
else if (section == ns_s_ar && ns_rr_type(rr) == ns_t_opt) {
|
||||
u_int16_t optcode, optlen, rdatalen = ns_rr_rdlen(rr);
|
||||
u_int32_t ttl = ns_rr_ttl(rr);
|
||||
|
||||
fprintf(file,
|
||||
"; EDNS: version: %u, udp=%u, flags=%04x\n",
|
||||
(ttl>>16)&0xff, ns_rr_class(rr), ttl&0xffff);
|
||||
|
||||
while (rdatalen >= 4) {
|
||||
const u_char *cp = ns_rr_rdata(rr);
|
||||
int i;
|
||||
|
||||
GETSHORT(optcode, cp);
|
||||
GETSHORT(optlen, cp);
|
||||
|
||||
if (optcode == NS_OPT_NSID) {
|
||||
fputs("; NSID: ", file);
|
||||
if (optlen == 0) {
|
||||
fputs("; NSID\n", file);
|
||||
} else {
|
||||
fputs("; NSID: ", file);
|
||||
for (i = 0; i < optlen; i++)
|
||||
fprintf(file, "%02x ",
|
||||
cp[i]);
|
||||
fputs(" (",file);
|
||||
for (i = 0; i < optlen; i++)
|
||||
fprintf(file, "%c",
|
||||
isprint(cp[i])?
|
||||
cp[i] : '.');
|
||||
fputs(")\n", file);
|
||||
}
|
||||
} else {
|
||||
if (optlen == 0) {
|
||||
fprintf(file, "; OPT=%u\n",
|
||||
optcode);
|
||||
} else {
|
||||
fprintf(file, "; OPT=%u: ",
|
||||
optcode);
|
||||
for (i = 0; i < optlen; i++)
|
||||
fprintf(file, "%02x ",
|
||||
cp[i]);
|
||||
fputs(" (",file);
|
||||
for (i = 0; i < optlen; i++)
|
||||
fprintf(file, "%c",
|
||||
isprint(cp[i]) ?
|
||||
cp[i] : '.');
|
||||
fputs(")\n", file);
|
||||
}
|
||||
}
|
||||
rdatalen -= 4 + optlen;
|
||||
}
|
||||
} else {
|
||||
n = ns_sprintrr(handle, &rr, NULL, NULL,
|
||||
buf, buflen);
|
||||
@@ -204,7 +250,7 @@ do_section(const res_state statp,
|
||||
buf = malloc(buflen += 1024);
|
||||
if (buf == NULL) {
|
||||
fprintf(file,
|
||||
";; memory allocation failure\n");
|
||||
";; memory allocation failure\n");
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
@@ -381,7 +427,7 @@ const struct res_sym __p_default_section_syms[] = {
|
||||
{ns_s_an, "ANSWER", (char *)0},
|
||||
{ns_s_ns, "AUTHORITY", (char *)0},
|
||||
{ns_s_ar, "ADDITIONAL", (char *)0},
|
||||
{0, (char *)0, (char *)0}
|
||||
{0, (char *)0, (char *)0}
|
||||
};
|
||||
|
||||
const struct res_sym __p_update_section_syms[] = {
|
||||
@@ -389,7 +435,7 @@ const struct res_sym __p_update_section_syms[] = {
|
||||
{S_PREREQ, "PREREQUISITE", (char *)0},
|
||||
{S_UPDATE, "UPDATE", (char *)0},
|
||||
{S_ADDT, "ADDITIONAL", (char *)0},
|
||||
{0, (char *)0, (char *)0}
|
||||
{0, (char *)0, (char *)0}
|
||||
};
|
||||
|
||||
const struct res_sym __p_key_syms[] = {
|
||||
@@ -617,6 +663,7 @@ p_option(u_long option) {
|
||||
case RES_USE_INET6: return "inet6";
|
||||
#ifdef RES_USE_EDNS0 /*%< KAME extension */
|
||||
case RES_USE_EDNS0: return "edns0";
|
||||
case RES_NSID: return "nsid";
|
||||
#endif
|
||||
#ifdef RES_USE_DNAME
|
||||
case RES_USE_DNAME: return "dname";
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
|
||||
static const char rcsid[] = "$Id: res_mkquery.c,v 1.6 2005/04/27 04:56:42 sra Exp $";
|
||||
static const char rcsid[] = "$Id: res_mkquery.c,v 1.6.672.1 2008/04/03 02:12:21 marka Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "port_before.h"
|
||||
@@ -203,9 +203,6 @@ res_nmkquery(res_state statp,
|
||||
|
||||
#ifdef RES_USE_EDNS0
|
||||
/* attach OPT pseudo-RR, as documented in RFC2671 (EDNS0). */
|
||||
#ifndef T_OPT
|
||||
#define T_OPT 41
|
||||
#endif
|
||||
|
||||
int
|
||||
res_nopt(res_state statp,
|
||||
@@ -230,13 +227,14 @@ res_nopt(res_state statp,
|
||||
if ((ep - cp) < 1 + RRFIXEDSZ)
|
||||
return (-1);
|
||||
|
||||
*cp++ = 0; /*%< "." */
|
||||
ns_put16(T_OPT, cp); /*%< TYPE */
|
||||
*cp++ = 0; /*%< "." */
|
||||
ns_put16(ns_t_opt, cp); /*%< TYPE */
|
||||
cp += INT16SZ;
|
||||
ns_put16(anslen & 0xffff, cp); /*%< CLASS = UDP payload size */
|
||||
ns_put16(anslen & 0xffff, cp); /*%< CLASS = UDP payload size */
|
||||
cp += INT16SZ;
|
||||
*cp++ = NOERROR; /*%< extended RCODE */
|
||||
*cp++ = 0; /*%< EDNS version */
|
||||
*cp++ = NOERROR; /*%< extended RCODE */
|
||||
*cp++ = 0; /*%< EDNS version */
|
||||
|
||||
if (statp->options & RES_USE_DNSSEC) {
|
||||
#ifdef DEBUG
|
||||
if (statp->options & RES_DEBUG)
|
||||
@@ -246,12 +244,60 @@ res_nopt(res_state statp,
|
||||
}
|
||||
ns_put16(flags, cp);
|
||||
cp += INT16SZ;
|
||||
ns_put16(0, cp); /*%< RDLEN */
|
||||
|
||||
ns_put16(0U, cp); /*%< RDLEN */
|
||||
cp += INT16SZ;
|
||||
|
||||
hp->arcount = htons(ntohs(hp->arcount) + 1);
|
||||
|
||||
return (cp - buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct variable data (RDATA) block for OPT psuedo-RR, append it
|
||||
* to the buffer, then update the RDLEN field (previously set to zero by
|
||||
* res_nopt()) with the new RDATA length.
|
||||
*/
|
||||
int
|
||||
res_nopt_rdata(res_state statp,
|
||||
int n0, /*%< current offset in buffer */
|
||||
u_char *buf, /*%< buffer to put query */
|
||||
int buflen, /*%< size of buffer */
|
||||
u_char *rdata, /*%< ptr to start of opt rdata */
|
||||
u_short code, /*%< OPTION-CODE */
|
||||
u_short len, /*%< OPTION-LENGTH */
|
||||
u_char *data) /*%< OPTION_DATA */
|
||||
{
|
||||
register u_char *cp, *ep;
|
||||
|
||||
#ifdef DEBUG
|
||||
if ((statp->options & RES_DEBUG) != 0U)
|
||||
printf(";; res_nopt_rdata()\n");
|
||||
#endif
|
||||
|
||||
cp = buf + n0;
|
||||
ep = buf + buflen;
|
||||
|
||||
if ((ep - cp) < (4 + len))
|
||||
return (-1);
|
||||
|
||||
if (rdata < (buf + 2) || rdata >= ep)
|
||||
return (-1);
|
||||
|
||||
ns_put16(code, cp);
|
||||
cp += INT16SZ;
|
||||
|
||||
ns_put16(len, cp);
|
||||
cp += INT16SZ;
|
||||
|
||||
memcpy(cp, data, len);
|
||||
cp += len;
|
||||
|
||||
len = cp - rdata;
|
||||
ns_put16(len, rdata - 2); /* Update RDLEN field */
|
||||
|
||||
return (cp - buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! \file */
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";
|
||||
static const char rcsid[] = "$Id: res_query.c,v 1.8 2005/04/27 04:56:42 sra Exp $";
|
||||
static const char rcsid[] = "$Id: res_query.c,v 1.8.672.1 2008/04/03 02:12:21 marka Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "port_before.h"
|
||||
@@ -116,8 +116,9 @@ res_nquery(res_state statp,
|
||||
{
|
||||
u_char buf[MAXPACKET];
|
||||
HEADER *hp = (HEADER *) answer;
|
||||
int n;
|
||||
u_int oflags;
|
||||
u_char *rdata;
|
||||
int n;
|
||||
|
||||
oflags = statp->_flags;
|
||||
|
||||
@@ -132,8 +133,14 @@ again:
|
||||
buf, sizeof(buf));
|
||||
#ifdef RES_USE_EDNS0
|
||||
if (n > 0 && (statp->_flags & RES_F_EDNS0ERR) == 0 &&
|
||||
(statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0U)
|
||||
(statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC|RES_NSID))) {
|
||||
n = res_nopt(statp, n, buf, sizeof(buf), anslen);
|
||||
rdata = &buf[n];
|
||||
if (n > 0 && (statp->options & RES_NSID) != 0) {
|
||||
n = res_nopt_rdata(statp, n, buf, sizeof(buf), rdata,
|
||||
NS_OPT_NSID, 0, NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (n <= 0) {
|
||||
#ifdef DEBUG
|
||||
@@ -143,6 +150,7 @@ again:
|
||||
RES_SET_H_ERRNO(statp, NO_RECOVERY);
|
||||
return (n);
|
||||
}
|
||||
|
||||
n = res_nsend(statp, buf, n, answer, anslen);
|
||||
if (n < 0) {
|
||||
#ifdef RES_USE_EDNS0
|
||||
|
||||
Reference in New Issue
Block a user