From 90880946803188d7c6b3ca7dea69761eb21241c2 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Tue, 2 Nov 1999 13:07:53 +0000 Subject: [PATCH] Add read support for BIND 8 TTL / counter format to soa. Move bind_ttl to ttl.c and rename dns_ttl_fromtext and dns_counter_fromtext, fix bug in handling of seconds (x 1 not x 60), can also handle raw number. --- lib/dns/include/dns/ttl.h | 20 +++++++++ lib/dns/master.c | 69 +++------------------------- lib/dns/rdata/generic/soa_6.c | 13 ++++-- lib/dns/ttl.c | 84 ++++++++++++++++++++++++++++++++--- 4 files changed, 115 insertions(+), 71 deletions(-) diff --git a/lib/dns/include/dns/ttl.h b/lib/dns/include/dns/ttl.h index 5e1f9beae1..6cf3c41643 100644 --- a/lib/dns/include/dns/ttl.h +++ b/lib/dns/include/dns/ttl.h @@ -49,6 +49,26 @@ dns_ttl_totext(isc_uint32_t src, isc_boolean_t verbose, * DNS_R_NOSPACE */ +dns_result_t +dns_counter_fromtext(isc_textregion_t *source, isc_uint32_t *ttl); +/* + * Converts a counter from either a plain number or a BIND 8 style value. + * + * Returns: + * DNS_R_SUCCESS + * DNS_R_SYNTAX + */ + +dns_result_t +dns_ttl_fromtext(isc_textregion_t *source, isc_uint32_t *ttl); +/* + * Converts a ttl from either a plain number or a BIND 8 style value. + * + * Returns: + * DNS_R_SUCCESS + * DNS_R_SYNTAX + */ + ISC_LANG_ENDDECLS #endif /* DNS_MASTER_H */ diff --git a/lib/dns/master.c b/lib/dns/master.c index 4880d81226..4f02c1e191 100644 --- a/lib/dns/master.c +++ b/lib/dns/master.c @@ -15,7 +15,7 @@ * SOFTWARE. */ - /* $Id: master.c,v 1.27 1999/10/26 18:05:23 ogud Exp $ */ + /* $Id: master.c,v 1.28 1999/11/02 13:07:51 marka Exp $ */ #include @@ -41,6 +41,7 @@ #include #include #include +#include /* * Grow the number of dns_rdatalist_t (RDLSZ) and dns_rdata_t (RDSZ) structures @@ -89,7 +90,6 @@ static dns_rdatalist_t *grow_rdatalist(int, dns_rdatalist_t *, int, static dns_rdata_t *grow_rdata(int, dns_rdata_t *, int, rdatalist_head_t *, rdatalist_head_t *, isc_mem_t *); -static isc_boolean_t bind_ttl(char *s, isc_uint32_t *ttl); static isc_boolean_t on_list(dns_rdatalist_t *this, dns_rdata_t *rdata); #define GETTOKEN(lexer, options, token, eol) \ @@ -513,16 +513,15 @@ load(isc_lex_t *lex, dns_name_t *top, dns_name_t *origin, type = 0; rdclass = 0; - GETTOKEN(lex, ISC_LEXOPT_NUMBER, &token, ISC_FALSE); + GETTOKEN(lex, 0, &token, ISC_FALSE); - if (token.type == isc_tokentype_string && - dns_rdataclass_fromtext(&rdclass, + if (dns_rdataclass_fromtext(&rdclass, &token.value.as_textregion) == DNS_R_SUCCESS) - GETTOKEN(lex, ISC_LEXOPT_NUMBER, &token, ISC_FALSE); + GETTOKEN(lex, 0, &token, ISC_FALSE); - if (token.type == isc_tokentype_number) { - ttl = token.value.as_ulong; + if (dns_ttl_fromtext(&token.value.as_textregion, &ttl) + == DNS_R_SUCCESS) { if (ttl > 0x7fffffffUL) { (callbacks->warn)(callbacks, "dns_master_load: %s:%d TTL %lu > maxtll, setting ttl to 0\n", @@ -533,9 +532,6 @@ load(isc_lex_t *lex, dns_name_t *top, dns_name_t *origin, } ttl_known = ISC_TRUE; GETTOKEN(lex, 0, &token, ISC_FALSE); - } else if (bind_ttl(token.value.as_pointer, &ttl)) { - ttl_known = ISC_TRUE; - GETTOKEN(lex, 0, &token, ISC_FALSE); } else if (!ttl_known && !default_ttl_known) { /* * BIND 4 / 8 'USE_SOA_MINIMUM' could be set here. @@ -1051,57 +1047,6 @@ is_glue(rdatalist_head_t *head, dns_name_t *owner) { return (ISC_FALSE); } -/* - * Convert BIND 8.x ttl representation to a number. - * Returns ISC_TRUE is string contained a valid string. - */ - -static isc_boolean_t -bind_ttl(char *s, isc_uint32_t *ttl) { - isc_uint32_t tmp = 0; - unsigned long n; - char *e; - - do { - n = strtoul(s, &e, 10); - if (s == e) - return (ISC_FALSE); - switch (*e) { - case 'w': - case 'W': - tmp += n * 7 * 24 * 3600; - s = e + 1; - break; - case 'd': - case 'D': - tmp += n * 24 * 3600; - s = e + 1; - break; - case 'h': - case 'H': - tmp += n * 3600; - s = e + 1; - break; - case 'm': - case 'M': - tmp += n * 60; - s = e + 1; - break; - case 's': - case 'S': - tmp += n * 60; - s = e + 1; - break; - default: - return (ISC_FALSE); - } - } while (*s != 0); - if (tmp > 0x7fffffffUL) - tmp = 0; - *ttl = tmp; - return (ISC_TRUE); -} - /* * Returns ISC_TRUE if the 'rdata' is already on 'rdatalist'. */ diff --git a/lib/dns/rdata/generic/soa_6.c b/lib/dns/rdata/generic/soa_6.c index fb5a7d1e7c..97a5bcee2b 100644 --- a/lib/dns/rdata/generic/soa_6.c +++ b/lib/dns/rdata/generic/soa_6.c @@ -15,7 +15,7 @@ * SOFTWARE. */ - /* $Id: soa_6.c,v 1.24 1999/09/15 23:03:32 explorer Exp $ */ + /* $Id: soa_6.c,v 1.25 1999/11/02 13:07:53 marka Exp $ */ #ifndef RDATA_GENERIC_SOA_6_C #define RDATA_GENERIC_SOA_6_C @@ -29,6 +29,7 @@ fromtext_soa(dns_rdataclass_t rdclass, dns_rdatatype_t type, dns_name_t name; isc_buffer_t buffer; int i; + isc_uint32_t n; REQUIRE(type == 6); @@ -46,10 +47,14 @@ fromtext_soa(dns_rdataclass_t rdclass, dns_rdatatype_t type, downcase, target)); } - for (i = 0; i < 5; i++) { - RETERR(gettoken(lexer, &token, isc_tokentype_number, + RETERR(gettoken(lexer, &token, isc_tokentype_number, + ISC_FALSE)); + RETERR(uint32_tobuffer(token.value.as_ulong, target)); + for (i = 0; i < 4; i++) { + RETERR(gettoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); - RETERR(uint32_tobuffer(token.value.as_ulong, target)); + RETERR(dns_counter_fromtext(&token.value.as_textregion, &n)); + RETERR(uint32_tobuffer(n, target)); } return (DNS_R_SUCCESS); diff --git a/lib/dns/ttl.c b/lib/dns/ttl.c index c45de4d9a3..dada84f544 100644 --- a/lib/dns/ttl.c +++ b/lib/dns/ttl.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -36,6 +37,8 @@ } while (0) +static dns_result_t bind_ttl(isc_textregion_t *source, isc_uint32_t *ttl); + /* Helper for dns_ttl_totext(). */ static dns_result_t @@ -46,12 +49,12 @@ ttlfmt(unsigned int t, char *s, isc_boolean_t verbose, size_t len; isc_region_t region; if (verbose) - len = sprintf(tmp, "%s%u %s%s", - space ? " " : "", - t, s, - t == 1 ? "" : "s"); + len = snprintf(tmp, sizeof(tmp), "%s%u %s%s", + space ? " " : "", + t, s, + t == 1 ? "" : "s"); else - len = sprintf(tmp, "%u%c", t, s[0]); + len = snprintf(tmp, sizeof(tmp), "%u%c", t, s[0]); INSIST(len + 1 <= sizeof tmp); isc_buffer_available(target, ®ion); if (len > region.length) @@ -115,3 +118,74 @@ dns_ttl_totext(isc_uint32_t src, isc_boolean_t verbose, return (DNS_R_SUCCESS); } +dns_result_t +dns_counter_fromtext(isc_textregion_t *source, isc_uint32_t *ttl) { + return (bind_ttl(source, ttl)); +} + +dns_result_t +dns_ttl_fromtext(isc_textregion_t *source, isc_uint32_t *ttl) { + return (bind_ttl(source, ttl)); +} + +static dns_result_t +bind_ttl(isc_textregion_t *source, isc_uint32_t *ttl) { + isc_uint32_t tmp = 0; + unsigned long n; + char *e, *s; + char buf[64]; + + /* + * Copy the buffer as it may not be NULL terminated. + * No legal counter / ttl is longer that 63 characters. + */ + if (source->length > sizeof(buf) - 1) + return(DNS_R_SYNTAX); + strncpy(buf, source->base, source->length); + buf[source->length] = '\0'; + s = buf; + + do { + n = strtoul(s, &e, 10); + if (s == e) + return (DNS_R_SYNTAX); + switch (*e) { + case 'w': + case 'W': + tmp += n * 7 * 24 * 3600; + s = e + 1; + break; + case 'd': + case 'D': + tmp += n * 24 * 3600; + s = e + 1; + break; + case 'h': + case 'H': + tmp += n * 3600; + s = e + 1; + break; + case 'm': + case 'M': + tmp += n * 60; + s = e + 1; + break; + case 's': + case 'S': + tmp += n; + s = e + 1; + break; + case '\0': + /* Plain number? */ + if (tmp != 0) + return (DNS_R_SYNTAX); + tmp = n; + s = e; + break; + default: + return (DNS_R_SYNTAX); + } + } while (*s != 0); + *ttl = tmp; + return (DNS_R_SUCCESS); +}