From cad3210bb95057a37aaed20bc8a1542e0534422c Mon Sep 17 00:00:00 2001 From: Andreas Gustafsson Date: Wed, 29 Aug 2001 18:57:28 +0000 Subject: [PATCH] 969. [func] dig now supports the undocumented dig 8 feature of allowing arbitrary labels, not just dotted decimal quads, with the -x option. This can be used to conveniently look up RFC2317 names as in "dig -x 10.0.0.0-127". [RT #827, #1576, #1598] --- CHANGES | 9 ++++ bin/dig/dig.c | 6 ++- bin/dig/dighost.c | 108 +++++++++++++++++++++++++------------- bin/dig/host.c | 6 ++- bin/dig/include/dig/dig.h | 5 +- bin/dig/nslookup.c | 6 ++- 6 files changed, 96 insertions(+), 44 deletions(-) diff --git a/CHANGES b/CHANGES index 9a552705dc..e39119527b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,12 @@ + + 969. [func] dig now supports the undocumented dig 8 feature + of allowing arbitrary labels, not just dotted + decimal quads, with the -x option. This can be + used to conveniently look up RFC2317 names as in + "dig -x 10.0.0.0-127". [RT #827, #1576, #1598] + + calling strtime(). [RT #1671] + 968. [bug] On win32, the isc_time_now() function was unnecessarily calling strtime(). [RT #1671] diff --git a/bin/dig/dig.c b/bin/dig/dig.c index 6633fdda94..605c2ed37d 100644 --- a/bin/dig/dig.c +++ b/bin/dig/dig.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dig.c,v 1.157 2001/08/23 04:39:31 marka Exp $ */ +/* $Id: dig.c,v 1.158 2001/08/29 18:57:06 gson Exp $ */ #include #include @@ -1027,7 +1027,9 @@ dash_option(char *option, char *next, dig_lookup_t **lookup, return (value_from_next); case 'x': *lookup = clone_lookup(default_lookup, ISC_TRUE); - if (get_reverse(textname, value, nibble) == ISC_R_SUCCESS) { + if (get_reverse(textname, value, nibble, ISC_FALSE) + == ISC_R_SUCCESS) + { strncpy((*lookup)->textname, textname, sizeof((*lookup)->textname)); debug("looking up %s", (*lookup)->textname); diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 106dfe2ebc..128de883ce 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dighost.c,v 1.221 2001/08/08 22:54:14 gson Exp $ */ +/* $Id: dighost.c,v 1.222 2001/08/29 18:57:08 gson Exp $ */ /* * Notice to programmers: Do not use this code as an example of how to @@ -203,54 +203,90 @@ hex_dump(isc_buffer_t *b) { printf("\n"); } +/* + * Append 'len' bytes of 'text' at '*p', failing with + * ISC_R_NOSPACE if that would advance p past 'end'. + */ +static isc_result_t +append(const char *text, int len, char **p, char *end) { + if (len > end - *p) + return (ISC_R_NOSPACE); + memcpy(*p, text, len); + *p += len; + return (ISC_R_SUCCESS); +} + +static isc_result_t +reverse_octets(const char *in, char **p, char *end) { + char *dot = strchr(in, '.'); + int len; + if (dot != NULL) { + isc_result_t result; + result = reverse_octets(dot + 1, p, end); + if (result != ISC_R_SUCCESS) + return (result); + result = append(".", 1, p, end); + if (result != ISC_R_SUCCESS) + return (result); + len = dot - in; + } else { + len = strlen(in); + } + return (append(in, len, p, end)); +} isc_result_t -get_reverse(char *reverse, char *value, isc_boolean_t nibble) { - int adrs[4]; - char working[MXNAME]; - int remaining; - int i, n; +get_reverse(char *reverse, char *value, isc_boolean_t nibble, + isc_boolean_t strict) +{ + int r; isc_result_t result; + isc_netaddr_t addr; - result = DNS_R_BADDOTTEDQUAD; - reverse[0] = 0; - - debug("get_reverse(%s)", value); - if (strspn(value, "0123456789.") == strlen(value)) { - n = sscanf(value, "%d.%d.%d.%d", - &adrs[0], &adrs[1], - &adrs[2], &adrs[3]); - if (n == 0) { - return (DNS_R_BADDOTTEDQUAD); - } - reverse[MXNAME - 1] = 0; - for (i = n - 1; i >= 0; i--) { - snprintf(working, sizeof(working), "%d.", - adrs[i]); - remaining = MXNAME - strlen(reverse) - 1; - strncat(reverse, working, remaining); - } - remaining = MXNAME - strlen(reverse) - 1; - strncat(reverse, "in-addr.arpa.", remaining); - result = ISC_R_SUCCESS; - } else if (strspn(value, "0123456789abcdefABCDEF:") - == strlen(value)) { - isc_netaddr_t addr; + addr.family = AF_INET6; + r= inet_pton(AF_INET6, value, &addr.type.in6); + if (r > 0) { + /* This is a valid IPv6 address. */ dns_fixedname_t fname; dns_name_t *name; - - addr.family = AF_INET6; - n = inet_pton(AF_INET6, value, &addr.type.in6); - if (n <= 0) - return (DNS_R_BADDOTTEDQUAD); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); result = dns_byaddr_createptrname(&addr, nibble, name); if (result != ISC_R_SUCCESS) return (result); dns_name_format(name, reverse, MXNAME); + return (ISC_R_SUCCESS); + } else { + /* + * Not a valid IPv6 address. Assume IPv4. + * If 'strict' is not set, construct the + * in-addr.arpa name by blindly reversing + * octets whether or not they look like integers, + * so that this can be used for RFC2317 names + * and such. + */ + char *p = reverse; + char *end = reverse + MXNAME; + if (strict) { + int adrs[4]; + int n; + if (strspn(value, "0123456789.") != strlen(value)) + return (DNS_R_BADDOTTEDQUAD); + n = sscanf(value, "%d.%d.%d.%d", + &adrs[0], &adrs[1], + &adrs[2], &adrs[3]); + if (n == 0) + return (DNS_R_BADDOTTEDQUAD); + } + result = reverse_octets(value, &p, end); + if (result != ISC_R_SUCCESS) + return (result); + /* Append .in-addr.arpa. and a terminating NUL. */ + result = append(".in-addr.arpa.", 15, &p, end); + if (result != ISC_R_SUCCESS) + return (result); + return (ISC_R_SUCCESS); } - return (result); } void diff --git a/bin/dig/host.c b/bin/dig/host.c index a2a1a330bd..bff9b5506f 100644 --- a/bin/dig/host.c +++ b/bin/dig/host.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: host.c,v 1.76 2001/08/27 21:31:29 gson Exp $ */ +/* $Id: host.c,v 1.77 2001/08/29 18:57:09 gson Exp $ */ #include #include @@ -654,7 +654,9 @@ parse_args(isc_boolean_t is_batchfile, int argc, char **argv) { } lookup->pending = ISC_FALSE; - if (get_reverse(store, hostname, lookup->nibble) == ISC_R_SUCCESS) { + if (get_reverse(store, hostname, lookup->nibble, ISC_TRUE) + == ISC_R_SUCCESS) + { strncpy(lookup->textname, store, sizeof(lookup->textname)); lookup->textname[sizeof(lookup->textname)-1] = 0; lookup->rdtype = dns_rdatatype_ptr; diff --git a/bin/dig/include/dig/dig.h b/bin/dig/include/dig/dig.h index fc96ef4b10..6056a6516f 100644 --- a/bin/dig/include/dig/dig.h +++ b/bin/dig/include/dig/dig.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dig.h,v 1.71 2001/08/08 22:54:15 gson Exp $ */ +/* $Id: dig.h,v 1.72 2001/08/29 18:57:12 gson Exp $ */ #ifndef DIG_H #define DIG_H @@ -191,7 +191,8 @@ void get_address(char *host, in_port_t port, isc_sockaddr_t *sockaddr); isc_result_t -get_reverse(char reverse[MXNAME], char *value, isc_boolean_t nibble); +get_reverse(char reverse[MXNAME], char *value, isc_boolean_t nibble, + isc_boolean_t strict); void fatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); diff --git a/bin/dig/nslookup.c b/bin/dig/nslookup.c index 627d2b008e..7fa37d3b6b 100644 --- a/bin/dig/nslookup.c +++ b/bin/dig/nslookup.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: nslookup.c,v 1.90 2001/07/30 01:09:14 marka Exp $ */ +/* $Id: nslookup.c,v 1.91 2001/08/29 18:57:10 gson Exp $ */ #include @@ -624,7 +624,9 @@ addlookup(char *opt) { rdclass = dns_rdataclass_in; } lookup = make_empty_lookup(); - if (get_reverse(store, opt, lookup->nibble) == ISC_R_SUCCESS) { + if (get_reverse(store, opt, lookup->nibble, ISC_TRUE) + == ISC_R_SUCCESS) + { safecpy(lookup->textname, store, sizeof(lookup->textname)); lookup->rdtype = dns_rdatatype_ptr; lookup->rdtypeset = ISC_TRUE;