162ac0c33Sjakob /* 262ac0c33Sjakob * rdata.c -- RDATA conversion functions. 362ac0c33Sjakob * 4dd5b221eSsthen * Copyright (c) 2001-2006, NLnet Labs. All rights reserved. 562ac0c33Sjakob * 662ac0c33Sjakob * See LICENSE for the license. 762ac0c33Sjakob * 862ac0c33Sjakob */ 962ac0c33Sjakob 10d11a62c8Ssthen #include "config.h" 1162ac0c33Sjakob 1262ac0c33Sjakob #include <sys/types.h> 1362ac0c33Sjakob #include <sys/socket.h> 1462ac0c33Sjakob #include <netinet/in.h> 1562ac0c33Sjakob #include <arpa/inet.h> 1662ac0c33Sjakob #include <ctype.h> 1762ac0c33Sjakob #include <netdb.h> 1862ac0c33Sjakob #include <stdlib.h> 1962ac0c33Sjakob #include <string.h> 2062ac0c33Sjakob #ifdef HAVE_STRINGS_H 2162ac0c33Sjakob #include <strings.h> 2262ac0c33Sjakob #endif 2362ac0c33Sjakob 2462ac0c33Sjakob #include "rdata.h" 2562ac0c33Sjakob #include "zonec.h" 2662ac0c33Sjakob 2762ac0c33Sjakob /* Taken from RFC 4398, section 2.1. */ 2862ac0c33Sjakob lookup_table_type dns_certificate_types[] = { 2962ac0c33Sjakob /* 0 Reserved */ 3062ac0c33Sjakob { 1, "PKIX" }, /* X.509 as per PKIX */ 3162ac0c33Sjakob { 2, "SPKI" }, /* SPKI cert */ 3262ac0c33Sjakob { 3, "PGP" }, /* OpenPGP packet */ 3362ac0c33Sjakob { 4, "IPKIX" }, /* The URL of an X.509 data object */ 3462ac0c33Sjakob { 5, "ISPKI" }, /* The URL of an SPKI certificate */ 3562ac0c33Sjakob { 6, "IPGP" }, /* The fingerprint and URL of an OpenPGP packet */ 3662ac0c33Sjakob { 7, "ACPKIX" }, /* Attribute Certificate */ 3762ac0c33Sjakob { 8, "IACPKIX" }, /* The URL of an Attribute Certificate */ 3862ac0c33Sjakob { 253, "URI" }, /* URI private */ 3962ac0c33Sjakob { 254, "OID" }, /* OID private */ 4062ac0c33Sjakob /* 255 Reserved */ 4162ac0c33Sjakob /* 256-65279 Available for IANA assignment */ 4262ac0c33Sjakob /* 65280-65534 Experimental */ 4362ac0c33Sjakob /* 65535 Reserved */ 4462ac0c33Sjakob { 0, NULL } 4562ac0c33Sjakob }; 4662ac0c33Sjakob 4762ac0c33Sjakob /* Taken from RFC 2535, section 7. */ 4862ac0c33Sjakob lookup_table_type dns_algorithms[] = { 4962ac0c33Sjakob { 1, "RSAMD5" }, /* RFC 2537 */ 5062ac0c33Sjakob { 2, "DH" }, /* RFC 2539 */ 5162ac0c33Sjakob { 3, "DSA" }, /* RFC 2536 */ 5262ac0c33Sjakob { 4, "ECC" }, 5362ac0c33Sjakob { 5, "RSASHA1" }, /* RFC 3110 */ 54d11a62c8Ssthen { 6, "DSA-NSEC3-SHA1" }, /* RFC 5155 */ 55d11a62c8Ssthen { 7, "RSASHA1-NSEC3-SHA1" }, /* RFC 5155 */ 56d11a62c8Ssthen { 8, "RSASHA256" }, /* RFC 5702 */ 57d11a62c8Ssthen { 10, "RSASHA512" }, /* RFC 5702 */ 58d11a62c8Ssthen { 12, "ECC-GOST" }, /* RFC 5933 */ 59d11a62c8Ssthen { 13, "ECDSAP256SHA256" }, /* RFC 6605 */ 60d11a62c8Ssthen { 14, "ECDSAP384SHA384" }, /* RFC 6605 */ 6162ac0c33Sjakob { 252, "INDIRECT" }, 6262ac0c33Sjakob { 253, "PRIVATEDNS" }, 6362ac0c33Sjakob { 254, "PRIVATEOID" }, 6462ac0c33Sjakob { 0, NULL } 6562ac0c33Sjakob }; 6662ac0c33Sjakob 6762ac0c33Sjakob typedef int (*rdata_to_string_type)(buffer_type *output, 6862ac0c33Sjakob rdata_atom_type rdata, 6962ac0c33Sjakob rr_type *rr); 7062ac0c33Sjakob 7162ac0c33Sjakob static int 7262ac0c33Sjakob rdata_dname_to_string(buffer_type *output, rdata_atom_type rdata, 7362ac0c33Sjakob rr_type* ATTR_UNUSED(rr)) 7462ac0c33Sjakob { 7562ac0c33Sjakob buffer_printf(output, 7662ac0c33Sjakob "%s", 7762ac0c33Sjakob dname_to_string(domain_dname(rdata_atom_domain(rdata)), 7862ac0c33Sjakob NULL)); 7962ac0c33Sjakob return 1; 8062ac0c33Sjakob } 8162ac0c33Sjakob 8262ac0c33Sjakob static int 8362ac0c33Sjakob rdata_dns_name_to_string(buffer_type *output, rdata_atom_type rdata, 8462ac0c33Sjakob rr_type* ATTR_UNUSED(rr)) 8562ac0c33Sjakob { 8662ac0c33Sjakob const uint8_t *data = rdata_atom_data(rdata); 8762ac0c33Sjakob size_t offset = 0; 8862ac0c33Sjakob uint8_t length = data[offset]; 8962ac0c33Sjakob size_t i; 9062ac0c33Sjakob 9162ac0c33Sjakob while (length > 0) 9262ac0c33Sjakob { 9362ac0c33Sjakob if (offset) /* concat label */ 9462ac0c33Sjakob buffer_printf(output, "."); 9562ac0c33Sjakob 9662ac0c33Sjakob for (i = 1; i <= length; ++i) { 97d65f3523Sjakob uint8_t ch = data[i+offset]; 98d65f3523Sjakob 99d65f3523Sjakob if (ch=='.' || ch==';' || ch=='(' || ch==')' || ch=='\\') { 100d65f3523Sjakob buffer_printf(output, "\\%c", (char) ch); 101*a302926fSbrad } else if (!isgraph((int)(unsigned char) ch)) { 102d65f3523Sjakob buffer_printf(output, "\\%03u", (unsigned int) ch); 103*a302926fSbrad } else if (isprint((int)(unsigned char) ch)) { 104d65f3523Sjakob buffer_printf(output, "%c", (char) ch); 105d65f3523Sjakob } else { 106d65f3523Sjakob buffer_printf(output, "\\%03u", (unsigned int) ch); 107d65f3523Sjakob } 10862ac0c33Sjakob } 10962ac0c33Sjakob /* next label */ 11062ac0c33Sjakob offset = offset+length+1; 11162ac0c33Sjakob length = data[offset]; 11262ac0c33Sjakob } 11362ac0c33Sjakob 11462ac0c33Sjakob /* root label */ 11562ac0c33Sjakob buffer_printf(output, "."); 11662ac0c33Sjakob return 1; 11762ac0c33Sjakob } 11862ac0c33Sjakob 11962ac0c33Sjakob static int 12062ac0c33Sjakob rdata_text_to_string(buffer_type *output, rdata_atom_type rdata, 12162ac0c33Sjakob rr_type* ATTR_UNUSED(rr)) 12262ac0c33Sjakob { 12362ac0c33Sjakob const uint8_t *data = rdata_atom_data(rdata); 12462ac0c33Sjakob uint8_t length = data[0]; 12562ac0c33Sjakob size_t i; 12662ac0c33Sjakob 12762ac0c33Sjakob buffer_printf(output, "\""); 12862ac0c33Sjakob for (i = 1; i <= length; ++i) { 12962ac0c33Sjakob char ch = (char) data[i]; 130*a302926fSbrad if (isprint((int)(unsigned char)ch)) { 13162ac0c33Sjakob if (ch == '"' || ch == '\\') { 13262ac0c33Sjakob buffer_printf(output, "\\"); 13362ac0c33Sjakob } 13462ac0c33Sjakob buffer_printf(output, "%c", ch); 13562ac0c33Sjakob } else { 1365bcb494bSjakob buffer_printf(output, "\\%03u", (unsigned) data[i]); 13762ac0c33Sjakob } 13862ac0c33Sjakob } 13962ac0c33Sjakob buffer_printf(output, "\""); 14062ac0c33Sjakob return 1; 14162ac0c33Sjakob } 14262ac0c33Sjakob 14362ac0c33Sjakob static int 144f72b2965Sjakob rdata_texts_to_string(buffer_type *output, rdata_atom_type rdata, 145f72b2965Sjakob rr_type* ATTR_UNUSED(rr)) 146f72b2965Sjakob { 147f72b2965Sjakob uint16_t pos = 0; 148f72b2965Sjakob const uint8_t *data = rdata_atom_data(rdata); 149f72b2965Sjakob uint16_t length = rdata_atom_size(rdata); 150f72b2965Sjakob size_t i; 151f72b2965Sjakob 152f72b2965Sjakob while (pos < length && pos + data[pos] < length) { 153f72b2965Sjakob buffer_printf(output, "\""); 154f72b2965Sjakob for (i = 1; i <= data[pos]; ++i) { 155f72b2965Sjakob char ch = (char) data[pos + i]; 156*a302926fSbrad if (isprint((int)(unsigned char)ch)) { 157f72b2965Sjakob if (ch == '"' || ch == '\\') { 158f72b2965Sjakob buffer_printf(output, "\\"); 159f72b2965Sjakob } 160f72b2965Sjakob buffer_printf(output, "%c", ch); 161f72b2965Sjakob } else { 1625bcb494bSjakob buffer_printf(output, "\\%03u", (unsigned) data[pos+i]); 163f72b2965Sjakob } 164f72b2965Sjakob } 165f72b2965Sjakob pos += data[pos]+1; 166f72b2965Sjakob buffer_printf(output, pos < length?"\" ":"\""); 167f72b2965Sjakob } 168f72b2965Sjakob return 1; 169f72b2965Sjakob } 170f72b2965Sjakob 171f72b2965Sjakob static int 172*a302926fSbrad rdata_long_text_to_string(buffer_type *output, rdata_atom_type rdata, 173*a302926fSbrad rr_type* ATTR_UNUSED(rr)) 174*a302926fSbrad { 175*a302926fSbrad const uint8_t *data = rdata_atom_data(rdata); 176*a302926fSbrad uint16_t length = rdata_atom_size(rdata); 177*a302926fSbrad size_t i; 178*a302926fSbrad 179*a302926fSbrad buffer_printf(output, "\""); 180*a302926fSbrad for (i = 0; i < length; ++i) { 181*a302926fSbrad char ch = (char) data[i]; 182*a302926fSbrad if (isprint((int)(unsigned char)ch)) { 183*a302926fSbrad if (ch == '"' || ch == '\\') { 184*a302926fSbrad buffer_printf(output, "\\"); 185*a302926fSbrad } 186*a302926fSbrad buffer_printf(output, "%c", ch); 187*a302926fSbrad } else { 188*a302926fSbrad buffer_printf(output, "\\%03u", (unsigned) data[i]); 189*a302926fSbrad } 190*a302926fSbrad } 191*a302926fSbrad buffer_printf(output, "\""); 192*a302926fSbrad return 1; 193*a302926fSbrad } 194*a302926fSbrad 195*a302926fSbrad static int 196*a302926fSbrad rdata_tag_to_string(buffer_type *output, rdata_atom_type rdata, 197*a302926fSbrad rr_type* ATTR_UNUSED(rr)) 198*a302926fSbrad { 199*a302926fSbrad const uint8_t *data = rdata_atom_data(rdata); 200*a302926fSbrad uint8_t length = data[0]; 201*a302926fSbrad size_t i; 202*a302926fSbrad for (i = 1; i <= length; ++i) { 203*a302926fSbrad char ch = (char) data[i]; 204*a302926fSbrad if (isdigit((int)ch) || islower((int)ch)) 205*a302926fSbrad buffer_printf(output, "%c", ch); 206*a302926fSbrad else return 0; 207*a302926fSbrad } 208*a302926fSbrad return 1; 209*a302926fSbrad } 210*a302926fSbrad 211*a302926fSbrad static int 21262ac0c33Sjakob rdata_byte_to_string(buffer_type *output, rdata_atom_type rdata, 21362ac0c33Sjakob rr_type* ATTR_UNUSED(rr)) 21462ac0c33Sjakob { 21562ac0c33Sjakob uint8_t data = *rdata_atom_data(rdata); 21662ac0c33Sjakob buffer_printf(output, "%lu", (unsigned long) data); 21762ac0c33Sjakob return 1; 21862ac0c33Sjakob } 21962ac0c33Sjakob 22062ac0c33Sjakob static int 22162ac0c33Sjakob rdata_short_to_string(buffer_type *output, rdata_atom_type rdata, 22262ac0c33Sjakob rr_type* ATTR_UNUSED(rr)) 22362ac0c33Sjakob { 22462ac0c33Sjakob uint16_t data = read_uint16(rdata_atom_data(rdata)); 22562ac0c33Sjakob buffer_printf(output, "%lu", (unsigned long) data); 22662ac0c33Sjakob return 1; 22762ac0c33Sjakob } 22862ac0c33Sjakob 22962ac0c33Sjakob static int 23062ac0c33Sjakob rdata_long_to_string(buffer_type *output, rdata_atom_type rdata, 23162ac0c33Sjakob rr_type* ATTR_UNUSED(rr)) 23262ac0c33Sjakob { 23362ac0c33Sjakob uint32_t data = read_uint32(rdata_atom_data(rdata)); 23462ac0c33Sjakob buffer_printf(output, "%lu", (unsigned long) data); 23562ac0c33Sjakob return 1; 23662ac0c33Sjakob } 23762ac0c33Sjakob 23862ac0c33Sjakob static int 23962ac0c33Sjakob rdata_a_to_string(buffer_type *output, rdata_atom_type rdata, 24062ac0c33Sjakob rr_type* ATTR_UNUSED(rr)) 24162ac0c33Sjakob { 24262ac0c33Sjakob int result = 0; 24362ac0c33Sjakob char str[200]; 24462ac0c33Sjakob if (inet_ntop(AF_INET, rdata_atom_data(rdata), str, sizeof(str))) { 24562ac0c33Sjakob buffer_printf(output, "%s", str); 24662ac0c33Sjakob result = 1; 24762ac0c33Sjakob } 24862ac0c33Sjakob return result; 24962ac0c33Sjakob } 25062ac0c33Sjakob 25162ac0c33Sjakob static int 25262ac0c33Sjakob rdata_aaaa_to_string(buffer_type *output, rdata_atom_type rdata, 25362ac0c33Sjakob rr_type* ATTR_UNUSED(rr)) 25462ac0c33Sjakob { 25562ac0c33Sjakob int result = 0; 25662ac0c33Sjakob char str[200]; 25762ac0c33Sjakob if (inet_ntop(AF_INET6, rdata_atom_data(rdata), str, sizeof(str))) { 25862ac0c33Sjakob buffer_printf(output, "%s", str); 25962ac0c33Sjakob result = 1; 26062ac0c33Sjakob } 26162ac0c33Sjakob return result; 26262ac0c33Sjakob } 26362ac0c33Sjakob 26462ac0c33Sjakob static int 26575343be4Ssthen rdata_ilnp64_to_string(buffer_type *output, rdata_atom_type rdata, 26675343be4Ssthen rr_type* ATTR_UNUSED(rr)) 26775343be4Ssthen { 26875343be4Ssthen uint8_t* data = rdata_atom_data(rdata); 26975343be4Ssthen uint16_t a1 = read_uint16(data); 27075343be4Ssthen uint16_t a2 = read_uint16(data+2); 27175343be4Ssthen uint16_t a3 = read_uint16(data+4); 27275343be4Ssthen uint16_t a4 = read_uint16(data+6); 27375343be4Ssthen 27475343be4Ssthen buffer_printf(output, "%.4x:%.4x:%.4x:%.4x", a1, a2, a3, a4); 27575343be4Ssthen return 1; 27675343be4Ssthen } 27775343be4Ssthen 2789c620270Ssthen static int 2799c620270Ssthen rdata_eui48_to_string(buffer_type *output, rdata_atom_type rdata, 2809c620270Ssthen rr_type* ATTR_UNUSED(rr)) 2819c620270Ssthen { 2829c620270Ssthen uint8_t* data = rdata_atom_data(rdata); 2839c620270Ssthen uint8_t a1 = data[0]; 2849c620270Ssthen uint8_t a2 = data[1]; 2859c620270Ssthen uint8_t a3 = data[2]; 2869c620270Ssthen uint8_t a4 = data[3]; 2879c620270Ssthen uint8_t a5 = data[4]; 2889c620270Ssthen uint8_t a6 = data[5]; 2899c620270Ssthen 2909c620270Ssthen buffer_printf(output, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", 2919c620270Ssthen a1, a2, a3, a4, a5, a6); 2929c620270Ssthen return 1; 2939c620270Ssthen } 2949c620270Ssthen 2959c620270Ssthen static int 2969c620270Ssthen rdata_eui64_to_string(buffer_type *output, rdata_atom_type rdata, 2979c620270Ssthen rr_type* ATTR_UNUSED(rr)) 2989c620270Ssthen { 2999c620270Ssthen uint8_t* data = rdata_atom_data(rdata); 3009c620270Ssthen uint8_t a1 = data[0]; 3019c620270Ssthen uint8_t a2 = data[1]; 3029c620270Ssthen uint8_t a3 = data[2]; 3039c620270Ssthen uint8_t a4 = data[3]; 3049c620270Ssthen uint8_t a5 = data[4]; 3059c620270Ssthen uint8_t a6 = data[5]; 3069c620270Ssthen uint8_t a7 = data[6]; 3079c620270Ssthen uint8_t a8 = data[7]; 3089c620270Ssthen 3099c620270Ssthen buffer_printf(output, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", 3109c620270Ssthen a1, a2, a3, a4, a5, a6, a7, a8); 3119c620270Ssthen return 1; 3129c620270Ssthen } 3139c620270Ssthen 31475343be4Ssthen static int 31562ac0c33Sjakob rdata_rrtype_to_string(buffer_type *output, rdata_atom_type rdata, 31662ac0c33Sjakob rr_type* ATTR_UNUSED(rr)) 31762ac0c33Sjakob { 31862ac0c33Sjakob uint16_t type = read_uint16(rdata_atom_data(rdata)); 31962ac0c33Sjakob buffer_printf(output, "%s", rrtype_to_string(type)); 32062ac0c33Sjakob return 1; 32162ac0c33Sjakob } 32262ac0c33Sjakob 32362ac0c33Sjakob static int 32462ac0c33Sjakob rdata_algorithm_to_string(buffer_type *output, rdata_atom_type rdata, 32562ac0c33Sjakob rr_type* ATTR_UNUSED(rr)) 32662ac0c33Sjakob { 32762ac0c33Sjakob uint8_t id = *rdata_atom_data(rdata); 32862ac0c33Sjakob buffer_printf(output, "%u", (unsigned) id); 32962ac0c33Sjakob return 1; 33062ac0c33Sjakob } 33162ac0c33Sjakob 33262ac0c33Sjakob static int 33362ac0c33Sjakob rdata_certificate_type_to_string(buffer_type *output, rdata_atom_type rdata, 33462ac0c33Sjakob rr_type* ATTR_UNUSED(rr)) 33562ac0c33Sjakob { 33662ac0c33Sjakob uint16_t id = read_uint16(rdata_atom_data(rdata)); 33762ac0c33Sjakob lookup_table_type *type 33862ac0c33Sjakob = lookup_by_id(dns_certificate_types, id); 33962ac0c33Sjakob if (type) { 34062ac0c33Sjakob buffer_printf(output, "%s", type->name); 34162ac0c33Sjakob } else { 34262ac0c33Sjakob buffer_printf(output, "%u", (unsigned) id); 34362ac0c33Sjakob } 34462ac0c33Sjakob return 1; 34562ac0c33Sjakob } 34662ac0c33Sjakob 34762ac0c33Sjakob static int 34862ac0c33Sjakob rdata_period_to_string(buffer_type *output, rdata_atom_type rdata, 34962ac0c33Sjakob rr_type* ATTR_UNUSED(rr)) 35062ac0c33Sjakob { 35162ac0c33Sjakob uint32_t period = read_uint32(rdata_atom_data(rdata)); 35262ac0c33Sjakob buffer_printf(output, "%lu", (unsigned long) period); 35362ac0c33Sjakob return 1; 35462ac0c33Sjakob } 35562ac0c33Sjakob 35662ac0c33Sjakob static int 35762ac0c33Sjakob rdata_time_to_string(buffer_type *output, rdata_atom_type rdata, 35862ac0c33Sjakob rr_type* ATTR_UNUSED(rr)) 35962ac0c33Sjakob { 36062ac0c33Sjakob int result = 0; 36162ac0c33Sjakob time_t time = (time_t) read_uint32(rdata_atom_data(rdata)); 36262ac0c33Sjakob struct tm *tm = gmtime(&time); 36362ac0c33Sjakob char buf[15]; 36462ac0c33Sjakob if (strftime(buf, sizeof(buf), "%Y%m%d%H%M%S", tm)) { 36562ac0c33Sjakob buffer_printf(output, "%s", buf); 36662ac0c33Sjakob result = 1; 36762ac0c33Sjakob } 36862ac0c33Sjakob return result; 36962ac0c33Sjakob } 37062ac0c33Sjakob 37162ac0c33Sjakob static int 37262ac0c33Sjakob rdata_base32_to_string(buffer_type *output, rdata_atom_type rdata, 37362ac0c33Sjakob rr_type* ATTR_UNUSED(rr)) 37462ac0c33Sjakob { 37562ac0c33Sjakob int length; 37662ac0c33Sjakob size_t size = rdata_atom_size(rdata); 37762ac0c33Sjakob if(size == 0) { 37862ac0c33Sjakob buffer_write(output, "-", 1); 37962ac0c33Sjakob return 1; 38062ac0c33Sjakob } 38162ac0c33Sjakob size -= 1; /* remove length byte from count */ 38262ac0c33Sjakob buffer_reserve(output, size * 2 + 1); 38362ac0c33Sjakob length = b32_ntop(rdata_atom_data(rdata)+1, size, 38462ac0c33Sjakob (char *) buffer_current(output), size * 2); 38562ac0c33Sjakob if (length > 0) { 38662ac0c33Sjakob buffer_skip(output, length); 38762ac0c33Sjakob } 38862ac0c33Sjakob return length != -1; 38962ac0c33Sjakob } 39062ac0c33Sjakob 39162ac0c33Sjakob static int 39262ac0c33Sjakob rdata_base64_to_string(buffer_type *output, rdata_atom_type rdata, 39362ac0c33Sjakob rr_type* ATTR_UNUSED(rr)) 39462ac0c33Sjakob { 39562ac0c33Sjakob int length; 39662ac0c33Sjakob size_t size = rdata_atom_size(rdata); 3975bcb494bSjakob if(size == 0) 3985bcb494bSjakob return 1; 39962ac0c33Sjakob buffer_reserve(output, size * 2 + 1); 40062ac0c33Sjakob length = b64_ntop(rdata_atom_data(rdata), size, 40162ac0c33Sjakob (char *) buffer_current(output), size * 2); 40262ac0c33Sjakob if (length > 0) { 40362ac0c33Sjakob buffer_skip(output, length); 40462ac0c33Sjakob } 40562ac0c33Sjakob return length != -1; 40662ac0c33Sjakob } 40762ac0c33Sjakob 40862ac0c33Sjakob static void 40962ac0c33Sjakob hex_to_string(buffer_type *output, const uint8_t *data, size_t size) 41062ac0c33Sjakob { 41162ac0c33Sjakob static const char hexdigits[] = { 41262ac0c33Sjakob '0', '1', '2', '3', '4', '5', '6', '7', 41362ac0c33Sjakob '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' 41462ac0c33Sjakob }; 41562ac0c33Sjakob size_t i; 41662ac0c33Sjakob 41762ac0c33Sjakob buffer_reserve(output, size * 2); 41862ac0c33Sjakob for (i = 0; i < size; ++i) { 41962ac0c33Sjakob uint8_t octet = *data++; 42062ac0c33Sjakob buffer_write_u8(output, hexdigits[octet >> 4]); 42162ac0c33Sjakob buffer_write_u8(output, hexdigits[octet & 0x0f]); 42262ac0c33Sjakob } 42362ac0c33Sjakob } 42462ac0c33Sjakob 42562ac0c33Sjakob static int 42662ac0c33Sjakob rdata_hex_to_string(buffer_type *output, rdata_atom_type rdata, 42762ac0c33Sjakob rr_type* ATTR_UNUSED(rr)) 42862ac0c33Sjakob { 42962ac0c33Sjakob hex_to_string(output, rdata_atom_data(rdata), rdata_atom_size(rdata)); 43062ac0c33Sjakob return 1; 43162ac0c33Sjakob } 43262ac0c33Sjakob 43362ac0c33Sjakob static int 43462ac0c33Sjakob rdata_hexlen_to_string(buffer_type *output, rdata_atom_type rdata, 43562ac0c33Sjakob rr_type* ATTR_UNUSED(rr)) 43662ac0c33Sjakob { 43762ac0c33Sjakob if(rdata_atom_size(rdata) <= 1) { 43862ac0c33Sjakob /* NSEC3 salt hex can be empty */ 43962ac0c33Sjakob buffer_printf(output, "-"); 44062ac0c33Sjakob return 1; 44162ac0c33Sjakob } 44262ac0c33Sjakob hex_to_string(output, rdata_atom_data(rdata)+1, rdata_atom_size(rdata)-1); 44362ac0c33Sjakob return 1; 44462ac0c33Sjakob } 44562ac0c33Sjakob 44662ac0c33Sjakob static int 44762ac0c33Sjakob rdata_nsap_to_string(buffer_type *output, rdata_atom_type rdata, 44862ac0c33Sjakob rr_type* ATTR_UNUSED(rr)) 44962ac0c33Sjakob { 45062ac0c33Sjakob buffer_printf(output, "0x"); 45162ac0c33Sjakob hex_to_string(output, rdata_atom_data(rdata), rdata_atom_size(rdata)); 45262ac0c33Sjakob return 1; 45362ac0c33Sjakob } 45462ac0c33Sjakob 45562ac0c33Sjakob static int 45662ac0c33Sjakob rdata_apl_to_string(buffer_type *output, rdata_atom_type rdata, 45762ac0c33Sjakob rr_type* ATTR_UNUSED(rr)) 45862ac0c33Sjakob { 45962ac0c33Sjakob int result = 0; 46062ac0c33Sjakob buffer_type packet; 46162ac0c33Sjakob 46262ac0c33Sjakob buffer_create_from( 46362ac0c33Sjakob &packet, rdata_atom_data(rdata), rdata_atom_size(rdata)); 46462ac0c33Sjakob 46562ac0c33Sjakob if (buffer_available(&packet, 4)) { 46662ac0c33Sjakob uint16_t address_family = buffer_read_u16(&packet); 46762ac0c33Sjakob uint8_t prefix = buffer_read_u8(&packet); 46862ac0c33Sjakob uint8_t length = buffer_read_u8(&packet); 46962ac0c33Sjakob int negated = length & APL_NEGATION_MASK; 47062ac0c33Sjakob int af = -1; 47162ac0c33Sjakob 47262ac0c33Sjakob length &= APL_LENGTH_MASK; 47362ac0c33Sjakob switch (address_family) { 47462ac0c33Sjakob case 1: af = AF_INET; break; 47562ac0c33Sjakob case 2: af = AF_INET6; break; 47662ac0c33Sjakob } 47762ac0c33Sjakob if (af != -1 && buffer_available(&packet, length)) { 47862ac0c33Sjakob char text_address[1000]; 47962ac0c33Sjakob uint8_t address[128]; 48062ac0c33Sjakob memset(address, 0, sizeof(address)); 48162ac0c33Sjakob buffer_read(&packet, address, length); 48262ac0c33Sjakob if (inet_ntop(af, address, text_address, sizeof(text_address))) { 48362ac0c33Sjakob buffer_printf(output, "%s%d:%s/%d", 48462ac0c33Sjakob negated ? "!" : "", 48562ac0c33Sjakob (int) address_family, 48662ac0c33Sjakob text_address, 48762ac0c33Sjakob (int) prefix); 48862ac0c33Sjakob result = 1; 48962ac0c33Sjakob } 49062ac0c33Sjakob } 49162ac0c33Sjakob } 49262ac0c33Sjakob return result; 49362ac0c33Sjakob } 49462ac0c33Sjakob 49562ac0c33Sjakob static int 49662ac0c33Sjakob rdata_services_to_string(buffer_type *output, rdata_atom_type rdata, 49762ac0c33Sjakob rr_type* ATTR_UNUSED(rr)) 49862ac0c33Sjakob { 49962ac0c33Sjakob int result = 0; 50062ac0c33Sjakob buffer_type packet; 50162ac0c33Sjakob 50262ac0c33Sjakob buffer_create_from( 50362ac0c33Sjakob &packet, rdata_atom_data(rdata), rdata_atom_size(rdata)); 50462ac0c33Sjakob 50562ac0c33Sjakob if (buffer_available(&packet, 1)) { 50662ac0c33Sjakob uint8_t protocol_number = buffer_read_u8(&packet); 50762ac0c33Sjakob ssize_t bitmap_size = buffer_remaining(&packet); 50862ac0c33Sjakob uint8_t *bitmap = buffer_current(&packet); 50962ac0c33Sjakob struct protoent *proto = getprotobynumber(protocol_number); 51062ac0c33Sjakob 51162ac0c33Sjakob if (proto) { 51262ac0c33Sjakob int i; 51362ac0c33Sjakob 51462ac0c33Sjakob buffer_printf(output, "%s", proto->p_name); 51562ac0c33Sjakob 51662ac0c33Sjakob for (i = 0; i < bitmap_size * 8; ++i) { 51762ac0c33Sjakob if (get_bit(bitmap, i)) { 51862ac0c33Sjakob struct servent *service = getservbyport((int)htons(i), proto->p_name); 51962ac0c33Sjakob if (service) { 52062ac0c33Sjakob buffer_printf(output, " %s", service->s_name); 52162ac0c33Sjakob } else { 52262ac0c33Sjakob buffer_printf(output, " %d", i); 52362ac0c33Sjakob } 52462ac0c33Sjakob } 52562ac0c33Sjakob } 52662ac0c33Sjakob buffer_skip(&packet, bitmap_size); 52762ac0c33Sjakob result = 1; 52862ac0c33Sjakob } 52962ac0c33Sjakob } 53062ac0c33Sjakob return result; 53162ac0c33Sjakob } 53262ac0c33Sjakob 53362ac0c33Sjakob static int 53462ac0c33Sjakob rdata_ipsecgateway_to_string(buffer_type *output, rdata_atom_type rdata, rr_type* rr) 53562ac0c33Sjakob { 53662ac0c33Sjakob int gateway_type = rdata_atom_data(rr->rdatas[1])[0]; 53762ac0c33Sjakob switch(gateway_type) { 53862ac0c33Sjakob case IPSECKEY_NOGATEWAY: 53962ac0c33Sjakob buffer_printf(output, "."); 54062ac0c33Sjakob break; 54162ac0c33Sjakob case IPSECKEY_IP4: 54262ac0c33Sjakob rdata_a_to_string(output, rdata, rr); 54362ac0c33Sjakob break; 54462ac0c33Sjakob case IPSECKEY_IP6: 54562ac0c33Sjakob rdata_aaaa_to_string(output, rdata, rr); 54662ac0c33Sjakob break; 54762ac0c33Sjakob case IPSECKEY_DNAME: 5485bcb494bSjakob { 5495bcb494bSjakob region_type* temp = region_create(xalloc, free); 5505bcb494bSjakob const dname_type* d = dname_make(temp, 5515bcb494bSjakob rdata_atom_data(rdata), 0); 5525bcb494bSjakob if(!d) { 5535bcb494bSjakob region_destroy(temp); 5545bcb494bSjakob return 0; 5555bcb494bSjakob } 5565bcb494bSjakob buffer_printf(output, "%s", dname_to_string(d, NULL)); 5575bcb494bSjakob region_destroy(temp); 5585bcb494bSjakob } 55962ac0c33Sjakob break; 56062ac0c33Sjakob default: 56162ac0c33Sjakob return 0; 56262ac0c33Sjakob } 56362ac0c33Sjakob return 1; 56462ac0c33Sjakob } 56562ac0c33Sjakob 56662ac0c33Sjakob static int 56762ac0c33Sjakob rdata_nxt_to_string(buffer_type *output, rdata_atom_type rdata, 56862ac0c33Sjakob rr_type* ATTR_UNUSED(rr)) 56962ac0c33Sjakob { 57062ac0c33Sjakob size_t i; 57162ac0c33Sjakob uint8_t *bitmap = rdata_atom_data(rdata); 57262ac0c33Sjakob size_t bitmap_size = rdata_atom_size(rdata); 57362ac0c33Sjakob 57462ac0c33Sjakob for (i = 0; i < bitmap_size * 8; ++i) { 57562ac0c33Sjakob if (get_bit(bitmap, i)) { 57662ac0c33Sjakob buffer_printf(output, "%s ", rrtype_to_string(i)); 57762ac0c33Sjakob } 57862ac0c33Sjakob } 57962ac0c33Sjakob 58062ac0c33Sjakob buffer_skip(output, -1); 58162ac0c33Sjakob 58262ac0c33Sjakob return 1; 58362ac0c33Sjakob } 58462ac0c33Sjakob 58562ac0c33Sjakob static int 58662ac0c33Sjakob rdata_nsec_to_string(buffer_type *output, rdata_atom_type rdata, 58762ac0c33Sjakob rr_type* ATTR_UNUSED(rr)) 58862ac0c33Sjakob { 58962ac0c33Sjakob size_t saved_position = buffer_position(output); 59062ac0c33Sjakob buffer_type packet; 59162ac0c33Sjakob int insert_space = 0; 59262ac0c33Sjakob 59362ac0c33Sjakob buffer_create_from( 59462ac0c33Sjakob &packet, rdata_atom_data(rdata), rdata_atom_size(rdata)); 59562ac0c33Sjakob 59662ac0c33Sjakob while (buffer_available(&packet, 2)) { 59762ac0c33Sjakob uint8_t window = buffer_read_u8(&packet); 59862ac0c33Sjakob uint8_t bitmap_size = buffer_read_u8(&packet); 59962ac0c33Sjakob uint8_t *bitmap = buffer_current(&packet); 60062ac0c33Sjakob int i; 60162ac0c33Sjakob 60262ac0c33Sjakob if (!buffer_available(&packet, bitmap_size)) { 60362ac0c33Sjakob buffer_set_position(output, saved_position); 60462ac0c33Sjakob return 0; 60562ac0c33Sjakob } 60662ac0c33Sjakob 60762ac0c33Sjakob for (i = 0; i < bitmap_size * 8; ++i) { 60862ac0c33Sjakob if (get_bit(bitmap, i)) { 60962ac0c33Sjakob buffer_printf(output, 61062ac0c33Sjakob "%s%s", 61162ac0c33Sjakob insert_space ? " " : "", 61262ac0c33Sjakob rrtype_to_string( 61362ac0c33Sjakob window * 256 + i)); 61462ac0c33Sjakob insert_space = 1; 61562ac0c33Sjakob } 61662ac0c33Sjakob } 61762ac0c33Sjakob buffer_skip(&packet, bitmap_size); 61862ac0c33Sjakob } 61962ac0c33Sjakob 62062ac0c33Sjakob return 1; 62162ac0c33Sjakob } 62262ac0c33Sjakob 62362ac0c33Sjakob static int 62462ac0c33Sjakob rdata_loc_to_string(buffer_type *ATTR_UNUSED(output), 62562ac0c33Sjakob rdata_atom_type ATTR_UNUSED(rdata), 62662ac0c33Sjakob rr_type* ATTR_UNUSED(rr)) 62762ac0c33Sjakob { 62862ac0c33Sjakob /* 62962ac0c33Sjakob * Returning 0 forces the record to be printed in unknown 63062ac0c33Sjakob * format. 63162ac0c33Sjakob */ 63262ac0c33Sjakob return 0; 63362ac0c33Sjakob } 63462ac0c33Sjakob 63562ac0c33Sjakob static int 63662ac0c33Sjakob rdata_unknown_to_string(buffer_type *output, rdata_atom_type rdata, 63762ac0c33Sjakob rr_type* ATTR_UNUSED(rr)) 63862ac0c33Sjakob { 63962ac0c33Sjakob uint16_t size = rdata_atom_size(rdata); 64062ac0c33Sjakob buffer_printf(output, "\\# %lu ", (unsigned long) size); 64162ac0c33Sjakob hex_to_string(output, rdata_atom_data(rdata), size); 64262ac0c33Sjakob return 1; 64362ac0c33Sjakob } 64462ac0c33Sjakob 64562ac0c33Sjakob static rdata_to_string_type rdata_to_string_table[RDATA_ZF_UNKNOWN + 1] = { 64662ac0c33Sjakob rdata_dname_to_string, 64762ac0c33Sjakob rdata_dns_name_to_string, 64862ac0c33Sjakob rdata_text_to_string, 649f72b2965Sjakob rdata_texts_to_string, 65062ac0c33Sjakob rdata_byte_to_string, 65162ac0c33Sjakob rdata_short_to_string, 65262ac0c33Sjakob rdata_long_to_string, 65362ac0c33Sjakob rdata_a_to_string, 65462ac0c33Sjakob rdata_aaaa_to_string, 65562ac0c33Sjakob rdata_rrtype_to_string, 65662ac0c33Sjakob rdata_algorithm_to_string, 65762ac0c33Sjakob rdata_certificate_type_to_string, 65862ac0c33Sjakob rdata_period_to_string, 65962ac0c33Sjakob rdata_time_to_string, 66062ac0c33Sjakob rdata_base64_to_string, 66162ac0c33Sjakob rdata_base32_to_string, 66262ac0c33Sjakob rdata_hex_to_string, 66362ac0c33Sjakob rdata_hexlen_to_string, 66462ac0c33Sjakob rdata_nsap_to_string, 66562ac0c33Sjakob rdata_apl_to_string, 66662ac0c33Sjakob rdata_ipsecgateway_to_string, 66762ac0c33Sjakob rdata_services_to_string, 66862ac0c33Sjakob rdata_nxt_to_string, 66962ac0c33Sjakob rdata_nsec_to_string, 67062ac0c33Sjakob rdata_loc_to_string, 67175343be4Ssthen rdata_ilnp64_to_string, 6729c620270Ssthen rdata_eui48_to_string, 6739c620270Ssthen rdata_eui64_to_string, 674*a302926fSbrad rdata_long_text_to_string, 675*a302926fSbrad rdata_tag_to_string, 67662ac0c33Sjakob rdata_unknown_to_string 67762ac0c33Sjakob }; 67862ac0c33Sjakob 67962ac0c33Sjakob int 68062ac0c33Sjakob rdata_atom_to_string(buffer_type *output, rdata_zoneformat_type type, 68162ac0c33Sjakob rdata_atom_type rdata, rr_type* record) 68262ac0c33Sjakob { 68362ac0c33Sjakob return rdata_to_string_table[type](output, rdata, record); 68462ac0c33Sjakob } 68562ac0c33Sjakob 68662ac0c33Sjakob ssize_t 68762ac0c33Sjakob rdata_wireformat_to_rdata_atoms(region_type *region, 68862ac0c33Sjakob domain_table_type *owners, 68962ac0c33Sjakob uint16_t rrtype, 69062ac0c33Sjakob uint16_t data_size, 69162ac0c33Sjakob buffer_type *packet, 69262ac0c33Sjakob rdata_atom_type **rdatas) 69362ac0c33Sjakob { 69462ac0c33Sjakob size_t end = buffer_position(packet) + data_size; 695d65f3523Sjakob size_t i; 69662ac0c33Sjakob rdata_atom_type temp_rdatas[MAXRDATALEN]; 69762ac0c33Sjakob rrtype_descriptor_type *descriptor = rrtype_descriptor_by_type(rrtype); 69862ac0c33Sjakob region_type *temp_region; 69962ac0c33Sjakob 70062ac0c33Sjakob assert(descriptor->maximum <= MAXRDATALEN); 70162ac0c33Sjakob 70262ac0c33Sjakob if (!buffer_available(packet, data_size)) { 70362ac0c33Sjakob return -1; 70462ac0c33Sjakob } 70562ac0c33Sjakob 70662ac0c33Sjakob temp_region = region_create(xalloc, free); 70762ac0c33Sjakob 70862ac0c33Sjakob for (i = 0; i < descriptor->maximum; ++i) { 70962ac0c33Sjakob int is_domain = 0; 71062ac0c33Sjakob int is_normalized = 0; 71162ac0c33Sjakob int is_wirestore = 0; 71262ac0c33Sjakob size_t length = 0; 71362ac0c33Sjakob int required = i < descriptor->minimum; 71462ac0c33Sjakob 71562ac0c33Sjakob switch (rdata_atom_wireformat_type(rrtype, i)) { 71662ac0c33Sjakob case RDATA_WF_COMPRESSED_DNAME: 71762ac0c33Sjakob case RDATA_WF_UNCOMPRESSED_DNAME: 71862ac0c33Sjakob is_domain = 1; 71962ac0c33Sjakob is_normalized = 1; 72062ac0c33Sjakob break; 72162ac0c33Sjakob case RDATA_WF_LITERAL_DNAME: 72262ac0c33Sjakob is_domain = 1; 72362ac0c33Sjakob is_wirestore = 1; 72462ac0c33Sjakob break; 72562ac0c33Sjakob case RDATA_WF_BYTE: 72662ac0c33Sjakob length = sizeof(uint8_t); 72762ac0c33Sjakob break; 72862ac0c33Sjakob case RDATA_WF_SHORT: 72962ac0c33Sjakob length = sizeof(uint16_t); 73062ac0c33Sjakob break; 73162ac0c33Sjakob case RDATA_WF_LONG: 73262ac0c33Sjakob length = sizeof(uint32_t); 73362ac0c33Sjakob break; 734f72b2965Sjakob case RDATA_WF_TEXTS: 735*a302926fSbrad case RDATA_WF_LONG_TEXT: 736*a302926fSbrad length = end - buffer_position(packet); 737f72b2965Sjakob break; 73862ac0c33Sjakob case RDATA_WF_TEXT: 73962ac0c33Sjakob case RDATA_WF_BINARYWITHLENGTH: 74062ac0c33Sjakob /* Length is stored in the first byte. */ 74162ac0c33Sjakob length = 1; 74262ac0c33Sjakob if (buffer_position(packet) + length <= end) { 74362ac0c33Sjakob length += buffer_current(packet)[length - 1]; 74462ac0c33Sjakob } 74562ac0c33Sjakob break; 74662ac0c33Sjakob case RDATA_WF_A: 74762ac0c33Sjakob length = sizeof(in_addr_t); 74862ac0c33Sjakob break; 74962ac0c33Sjakob case RDATA_WF_AAAA: 75062ac0c33Sjakob length = IP6ADDRLEN; 75162ac0c33Sjakob break; 75275343be4Ssthen case RDATA_WF_ILNP64: 75375343be4Ssthen length = IP6ADDRLEN/2; 75475343be4Ssthen break; 7559c620270Ssthen case RDATA_WF_EUI48: 7569c620270Ssthen length = EUI48ADDRLEN; 757*a302926fSbrad break; 7589c620270Ssthen case RDATA_WF_EUI64: 7599c620270Ssthen length = EUI64ADDRLEN; 7609c620270Ssthen break; 76162ac0c33Sjakob case RDATA_WF_BINARY: 76262ac0c33Sjakob /* Remaining RDATA is binary. */ 76362ac0c33Sjakob length = end - buffer_position(packet); 76462ac0c33Sjakob break; 76562ac0c33Sjakob case RDATA_WF_APL: 76662ac0c33Sjakob length = (sizeof(uint16_t) /* address family */ 76762ac0c33Sjakob + sizeof(uint8_t) /* prefix */ 76862ac0c33Sjakob + sizeof(uint8_t)); /* length */ 76962ac0c33Sjakob if (buffer_position(packet) + length <= end) { 77062ac0c33Sjakob /* Mask out negation bit. */ 77162ac0c33Sjakob length += (buffer_current(packet)[length - 1] 77262ac0c33Sjakob & APL_LENGTH_MASK); 77362ac0c33Sjakob } 77462ac0c33Sjakob break; 77562ac0c33Sjakob case RDATA_WF_IPSECGATEWAY: 77662ac0c33Sjakob switch(rdata_atom_data(temp_rdatas[1])[0]) /* gateway type */ { 77762ac0c33Sjakob default: 77862ac0c33Sjakob case IPSECKEY_NOGATEWAY: 77962ac0c33Sjakob length = 0; 78062ac0c33Sjakob break; 78162ac0c33Sjakob case IPSECKEY_IP4: 78262ac0c33Sjakob length = IP4ADDRLEN; 78362ac0c33Sjakob break; 78462ac0c33Sjakob case IPSECKEY_IP6: 78562ac0c33Sjakob length = IP6ADDRLEN; 78662ac0c33Sjakob break; 78762ac0c33Sjakob case IPSECKEY_DNAME: 78862ac0c33Sjakob is_domain = 1; 78962ac0c33Sjakob is_normalized = 1; 79062ac0c33Sjakob is_wirestore = 1; 79162ac0c33Sjakob break; 79262ac0c33Sjakob } 79362ac0c33Sjakob break; 79462ac0c33Sjakob } 79562ac0c33Sjakob 79662ac0c33Sjakob if (is_domain) { 79762ac0c33Sjakob const dname_type *dname; 79862ac0c33Sjakob 79962ac0c33Sjakob if (!required && buffer_position(packet) == end) { 80062ac0c33Sjakob break; 80162ac0c33Sjakob } 80262ac0c33Sjakob 80362ac0c33Sjakob dname = dname_make_from_packet( 80462ac0c33Sjakob temp_region, packet, 1, is_normalized); 80562ac0c33Sjakob if (!dname || buffer_position(packet) > end) { 80662ac0c33Sjakob /* Error in domain name. */ 80762ac0c33Sjakob region_destroy(temp_region); 80862ac0c33Sjakob return -1; 80962ac0c33Sjakob } 81062ac0c33Sjakob if(is_wirestore) { 81162ac0c33Sjakob temp_rdatas[i].data = (uint16_t *) region_alloc( 81262ac0c33Sjakob region, sizeof(uint16_t) + dname->name_size); 81362ac0c33Sjakob temp_rdatas[i].data[0] = dname->name_size; 81462ac0c33Sjakob memcpy(temp_rdatas[i].data+1, dname_name(dname), 81562ac0c33Sjakob dname->name_size); 816dd5b221eSsthen } else { 81762ac0c33Sjakob temp_rdatas[i].domain 81862ac0c33Sjakob = domain_table_insert(owners, dname); 819dd5b221eSsthen temp_rdatas[i].domain->usage ++; 820dd5b221eSsthen } 82162ac0c33Sjakob } else { 82262ac0c33Sjakob if (buffer_position(packet) + length > end) { 82362ac0c33Sjakob if (required) { 82462ac0c33Sjakob /* Truncated RDATA. */ 82562ac0c33Sjakob region_destroy(temp_region); 82662ac0c33Sjakob return -1; 82762ac0c33Sjakob } else { 82862ac0c33Sjakob break; 82962ac0c33Sjakob } 83062ac0c33Sjakob } 8315bcb494bSjakob if (!required && buffer_position(packet) == end) { 8325bcb494bSjakob break; 8335bcb494bSjakob } 83462ac0c33Sjakob 83562ac0c33Sjakob temp_rdatas[i].data = (uint16_t *) region_alloc( 83662ac0c33Sjakob region, sizeof(uint16_t) + length); 83762ac0c33Sjakob temp_rdatas[i].data[0] = length; 83862ac0c33Sjakob buffer_read(packet, temp_rdatas[i].data + 1, length); 83962ac0c33Sjakob } 84062ac0c33Sjakob } 84162ac0c33Sjakob 84262ac0c33Sjakob if (buffer_position(packet) < end) { 84362ac0c33Sjakob /* Trailing garbage. */ 84462ac0c33Sjakob region_destroy(temp_region); 84562ac0c33Sjakob return -1; 84662ac0c33Sjakob } 84762ac0c33Sjakob 84862ac0c33Sjakob *rdatas = (rdata_atom_type *) region_alloc_init( 84962ac0c33Sjakob region, temp_rdatas, i * sizeof(rdata_atom_type)); 85062ac0c33Sjakob region_destroy(temp_region); 851d65f3523Sjakob return (ssize_t)i; 85262ac0c33Sjakob } 85362ac0c33Sjakob 85462ac0c33Sjakob size_t 85562ac0c33Sjakob rdata_maximum_wireformat_size(rrtype_descriptor_type *descriptor, 85662ac0c33Sjakob size_t rdata_count, 85762ac0c33Sjakob rdata_atom_type *rdatas) 85862ac0c33Sjakob { 85962ac0c33Sjakob size_t result = 0; 86062ac0c33Sjakob size_t i; 86162ac0c33Sjakob for (i = 0; i < rdata_count; ++i) { 86262ac0c33Sjakob if (rdata_atom_is_domain(descriptor->type, i)) { 86362ac0c33Sjakob result += domain_dname(rdata_atom_domain(rdatas[i]))->name_size; 86462ac0c33Sjakob } else { 86562ac0c33Sjakob result += rdata_atom_size(rdatas[i]); 86662ac0c33Sjakob } 86762ac0c33Sjakob } 86862ac0c33Sjakob return result; 86962ac0c33Sjakob } 87062ac0c33Sjakob 87162ac0c33Sjakob int 87262ac0c33Sjakob rdata_atoms_to_unknown_string(buffer_type *output, 87362ac0c33Sjakob rrtype_descriptor_type *descriptor, 87462ac0c33Sjakob size_t rdata_count, 87562ac0c33Sjakob rdata_atom_type *rdatas) 87662ac0c33Sjakob { 87762ac0c33Sjakob size_t i; 87862ac0c33Sjakob size_t size = 87962ac0c33Sjakob rdata_maximum_wireformat_size(descriptor, rdata_count, rdatas); 88062ac0c33Sjakob buffer_printf(output, " \\# %lu ", (unsigned long) size); 88162ac0c33Sjakob for (i = 0; i < rdata_count; ++i) { 88262ac0c33Sjakob if (rdata_atom_is_domain(descriptor->type, i)) { 88362ac0c33Sjakob const dname_type *dname = 88462ac0c33Sjakob domain_dname(rdata_atom_domain(rdatas[i])); 88562ac0c33Sjakob hex_to_string( 88662ac0c33Sjakob output, dname_name(dname), dname->name_size); 88762ac0c33Sjakob } else { 88862ac0c33Sjakob hex_to_string(output, rdata_atom_data(rdatas[i]), 88962ac0c33Sjakob rdata_atom_size(rdatas[i])); 89062ac0c33Sjakob } 89162ac0c33Sjakob } 89262ac0c33Sjakob return 1; 89362ac0c33Sjakob } 89462ac0c33Sjakob 89562ac0c33Sjakob int 89662ac0c33Sjakob print_rdata(buffer_type *output, rrtype_descriptor_type *descriptor, 89762ac0c33Sjakob rr_type *record) 89862ac0c33Sjakob { 89962ac0c33Sjakob size_t i; 90062ac0c33Sjakob size_t saved_position = buffer_position(output); 90162ac0c33Sjakob 90262ac0c33Sjakob for (i = 0; i < record->rdata_count; ++i) { 90362ac0c33Sjakob if (i == 0) { 90462ac0c33Sjakob buffer_printf(output, "\t"); 90562ac0c33Sjakob } else if (descriptor->type == TYPE_SOA && i == 2) { 90662ac0c33Sjakob buffer_printf(output, " (\n\t\t"); 90762ac0c33Sjakob } else { 90862ac0c33Sjakob buffer_printf(output, " "); 90962ac0c33Sjakob } 91062ac0c33Sjakob if (!rdata_atom_to_string( 91162ac0c33Sjakob output, 91262ac0c33Sjakob (rdata_zoneformat_type) descriptor->zoneformat[i], 91362ac0c33Sjakob record->rdatas[i], record)) 91462ac0c33Sjakob { 91562ac0c33Sjakob buffer_set_position(output, saved_position); 91662ac0c33Sjakob return 0; 91762ac0c33Sjakob } 91862ac0c33Sjakob } 91962ac0c33Sjakob if (descriptor->type == TYPE_SOA) { 92062ac0c33Sjakob buffer_printf(output, " )"); 92162ac0c33Sjakob } 92262ac0c33Sjakob 92362ac0c33Sjakob return 1; 92462ac0c33Sjakob } 92562ac0c33Sjakob 92662ac0c33Sjakob 927