1 /* 2 * wire2str.c 3 * 4 * conversion routines from the wire format 5 * to the presentation format (strings) 6 * 7 * (c) NLnet Labs, 2004-2006 8 * 9 * See the file LICENSE for the license 10 */ 11 /** 12 * \file 13 * 14 * Contains functions to translate the wireformat to text 15 * representation, as well as functions to print them. 16 */ 17 #include "config.h" 18 #include "sldns/wire2str.h" 19 #include "sldns/str2wire.h" 20 #include "sldns/rrdef.h" 21 #include "sldns/pkthdr.h" 22 #include "sldns/parseutil.h" 23 #include "sldns/sbuffer.h" 24 #include "sldns/keyraw.h" 25 #include "util/data/dname.h" 26 #ifdef HAVE_TIME_H 27 #include <time.h> 28 #endif 29 #include <sys/time.h> 30 #include <stdarg.h> 31 #include <ctype.h> 32 #ifdef HAVE_NETDB_H 33 #include <netdb.h> 34 #endif 35 36 /* lookup tables for standard DNS stuff */ 37 /* Taken from RFC 2535, section 7. */ 38 static sldns_lookup_table sldns_algorithms_data[] = { 39 { LDNS_RSAMD5, "RSAMD5" }, 40 { LDNS_DH, "DH" }, 41 { LDNS_DSA, "DSA" }, 42 { LDNS_ECC, "ECC" }, 43 { LDNS_RSASHA1, "RSASHA1" }, 44 { LDNS_DSA_NSEC3, "DSA-NSEC3-SHA1" }, 45 { LDNS_RSASHA1_NSEC3, "RSASHA1-NSEC3-SHA1" }, 46 { LDNS_RSASHA256, "RSASHA256"}, 47 { LDNS_RSASHA512, "RSASHA512"}, 48 { LDNS_ECC_GOST, "ECC-GOST"}, 49 { LDNS_ECDSAP256SHA256, "ECDSAP256SHA256"}, 50 { LDNS_ECDSAP384SHA384, "ECDSAP384SHA384"}, 51 { LDNS_ED25519, "ED25519"}, 52 { LDNS_ED448, "ED448"}, 53 { LDNS_INDIRECT, "INDIRECT" }, 54 { LDNS_PRIVATEDNS, "PRIVATEDNS" }, 55 { LDNS_PRIVATEOID, "PRIVATEOID" }, 56 { 0, NULL } 57 }; 58 sldns_lookup_table* sldns_algorithms = sldns_algorithms_data; 59 60 /* hash algorithms in DS record */ 61 static sldns_lookup_table sldns_hashes_data[] = { 62 { LDNS_SHA1, "SHA1" }, 63 { LDNS_SHA256, "SHA256" }, 64 { LDNS_HASH_GOST, "HASH-GOST" }, 65 { LDNS_SHA384, "SHA384" }, 66 { 0, NULL } 67 }; 68 sldns_lookup_table* sldns_hashes = sldns_hashes_data; 69 70 /* Taken from RFC 4398 */ 71 static sldns_lookup_table sldns_cert_algorithms_data[] = { 72 { LDNS_CERT_PKIX, "PKIX" }, 73 { LDNS_CERT_SPKI, "SPKI" }, 74 { LDNS_CERT_PGP, "PGP" }, 75 { LDNS_CERT_IPKIX, "IPKIX" }, 76 { LDNS_CERT_ISPKI, "ISPKI" }, 77 { LDNS_CERT_IPGP, "IPGP" }, 78 { LDNS_CERT_ACPKIX, "ACPKIX" }, 79 { LDNS_CERT_IACPKIX, "IACPKIX" }, 80 { LDNS_CERT_URI, "URI" }, 81 { LDNS_CERT_OID, "OID" }, 82 { 0, NULL } 83 }; 84 sldns_lookup_table* sldns_cert_algorithms = sldns_cert_algorithms_data; 85 86 /* if these are used elsewhere */ 87 static sldns_lookup_table sldns_rcodes_data[] = { 88 { LDNS_RCODE_NOERROR, "NOERROR" }, 89 { LDNS_RCODE_FORMERR, "FORMERR" }, 90 { LDNS_RCODE_SERVFAIL, "SERVFAIL" }, 91 { LDNS_RCODE_NXDOMAIN, "NXDOMAIN" }, 92 { LDNS_RCODE_NOTIMPL, "NOTIMPL" }, 93 { LDNS_RCODE_REFUSED, "REFUSED" }, 94 { LDNS_RCODE_YXDOMAIN, "YXDOMAIN" }, 95 { LDNS_RCODE_YXRRSET, "YXRRSET" }, 96 { LDNS_RCODE_NXRRSET, "NXRRSET" }, 97 { LDNS_RCODE_NOTAUTH, "NOTAUTH" }, 98 { LDNS_RCODE_NOTZONE, "NOTZONE" }, 99 { 0, NULL } 100 }; 101 sldns_lookup_table* sldns_rcodes = sldns_rcodes_data; 102 103 static sldns_lookup_table sldns_opcodes_data[] = { 104 { LDNS_PACKET_QUERY, "QUERY" }, 105 { LDNS_PACKET_IQUERY, "IQUERY" }, 106 { LDNS_PACKET_STATUS, "STATUS" }, 107 { LDNS_PACKET_NOTIFY, "NOTIFY" }, 108 { LDNS_PACKET_UPDATE, "UPDATE" }, 109 { 0, NULL } 110 }; 111 sldns_lookup_table* sldns_opcodes = sldns_opcodes_data; 112 113 static sldns_lookup_table sldns_wireparse_errors_data[] = { 114 { LDNS_WIREPARSE_ERR_OK, "no parse error" }, 115 { LDNS_WIREPARSE_ERR_GENERAL, "parse error" }, 116 { LDNS_WIREPARSE_ERR_DOMAINNAME_OVERFLOW, "Domainname length overflow" }, 117 { LDNS_WIREPARSE_ERR_DOMAINNAME_UNDERFLOW, "Domainname length underflow (zero length)" }, 118 { LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL, "buffer too small" }, 119 { LDNS_WIREPARSE_ERR_LABEL_OVERFLOW, "Label length overflow" }, 120 { LDNS_WIREPARSE_ERR_EMPTY_LABEL, "Empty label" }, 121 { LDNS_WIREPARSE_ERR_SYNTAX_BAD_ESCAPE, "Syntax error, bad escape sequence" }, 122 { LDNS_WIREPARSE_ERR_SYNTAX, "Syntax error, could not parse the RR" }, 123 { LDNS_WIREPARSE_ERR_SYNTAX_TTL, "Syntax error, could not parse the RR's TTL" }, 124 { LDNS_WIREPARSE_ERR_SYNTAX_TYPE, "Syntax error, could not parse the RR's type" }, 125 { LDNS_WIREPARSE_ERR_SYNTAX_CLASS, "Syntax error, could not parse the RR's class" }, 126 { LDNS_WIREPARSE_ERR_SYNTAX_RDATA, "Syntax error, could not parse the RR's rdata" }, 127 { LDNS_WIREPARSE_ERR_SYNTAX_MISSING_VALUE, "Syntax error, value expected" }, 128 { LDNS_WIREPARSE_ERR_INVALID_STR, "Conversion error, string expected" }, 129 { LDNS_WIREPARSE_ERR_SYNTAX_B64, "Conversion error, b64 encoding expected" }, 130 { LDNS_WIREPARSE_ERR_SYNTAX_B32_EXT, "Conversion error, b32 ext encoding expected" }, 131 { LDNS_WIREPARSE_ERR_SYNTAX_HEX, "Conversion error, hex encoding expected" }, 132 { LDNS_WIREPARSE_ERR_CERT_BAD_ALGORITHM, "Bad algorithm type for CERT record" }, 133 { LDNS_WIREPARSE_ERR_SYNTAX_TIME, "Conversion error, time encoding expected" }, 134 { LDNS_WIREPARSE_ERR_SYNTAX_PERIOD, "Conversion error, time period encoding expected" }, 135 { LDNS_WIREPARSE_ERR_SYNTAX_ILNP64, "Conversion error, 4 colon separated hex numbers expected" }, 136 { LDNS_WIREPARSE_ERR_SYNTAX_EUI48, 137 "Conversion error, 6 two character hex numbers " 138 "separated by dashes expected (i.e. xx-xx-xx-xx-xx-xx" }, 139 { LDNS_WIREPARSE_ERR_SYNTAX_EUI64, 140 "Conversion error, 8 two character hex numbers " 141 "separated by dashes expected (i.e. xx-xx-xx-xx-xx-xx-xx-xx" }, 142 { LDNS_WIREPARSE_ERR_SYNTAX_TAG, 143 "Conversion error, a non-zero sequence of US-ASCII letters " 144 "and numbers in lower case expected" }, 145 { LDNS_WIREPARSE_ERR_NOT_IMPL, "not implemented" }, 146 { LDNS_WIREPARSE_ERR_SYNTAX_INT, "Conversion error, integer expected" }, 147 { LDNS_WIREPARSE_ERR_SYNTAX_IP4, "Conversion error, ip4 addr expected" }, 148 { LDNS_WIREPARSE_ERR_SYNTAX_IP6, "Conversion error, ip6 addr expected" }, 149 { LDNS_WIREPARSE_ERR_SYNTAX_INTEGER_OVERFLOW, "Syntax error, integer overflow" }, 150 { LDNS_WIREPARSE_ERR_INCLUDE, "$INCLUDE directive was seen in the zone" }, 151 { LDNS_WIREPARSE_ERR_PARENTHESIS, "Parse error, parenthesis mismatch" }, 152 { LDNS_WIREPARSE_ERR_SVCB_UNKNOWN_KEY, "Unknown SvcParamKey"}, 153 { LDNS_WIREPARSE_ERR_SVCB_MISSING_PARAM, "SvcParam is missing a SvcParamValue"}, 154 { LDNS_WIREPARSE_ERR_SVCB_DUPLICATE_KEYS, "Duplicate SVCB key found"}, 155 { LDNS_WIREPARSE_ERR_SVCB_MANDATORY_TOO_MANY_KEYS, "Too many keys in mandatory" }, 156 { LDNS_WIREPARSE_ERR_SVCB_TOO_MANY_PARAMS, 157 "Too many SvcParams. Unbound only allows 63 entries" }, 158 { LDNS_WIREPARSE_ERR_SVCB_MANDATORY_MISSING_PARAM, 159 "Mandatory SvcParamKey is missing"}, 160 { LDNS_WIREPARSE_ERR_SVCB_MANDATORY_DUPLICATE_KEY, 161 "Keys in SvcParam mandatory MUST be unique" }, 162 { LDNS_WIREPARSE_ERR_SVCB_MANDATORY_IN_MANDATORY, 163 "mandatory MUST not be included as mandatory parameter" }, 164 { LDNS_WIREPARSE_ERR_SVCB_PORT_VALUE_SYNTAX, 165 "Could not parse port SvcParamValue" }, 166 { LDNS_WIREPARSE_ERR_SVCB_IPV4_TOO_MANY_ADDRESSES, 167 "Too many IPv4 addresses in ipv4hint" }, 168 { LDNS_WIREPARSE_ERR_SVCB_IPV6_TOO_MANY_ADDRESSES, 169 "Too many IPv6 addresses in ipv6hint" }, 170 { LDNS_WIREPARSE_ERR_SVCB_ALPN_KEY_TOO_LARGE, 171 "Alpn strings need to be smaller than 255 chars"}, 172 { LDNS_WIREPARSE_ERR_SVCB_NO_DEFAULT_ALPN_VALUE, 173 "No-default-alpn should not have a value" }, 174 { LDNS_WIREPARSE_ERR_SVCPARAM_BROKEN_RDATA, 175 "General SVCParam error" }, 176 { 0, NULL } 177 }; 178 sldns_lookup_table* sldns_wireparse_errors = sldns_wireparse_errors_data; 179 180 static sldns_lookup_table sldns_edns_flags_data[] = { 181 { 3600, "do"}, 182 { 0, NULL} 183 }; 184 sldns_lookup_table* sldns_edns_flags = sldns_edns_flags_data; 185 186 static sldns_lookup_table sldns_edns_options_data[] = { 187 { 1, "LLQ" }, 188 { 2, "UL" }, 189 { 3, "NSID" }, 190 /* 4 draft-cheshire-edns0-owner-option */ 191 { 5, "DAU" }, 192 { 6, "DHU" }, 193 { 7, "N3U" }, 194 { 8, "edns-client-subnet" }, 195 { 10, "COOKIE" }, 196 { 11, "edns-tcp-keepalive"}, 197 { 12, "Padding" }, 198 { 15, "EDE"}, 199 { 0, NULL} 200 }; 201 sldns_lookup_table* sldns_edns_options = sldns_edns_options_data; 202 203 /* From RFC8914 5.2 Table 3, the "Extended DNS Error Codes" registry. */ 204 static sldns_lookup_table sldns_edns_ede_codes_data[] = { 205 { LDNS_EDE_NONE, "None" }, 206 { LDNS_EDE_OTHER, "Other Error" }, 207 { LDNS_EDE_UNSUPPORTED_DNSKEY_ALG, "Unsupported DNSKEY Algorithm" }, 208 { LDNS_EDE_UNSUPPORTED_DS_DIGEST, "Unsupported DS Digest Type" }, 209 { LDNS_EDE_STALE_ANSWER, "Stale Answer" }, 210 { LDNS_EDE_FORGED_ANSWER, "Forged Answer" }, 211 { LDNS_EDE_DNSSEC_INDETERMINATE, "DNSSEC Indeterminate" }, 212 { LDNS_EDE_DNSSEC_BOGUS, "DNSSEC Bogus" }, 213 { LDNS_EDE_SIGNATURE_EXPIRED, "Signature Expired" }, 214 { LDNS_EDE_SIGNATURE_NOT_YET_VALID, "Signature Not Yet Valid" }, 215 { LDNS_EDE_DNSKEY_MISSING, "DNSKEY Missing" }, 216 { LDNS_EDE_RRSIGS_MISSING, "RRSIGs Missing" }, 217 { LDNS_EDE_NO_ZONE_KEY_BIT_SET, "No Zone Key Bit Set" }, 218 { LDNS_EDE_NSEC_MISSING, "NSEC Missing" }, 219 { LDNS_EDE_CACHED_ERROR, "Cached Error" }, 220 { LDNS_EDE_NOT_READY, "Not Ready" }, 221 { LDNS_EDE_BLOCKED, "Blocked" }, 222 { LDNS_EDE_CENSORED, "Censored" }, 223 { LDNS_EDE_FILTERED, "Filtered" }, 224 { LDNS_EDE_PROHIBITED, "Prohibited" }, 225 { LDNS_EDE_STALE_NXDOMAIN_ANSWER, "Stale NXDOMAIN Answer" }, 226 { LDNS_EDE_NOT_AUTHORITATIVE, "Not Authoritative" }, 227 { LDNS_EDE_NOT_SUPPORTED, "Not Supported" }, 228 { LDNS_EDE_NO_REACHABLE_AUTHORITY, "No Reachable Authority" }, 229 { LDNS_EDE_NETWORK_ERROR, "Network Error" }, 230 { LDNS_EDE_INVALID_DATA, "Invalid Data" }, 231 { LDNS_EDE_SIGNATURE_EXPIRED_BEFORE_VALID, "Signature Expired Before Valid" }, 232 { LDNS_EDE_TOO_EARLY, "Non-Replayable Transactions Received in 0-RTT Data" }, 233 { LDNS_EDE_UNSUPPORTED_NSEC3_ITERATIONS, "Unsupported NSEC3 Iterations Value" }, 234 { LDNS_EDE_BADPROXYPOLICY, "Unable to Conform to Policy" }, 235 { LDNS_EDE_SYNTHESIZED, "Synthesized Answer" }, 236 { LDNS_EDE_INVALID_QUERY_TYPE, "Invalid Query Type" }, 237 { 0, NULL} 238 }; 239 sldns_lookup_table* sldns_edns_ede_codes = sldns_edns_ede_codes_data; 240 241 static sldns_lookup_table sldns_tsig_errors_data[] = { 242 { LDNS_TSIG_ERROR_NOERROR, "NOERROR" }, 243 { LDNS_RCODE_FORMERR, "FORMERR" }, 244 { LDNS_RCODE_SERVFAIL, "SERVFAIL" }, 245 { LDNS_RCODE_NXDOMAIN, "NXDOMAIN" }, 246 { LDNS_RCODE_NOTIMPL, "NOTIMPL" }, 247 { LDNS_RCODE_REFUSED, "REFUSED" }, 248 { LDNS_RCODE_YXDOMAIN, "YXDOMAIN" }, 249 { LDNS_RCODE_YXRRSET, "YXRRSET" }, 250 { LDNS_RCODE_NXRRSET, "NXRRSET" }, 251 { LDNS_RCODE_NOTAUTH, "NOTAUTH" }, 252 { LDNS_RCODE_NOTZONE, "NOTZONE" }, 253 { LDNS_TSIG_ERROR_BADSIG, "BADSIG" }, 254 { LDNS_TSIG_ERROR_BADKEY, "BADKEY" }, 255 { LDNS_TSIG_ERROR_BADTIME, "BADTIME" }, 256 { LDNS_TSIG_ERROR_BADMODE, "BADMODE" }, 257 { LDNS_TSIG_ERROR_BADNAME, "BADNAME" }, 258 { LDNS_TSIG_ERROR_BADALG, "BADALG" }, 259 { 0, NULL } 260 }; 261 sldns_lookup_table* sldns_tsig_errors = sldns_tsig_errors_data; 262 263 /* draft-ietf-dnsop-svcb-https-06: 6. Initial SvcParamKeys */ 264 const char *svcparamkey_strs[] = { 265 "mandatory", "alpn", "no-default-alpn", "port", 266 "ipv4hint", "ech", "ipv6hint", "dohpath" 267 }; 268 269 char* sldns_wire2str_pkt(uint8_t* data, size_t len) 270 { 271 size_t slen = (size_t)sldns_wire2str_pkt_buf(data, len, NULL, 0); 272 char* result = (char*)malloc(slen+1); 273 if(!result) return NULL; 274 sldns_wire2str_pkt_buf(data, len, result, slen+1); 275 return result; 276 } 277 278 char* sldns_wire2str_rr(uint8_t* rr, size_t len) 279 { 280 size_t slen = (size_t)sldns_wire2str_rr_buf(rr, len, NULL, 0); 281 char* result = (char*)malloc(slen+1); 282 if(!result) return NULL; 283 sldns_wire2str_rr_buf(rr, len, result, slen+1); 284 return result; 285 } 286 287 char* sldns_wire2str_type(uint16_t rrtype) 288 { 289 char buf[16]; 290 sldns_wire2str_type_buf(rrtype, buf, sizeof(buf)); 291 return strdup(buf); 292 } 293 294 char* sldns_wire2str_class(uint16_t rrclass) 295 { 296 char buf[16]; 297 sldns_wire2str_class_buf(rrclass, buf, sizeof(buf)); 298 return strdup(buf); 299 } 300 301 char* sldns_wire2str_dname(uint8_t* dname, size_t dname_len) 302 { 303 size_t slen=(size_t)sldns_wire2str_dname_buf(dname, dname_len, NULL, 0); 304 char* result = (char*)malloc(slen+1); 305 if(!result) return NULL; 306 sldns_wire2str_dname_buf(dname, dname_len, result, slen+1); 307 return result; 308 } 309 310 char* sldns_wire2str_rcode(int rcode) 311 { 312 char buf[16]; 313 sldns_wire2str_rcode_buf(rcode, buf, sizeof(buf)); 314 return strdup(buf); 315 } 316 317 int sldns_wire2str_pkt_buf(uint8_t* d, size_t dlen, char* s, size_t slen) 318 { 319 /* use arguments as temporary variables */ 320 return sldns_wire2str_pkt_scan(&d, &dlen, &s, &slen); 321 } 322 323 int sldns_wire2str_rr_buf(uint8_t* d, size_t dlen, char* s, size_t slen) 324 { 325 /* use arguments as temporary variables */ 326 return sldns_wire2str_rr_scan(&d, &dlen, &s, &slen, NULL, 0, NULL); 327 } 328 329 int sldns_wire2str_rrquestion_buf(uint8_t* d, size_t dlen, char* s, size_t slen) 330 { 331 /* use arguments as temporary variables */ 332 return sldns_wire2str_rrquestion_scan(&d, &dlen, &s, &slen, NULL, 0, NULL); 333 } 334 335 int sldns_wire2str_rdata_buf(uint8_t* rdata, size_t rdata_len, char* str, 336 size_t str_len, uint16_t rrtype) 337 { 338 /* use arguments as temporary variables */ 339 return sldns_wire2str_rdata_scan(&rdata, &rdata_len, &str, &str_len, 340 rrtype, NULL, 0, NULL); 341 } 342 343 int sldns_wire2str_rr_unknown_buf(uint8_t* d, size_t dlen, char* s, size_t slen) 344 { 345 /* use arguments as temporary variables */ 346 return sldns_wire2str_rr_unknown_scan(&d, &dlen, &s, &slen, NULL, 0, NULL); 347 } 348 349 int sldns_wire2str_rr_comment_buf(uint8_t* rr, size_t rrlen, size_t dname_len, 350 char* s, size_t slen) 351 { 352 uint16_t rrtype = sldns_wirerr_get_type(rr, rrlen, dname_len); 353 return sldns_wire2str_rr_comment_print(&s, &slen, rr, rrlen, dname_len, 354 rrtype); 355 } 356 357 int sldns_wire2str_type_buf(uint16_t rrtype, char* s, size_t slen) 358 { 359 /* use arguments as temporary variables */ 360 return sldns_wire2str_type_print(&s, &slen, rrtype); 361 } 362 363 int sldns_wire2str_class_buf(uint16_t rrclass, char* s, size_t slen) 364 { 365 /* use arguments as temporary variables */ 366 return sldns_wire2str_class_print(&s, &slen, rrclass); 367 } 368 369 int sldns_wire2str_rcode_buf(int rcode, char* s, size_t slen) 370 { 371 /* use arguments as temporary variables */ 372 return sldns_wire2str_rcode_print(&s, &slen, rcode); 373 } 374 375 int sldns_wire2str_opcode_buf(int opcode, char* s, size_t slen) 376 { 377 /* use arguments as temporary variables */ 378 return sldns_wire2str_opcode_print(&s, &slen, opcode); 379 } 380 381 int sldns_wire2str_dname_buf(uint8_t* d, size_t dlen, char* s, size_t slen) 382 { 383 /* use arguments as temporary variables */ 384 return sldns_wire2str_dname_scan(&d, &dlen, &s, &slen, NULL, 0, NULL); 385 } 386 387 int sldns_str_vprint(char** str, size_t* slen, const char* format, va_list args) 388 { 389 int w = vsnprintf(*str, *slen, format, args); 390 if(w < 0) { 391 /* error in printout */ 392 return 0; 393 } else if((size_t)w >= *slen) { 394 *str = NULL; /* we do not want str to point outside of buffer*/ 395 *slen = 0; 396 } else { 397 *str += w; 398 *slen -= w; 399 } 400 return w; 401 } 402 403 int sldns_str_print(char** str, size_t* slen, const char* format, ...) 404 { 405 int w; 406 va_list args; 407 va_start(args, format); 408 w = sldns_str_vprint(str, slen, format, args); 409 va_end(args); 410 return w; 411 } 412 413 /** print hex format into text buffer for specified length */ 414 static int print_hex_buf(char** s, size_t* slen, uint8_t* buf, size_t len) 415 { 416 const char* hex = "0123456789ABCDEF"; 417 size_t i; 418 for(i=0; i<len; i++) { 419 (void)sldns_str_print(s, slen, "%c%c", hex[(buf[i]&0xf0)>>4], 420 hex[buf[i]&0x0f]); 421 } 422 return (int)len*2; 423 } 424 425 /** print remainder of buffer in hex format with prefixed text */ 426 static int print_remainder_hex(const char* pref, uint8_t** d, size_t* dlen, 427 char** s, size_t* slen) 428 { 429 int w = 0; 430 w += sldns_str_print(s, slen, "%s", pref); 431 w += print_hex_buf(s, slen, *d, *dlen); 432 *d += *dlen; 433 *dlen = 0; 434 return w; 435 } 436 437 int sldns_wire2str_pkt_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen) 438 { 439 int w = 0, comprloop = 0; 440 unsigned qdcount, ancount, nscount, arcount, i; 441 uint8_t* pkt = *d; 442 size_t pktlen = *dlen; 443 if(*dlen >= LDNS_HEADER_SIZE) { 444 qdcount = (unsigned)LDNS_QDCOUNT(*d); 445 ancount = (unsigned)LDNS_ANCOUNT(*d); 446 nscount = (unsigned)LDNS_NSCOUNT(*d); 447 arcount = (unsigned)LDNS_ARCOUNT(*d); 448 } else { 449 qdcount = ancount = nscount = arcount = 0; 450 } 451 w += sldns_wire2str_header_scan(d, dlen, s, slen); 452 w += sldns_str_print(s, slen, "\n"); 453 w += sldns_str_print(s, slen, ";; QUESTION SECTION:\n"); 454 for(i=0; i<qdcount; i++) { 455 w += sldns_wire2str_rrquestion_scan(d, dlen, s, slen, 456 pkt, pktlen, &comprloop); 457 if(!*dlen) break; 458 } 459 w += sldns_str_print(s, slen, "\n"); 460 w += sldns_str_print(s, slen, ";; ANSWER SECTION:\n"); 461 for(i=0; i<ancount; i++) { 462 w += sldns_wire2str_rr_scan(d, dlen, s, slen, pkt, pktlen, &comprloop); 463 if(!*dlen) break; 464 } 465 w += sldns_str_print(s, slen, "\n"); 466 w += sldns_str_print(s, slen, ";; AUTHORITY SECTION:\n"); 467 for(i=0; i<nscount; i++) { 468 w += sldns_wire2str_rr_scan(d, dlen, s, slen, pkt, pktlen, &comprloop); 469 if(!*dlen) break; 470 } 471 w += sldns_str_print(s, slen, "\n"); 472 w += sldns_str_print(s, slen, ";; ADDITIONAL SECTION:\n"); 473 for(i=0; i<arcount; i++) { 474 w += sldns_wire2str_rr_scan(d, dlen, s, slen, pkt, pktlen, &comprloop); 475 if(!*dlen) break; 476 } 477 /* other fields: WHEN(time), SERVER(IP) not available here. */ 478 w += sldns_str_print(s, slen, ";; MSG SIZE rcvd: %d\n", (int)pktlen); 479 if(*dlen > 0) { 480 w += print_remainder_hex(";; trailing garbage 0x", 481 d, dlen, s, slen); 482 w += sldns_str_print(s, slen, "\n"); 483 } 484 return w; 485 } 486 487 /** scan type, class and ttl and printout, for rr */ 488 static int sldns_rr_tcttl_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 489 { 490 int w = 0; 491 uint16_t t, c; 492 uint32_t ttl; 493 if(*dl < 8) { 494 if(*dl < 4) 495 return w + print_remainder_hex("; Error malformed 0x", 496 d, dl, s, sl); 497 /* these print values or 0x.. if none left */ 498 t = sldns_read_uint16(*d); 499 c = sldns_read_uint16((*d)+2); 500 (*d)+=4; 501 (*dl)-=4; 502 w += sldns_wire2str_class_print(s, sl, c); 503 w += sldns_str_print(s, sl, "\t"); 504 w += sldns_wire2str_type_print(s, sl, t); 505 if(*dl == 0) 506 return w + sldns_str_print(s, sl, "; Error no ttl"); 507 return w + print_remainder_hex( 508 "; Error malformed ttl 0x", d, dl, s, sl); 509 } 510 t = sldns_read_uint16(*d); 511 c = sldns_read_uint16((*d)+2); 512 ttl = sldns_read_uint32((*d)+4); 513 (*d)+=8; 514 (*dl)-=8; 515 w += sldns_str_print(s, sl, "%lu\t", (unsigned long)ttl); 516 w += sldns_wire2str_class_print(s, sl, c); 517 w += sldns_str_print(s, sl, "\t"); 518 w += sldns_wire2str_type_print(s, sl, t); 519 return w; 520 } 521 522 int sldns_wire2str_rr_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen, 523 uint8_t* pkt, size_t pktlen, int* comprloop) 524 { 525 int w = 0; 526 uint8_t* rr = *d; 527 size_t rrlen = *dlen, dname_off, rdlen, ordlen; 528 uint16_t rrtype = 0; 529 530 if(*dlen >= 3 && (*d)[0]==0 && 531 sldns_read_uint16((*d)+1)==LDNS_RR_TYPE_OPT) { 532 /* perform EDNS OPT processing */ 533 return sldns_wire2str_edns_scan(d, dlen, s, slen, pkt, pktlen); 534 } 535 536 /* try to scan the rdata with pretty-printing, but if that fails, then 537 * scan the rdata as an unknown RR type */ 538 w += sldns_wire2str_dname_scan(d, dlen, s, slen, pkt, pktlen, comprloop); 539 w += sldns_str_print(s, slen, "\t"); 540 dname_off = rrlen-(*dlen); 541 if(*dlen == 4) { 542 /* like a question-RR */ 543 uint16_t t = sldns_read_uint16(*d); 544 uint16_t c = sldns_read_uint16((*d)+2); 545 (*d)+=4; 546 (*dlen)-=4; 547 w += sldns_wire2str_class_print(s, slen, c); 548 w += sldns_str_print(s, slen, "\t"); 549 w += sldns_wire2str_type_print(s, slen, t); 550 w += sldns_str_print(s, slen, " ; Error no ttl,rdata\n"); 551 return w; 552 } 553 if(*dlen < 8) { 554 if(*dlen == 0) 555 return w + sldns_str_print(s, slen, ";Error missing RR\n"); 556 w += print_remainder_hex(";Error partial RR 0x", d, dlen, s, slen); 557 return w + sldns_str_print(s, slen, "\n"); 558 } 559 rrtype = sldns_read_uint16(*d); 560 w += sldns_rr_tcttl_scan(d, dlen, s, slen); 561 w += sldns_str_print(s, slen, "\t"); 562 563 /* rdata */ 564 if(*dlen < 2) { 565 if(*dlen == 0) 566 return w + sldns_str_print(s, slen, ";Error missing rdatalen\n"); 567 w += print_remainder_hex(";Error missing rdatalen 0x", 568 d, dlen, s, slen); 569 return w + sldns_str_print(s, slen, "\n"); 570 } 571 rdlen = sldns_read_uint16(*d); 572 ordlen = rdlen; 573 (*d)+=2; 574 (*dlen)-=2; 575 if(*dlen < rdlen) { 576 w += sldns_str_print(s, slen, "\\# %u ", (unsigned)rdlen); 577 if(*dlen == 0) 578 return w + sldns_str_print(s, slen, ";Error missing rdata\n"); 579 w += print_remainder_hex(";Error partial rdata 0x", d, dlen, s, slen); 580 return w + sldns_str_print(s, slen, "\n"); 581 } 582 w += sldns_wire2str_rdata_scan(d, &rdlen, s, slen, rrtype, pkt, pktlen, 583 comprloop); 584 (*dlen) -= (ordlen-rdlen); 585 586 /* default comment */ 587 w += sldns_wire2str_rr_comment_print(s, slen, rr, rrlen, dname_off, 588 rrtype); 589 w += sldns_str_print(s, slen, "\n"); 590 return w; 591 } 592 593 int sldns_wire2str_rrquestion_scan(uint8_t** d, size_t* dlen, char** s, 594 size_t* slen, uint8_t* pkt, size_t pktlen, int* comprloop) 595 { 596 int w = 0; 597 uint16_t t, c; 598 w += sldns_wire2str_dname_scan(d, dlen, s, slen, pkt, pktlen, comprloop); 599 w += sldns_str_print(s, slen, "\t"); 600 if(*dlen < 4) { 601 if(*dlen == 0) 602 return w + sldns_str_print(s, slen, "Error malformed\n"); 603 w += print_remainder_hex("Error malformed 0x", d, dlen, s, slen); 604 return w + sldns_str_print(s, slen, "\n"); 605 } 606 t = sldns_read_uint16(*d); 607 c = sldns_read_uint16((*d)+2); 608 (*d)+=4; 609 (*dlen)-=4; 610 w += sldns_wire2str_class_print(s, slen, c); 611 w += sldns_str_print(s, slen, "\t"); 612 w += sldns_wire2str_type_print(s, slen, t); 613 w += sldns_str_print(s, slen, "\n"); 614 return w; 615 } 616 617 int sldns_wire2str_rr_unknown_scan(uint8_t** d, size_t* dlen, char** s, 618 size_t* slen, uint8_t* pkt, size_t pktlen, int* comprloop) 619 { 620 size_t rdlen, ordlen; 621 int w = 0; 622 w += sldns_wire2str_dname_scan(d, dlen, s, slen, pkt, pktlen, comprloop); 623 w += sldns_str_print(s, slen, "\t"); 624 w += sldns_rr_tcttl_scan(d, dlen, s, slen); 625 w += sldns_str_print(s, slen, "\t"); 626 if(*dlen < 2) { 627 if(*dlen == 0) 628 return w + sldns_str_print(s, slen, ";Error missing rdatalen\n"); 629 w += print_remainder_hex(";Error missing rdatalen 0x", 630 d, dlen, s, slen); 631 return w + sldns_str_print(s, slen, "\n"); 632 } 633 rdlen = sldns_read_uint16(*d); 634 ordlen = rdlen; 635 (*d) += 2; 636 (*dlen) -= 2; 637 if(*dlen < rdlen) { 638 w += sldns_str_print(s, slen, "\\# %u ", (unsigned)rdlen); 639 if(*dlen == 0) 640 return w + sldns_str_print(s, slen, ";Error missing rdata\n"); 641 w += print_remainder_hex(";Error partial rdata 0x", d, dlen, s, slen); 642 return w + sldns_str_print(s, slen, "\n"); 643 } 644 w += sldns_wire2str_rdata_unknown_scan(d, &rdlen, s, slen); 645 (*dlen) -= (ordlen-rdlen); 646 w += sldns_str_print(s, slen, "\n"); 647 return w; 648 } 649 650 /** print rr comment for type DNSKEY */ 651 static int rr_comment_dnskey(char** s, size_t* slen, uint8_t* rr, 652 size_t rrlen, size_t dname_off) 653 { 654 size_t rdlen; 655 uint8_t* rdata; 656 int flags, w = 0; 657 if(rrlen < dname_off + 10) return 0; 658 rdlen = sldns_read_uint16(rr+dname_off+8); 659 if(rrlen < dname_off + 10 + rdlen) return 0; 660 if(rdlen < 2) return 0; 661 rdata = rr + dname_off + 10; 662 flags = (int)sldns_read_uint16(rdata); 663 w += sldns_str_print(s, slen, " ;{"); 664 665 /* id */ 666 w += sldns_str_print(s, slen, "id = %u", 667 sldns_calc_keytag_raw(rdata, rdlen)); 668 669 /* flags */ 670 if((flags&LDNS_KEY_ZONE_KEY)) { 671 if((flags&LDNS_KEY_SEP_KEY)) 672 w += sldns_str_print(s, slen, " (ksk)"); 673 else w += sldns_str_print(s, slen, " (zsk)"); 674 } 675 676 /* keysize */ 677 if(rdlen > 4) { 678 w += sldns_str_print(s, slen, ", "); 679 w += sldns_str_print(s, slen, "size = %db", 680 (int)sldns_rr_dnskey_key_size_raw( 681 (unsigned char*)rdata+4, rdlen-4, (int)(rdata[3]))); 682 } 683 684 w += sldns_str_print(s, slen, "}"); 685 return w; 686 } 687 688 /** print rr comment for type RRSIG */ 689 static int rr_comment_rrsig(char** s, size_t* slen, uint8_t* rr, 690 size_t rrlen, size_t dname_off) 691 { 692 size_t rdlen; 693 uint8_t* rdata; 694 if(rrlen < dname_off + 10) return 0; 695 rdlen = sldns_read_uint16(rr+dname_off+8); 696 if(rrlen < dname_off + 10 + rdlen) return 0; 697 rdata = rr + dname_off + 10; 698 if(rdlen < 18) return 0; 699 return sldns_str_print(s, slen, " ;{id = %d}", 700 (int)sldns_read_uint16(rdata+16)); 701 } 702 703 /** print rr comment for type NSEC3 */ 704 static int rr_comment_nsec3(char** s, size_t* slen, uint8_t* rr, 705 size_t rrlen, size_t dname_off) 706 { 707 size_t rdlen; 708 uint8_t* rdata; 709 int w = 0; 710 if(rrlen < dname_off + 10) return 0; 711 rdlen = sldns_read_uint16(rr+dname_off+8); 712 if(rrlen < dname_off + 10 + rdlen) return 0; 713 rdata = rr + dname_off + 10; 714 if(rdlen < 2) return 0; 715 if((rdata[1] & LDNS_NSEC3_VARS_OPTOUT_MASK)) 716 w += sldns_str_print(s, slen, " ;{flags: optout}"); 717 return w; 718 } 719 720 int sldns_wire2str_rr_comment_print(char** s, size_t* slen, uint8_t* rr, 721 size_t rrlen, size_t dname_off, uint16_t rrtype) 722 { 723 if(rrtype == LDNS_RR_TYPE_DNSKEY) { 724 return rr_comment_dnskey(s, slen, rr, rrlen, dname_off); 725 } else if(rrtype == LDNS_RR_TYPE_RRSIG) { 726 return rr_comment_rrsig(s, slen, rr, rrlen, dname_off); 727 } else if(rrtype == LDNS_RR_TYPE_NSEC3) { 728 return rr_comment_nsec3(s, slen, rr, rrlen, dname_off); 729 } 730 return 0; 731 } 732 733 int sldns_wire2str_header_scan(uint8_t** d, size_t* dlen, char** s, 734 size_t* slen) 735 { 736 int w = 0; 737 int opcode, rcode; 738 w += sldns_str_print(s, slen, ";; ->>HEADER<<- "); 739 if(*dlen == 0) 740 return w+sldns_str_print(s, slen, "Error empty packet"); 741 if(*dlen < 4) 742 return w+print_remainder_hex("Error header too short 0x", d, dlen, s, slen); 743 opcode = (int)LDNS_OPCODE_WIRE(*d); 744 rcode = (int)LDNS_RCODE_WIRE(*d); 745 w += sldns_str_print(s, slen, "opcode: "); 746 w += sldns_wire2str_opcode_print(s, slen, opcode); 747 w += sldns_str_print(s, slen, ", "); 748 w += sldns_str_print(s, slen, "rcode: "); 749 w += sldns_wire2str_rcode_print(s, slen, rcode); 750 w += sldns_str_print(s, slen, ", "); 751 w += sldns_str_print(s, slen, "id: %d\n", (int)LDNS_ID_WIRE(*d)); 752 w += sldns_str_print(s, slen, ";; flags:"); 753 if(LDNS_QR_WIRE(*d)) w += sldns_str_print(s, slen, " qr"); 754 if(LDNS_AA_WIRE(*d)) w += sldns_str_print(s, slen, " aa"); 755 if(LDNS_TC_WIRE(*d)) w += sldns_str_print(s, slen, " tc"); 756 if(LDNS_RD_WIRE(*d)) w += sldns_str_print(s, slen, " rd"); 757 if(LDNS_CD_WIRE(*d)) w += sldns_str_print(s, slen, " cd"); 758 if(LDNS_RA_WIRE(*d)) w += sldns_str_print(s, slen, " ra"); 759 if(LDNS_AD_WIRE(*d)) w += sldns_str_print(s, slen, " ad"); 760 if(LDNS_Z_WIRE(*d)) w += sldns_str_print(s, slen, " z"); 761 w += sldns_str_print(s, slen, " ; "); 762 if(*dlen < LDNS_HEADER_SIZE) 763 return w+print_remainder_hex("Error header too short 0x", d, dlen, s, slen); 764 w += sldns_str_print(s, slen, "QUERY: %d, ", (int)LDNS_QDCOUNT(*d)); 765 w += sldns_str_print(s, slen, "ANSWER: %d, ", (int)LDNS_ANCOUNT(*d)); 766 w += sldns_str_print(s, slen, "AUTHORITY: %d, ", (int)LDNS_NSCOUNT(*d)); 767 w += sldns_str_print(s, slen, "ADDITIONAL: %d ", (int)LDNS_ARCOUNT(*d)); 768 *d += LDNS_HEADER_SIZE; 769 *dlen -= LDNS_HEADER_SIZE; 770 return w; 771 } 772 773 int sldns_wire2str_rdata_scan(uint8_t** d, size_t* dlen, char** s, 774 size_t* slen, uint16_t rrtype, uint8_t* pkt, size_t pktlen, 775 int* comprloop) 776 { 777 /* try to prettyprint, but if that fails, use unknown format */ 778 uint8_t* origd = *d; 779 char* origs = *s; 780 size_t origdlen = *dlen, origslen = *slen; 781 size_t r_cnt, r_max; 782 sldns_rdf_type rdftype; 783 int w = 0, n; 784 785 const sldns_rr_descriptor *desc = sldns_rr_descript(rrtype); 786 if(!desc) /* unknown format */ 787 return sldns_wire2str_rdata_unknown_scan(d, dlen, s, slen); 788 /* dlen equals the rdatalen for the rdata */ 789 790 r_max = sldns_rr_descriptor_maximum(desc); 791 for(r_cnt=0; r_cnt < r_max; r_cnt++) { 792 if(*dlen == 0) { 793 if(r_cnt < sldns_rr_descriptor_minimum(desc)) 794 goto failed; 795 break; /* nothing more to print */ 796 } 797 rdftype = sldns_rr_descriptor_field_type(desc, r_cnt); 798 if(r_cnt != 0) 799 w += sldns_str_print(s, slen, " "); 800 n = sldns_wire2str_rdf_scan(d, dlen, s, slen, rdftype, 801 pkt, pktlen, comprloop); 802 if(n == -1) { 803 failed: 804 /* failed, use unknown format */ 805 *d = origd; *s = origs; 806 *dlen = origdlen; *slen = origslen; 807 return sldns_wire2str_rdata_unknown_scan(d, dlen, 808 s, slen); 809 } 810 w += n; 811 } 812 if(*dlen != 0) { 813 goto failed; 814 } 815 return w; 816 } 817 818 int sldns_wire2str_rdata_unknown_scan(uint8_t** d, size_t* dlen, char** s, 819 size_t* slen) 820 { 821 int w = 0; 822 823 /* print length */ 824 w += sldns_str_print(s, slen, "\\# %u", (unsigned)*dlen); 825 826 /* print rdlen in hex */ 827 if(*dlen != 0) 828 w += sldns_str_print(s, slen, " "); 829 w += print_hex_buf(s, slen, *d, *dlen); 830 (*d) += *dlen; 831 (*dlen) = 0; 832 return w; 833 } 834 835 /** print and escape one character for a domain dname */ 836 static int dname_char_print(char** s, size_t* slen, uint8_t c) 837 { 838 if(c == '.' || c == ';' || c == '(' || c == ')' || c == '\\') 839 return sldns_str_print(s, slen, "\\%c", c); 840 else if(!(isascii((unsigned char)c) && isgraph((unsigned char)c))) 841 return sldns_str_print(s, slen, "\\%03u", (unsigned)c); 842 /* plain printout */ 843 if(*slen) { 844 **s = (char)c; 845 (*s)++; 846 (*slen)--; 847 } 848 return 1; 849 } 850 851 int sldns_wire2str_dname_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen, 852 uint8_t* pkt, size_t pktlen, int* comprloop) 853 { 854 int w = 0; 855 /* spool labels onto the string, use compression if its there */ 856 uint8_t* pos = *d; 857 unsigned i, counter=0; 858 unsigned maxcompr = MAX_COMPRESS_PTRS; /* loop detection, max compr ptrs */ 859 int in_buf = 1; 860 size_t dname_len = 0; 861 if(comprloop) { 862 if(*comprloop != 0) 863 maxcompr = 30; /* for like ipv6 reverse name, per label */ 864 if(*comprloop > 4) 865 maxcompr = 4; /* just don't want to spend time, any more */ 866 } 867 if(*dlen == 0) return sldns_str_print(s, slen, "ErrorMissingDname"); 868 if(*pos == 0) { 869 (*d)++; 870 (*dlen)--; 871 return sldns_str_print(s, slen, "."); 872 } 873 while((!pkt || pos < pkt+pktlen) && *pos) { 874 /* read label length */ 875 uint8_t labellen = *pos++; 876 if(in_buf) { (*d)++; (*dlen)--; } 877 878 /* find out what sort of label we have */ 879 if((labellen&0xc0) == 0xc0) { 880 /* compressed */ 881 uint16_t target = 0; 882 if(in_buf && *dlen == 0) 883 return w + sldns_str_print(s, slen, 884 "ErrorPartialDname"); 885 else if(!in_buf && pos+1 > pkt+pktlen) 886 return w + sldns_str_print(s, slen, 887 "ErrorPartialDname"); 888 target = ((labellen&0x3f)<<8) | *pos; 889 if(in_buf) { (*d)++; (*dlen)--; } 890 /* move to target, if possible */ 891 if(!pkt || target >= pktlen) 892 return w + sldns_str_print(s, slen, 893 "ErrorComprPtrOutOfBounds"); 894 if(counter++ > maxcompr) { 895 if(comprloop && *comprloop < 10) 896 (*comprloop)++; 897 return w + sldns_str_print(s, slen, 898 "ErrorComprPtrLooped"); 899 } 900 in_buf = 0; 901 pos = pkt+target; 902 continue; 903 } else if((labellen&0xc0)) { 904 /* notimpl label type */ 905 w += sldns_str_print(s, slen, 906 "ErrorLABELTYPE%xIsUnknown", 907 (int)(labellen&0xc0)); 908 return w; 909 } 910 911 /* spool label characters, end with '.' */ 912 if(in_buf && *dlen < (size_t)labellen) 913 labellen = (uint8_t)*dlen; 914 else if(!in_buf && pos+(size_t)labellen > pkt+pktlen) 915 labellen = (uint8_t)(pkt + pktlen - pos); 916 dname_len += ((size_t)labellen)+1; 917 if(dname_len > LDNS_MAX_DOMAINLEN) { 918 /* dname_len counts the uncompressed length we have 919 * seen so far, and the domain name has become too 920 * long, prevent the loop from printing overly long 921 * content. */ 922 w += sldns_str_print(s, slen, 923 "ErrorDomainNameTooLong"); 924 return w; 925 } 926 for(i=0; i<(unsigned)labellen; i++) { 927 w += dname_char_print(s, slen, *pos++); 928 } 929 if(in_buf) { 930 (*d) += labellen; 931 (*dlen) -= labellen; 932 if(*dlen == 0) break; 933 } 934 w += sldns_str_print(s, slen, "."); 935 } 936 /* skip over final root label */ 937 if(in_buf && *dlen > 0) { (*d)++; (*dlen)--; } 938 /* in case we printed no labels, terminate dname */ 939 if(w == 0) w += sldns_str_print(s, slen, "."); 940 return w; 941 } 942 943 int sldns_wire2str_opcode_print(char** s, size_t* slen, int opcode) 944 { 945 sldns_lookup_table *lt = sldns_lookup_by_id(sldns_opcodes, opcode); 946 if (lt && lt->name) { 947 return sldns_str_print(s, slen, "%s", lt->name); 948 } 949 return sldns_str_print(s, slen, "OPCODE%u", (unsigned)opcode); 950 } 951 952 int sldns_wire2str_rcode_print(char** s, size_t* slen, int rcode) 953 { 954 sldns_lookup_table *lt = sldns_lookup_by_id(sldns_rcodes, rcode); 955 if (lt && lt->name) { 956 return sldns_str_print(s, slen, "%s", lt->name); 957 } 958 return sldns_str_print(s, slen, "RCODE%u", (unsigned)rcode); 959 } 960 961 int sldns_wire2str_class_print(char** s, size_t* slen, uint16_t rrclass) 962 { 963 sldns_lookup_table *lt = sldns_lookup_by_id(sldns_rr_classes, 964 (int)rrclass); 965 if (lt && lt->name) { 966 return sldns_str_print(s, slen, "%s", lt->name); 967 } 968 return sldns_str_print(s, slen, "CLASS%u", (unsigned)rrclass); 969 } 970 971 int sldns_wire2str_type_print(char** s, size_t* slen, uint16_t rrtype) 972 { 973 const sldns_rr_descriptor *descriptor = sldns_rr_descript(rrtype); 974 if (descriptor && descriptor->_name) { 975 return sldns_str_print(s, slen, "%s", descriptor->_name); 976 } 977 return sldns_str_print(s, slen, "TYPE%u", (unsigned)rrtype); 978 } 979 980 int sldns_wire2str_edns_option_code_print(char** s, size_t* slen, 981 uint16_t opcode) 982 { 983 sldns_lookup_table *lt = sldns_lookup_by_id(sldns_edns_options, 984 (int)opcode); 985 if (lt && lt->name) { 986 return sldns_str_print(s, slen, "%s", lt->name); 987 } 988 return sldns_str_print(s, slen, "OPT%u", (unsigned)opcode); 989 } 990 991 int sldns_wire2str_class_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen) 992 { 993 uint16_t c; 994 if(*dlen == 0) return 0; 995 if(*dlen < 2) return print_remainder_hex("Error malformed 0x", d, dlen, s, slen); 996 c = sldns_read_uint16(*d); 997 (*d)+=2; 998 (*dlen)-=2; 999 return sldns_wire2str_class_print(s, slen, c); 1000 } 1001 1002 int sldns_wire2str_type_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen) 1003 { 1004 uint16_t t; 1005 if(*dlen == 0) return 0; 1006 if(*dlen < 2) return print_remainder_hex("Error malformed 0x", d, dlen, s, slen); 1007 t = sldns_read_uint16(*d); 1008 (*d)+=2; 1009 (*dlen)-=2; 1010 return sldns_wire2str_type_print(s, slen, t); 1011 } 1012 1013 int sldns_wire2str_ttl_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen) 1014 { 1015 uint32_t ttl; 1016 if(*dlen == 0) return 0; 1017 if(*dlen < 4) return print_remainder_hex("Error malformed 0x", d, dlen, s, slen); 1018 ttl = sldns_read_uint32(*d); 1019 (*d)+=4; 1020 (*dlen)-=4; 1021 return sldns_str_print(s, slen, "%u", (unsigned)ttl); 1022 } 1023 1024 static int 1025 sldns_print_svcparamkey(char** s, size_t* slen, uint16_t svcparamkey) 1026 { 1027 if (svcparamkey < SVCPARAMKEY_COUNT) { 1028 return sldns_str_print(s, slen, "%s", svcparamkey_strs[svcparamkey]); 1029 } 1030 else { 1031 return sldns_str_print(s, slen, "key%d", (int)svcparamkey); 1032 } 1033 } 1034 1035 static int sldns_wire2str_svcparam_port2str(char** s, 1036 size_t* slen, uint16_t data_len, uint8_t* data) 1037 { 1038 int w = 0; 1039 1040 if (data_len != 2) 1041 return -1; /* wireformat error, a short is 2 bytes */ 1042 w = sldns_str_print(s, slen, "=%d", (int)sldns_read_uint16(data)); 1043 1044 return w; 1045 } 1046 1047 static int sldns_wire2str_svcparam_ipv4hint2str(char** s, 1048 size_t* slen, uint16_t data_len, uint8_t* data) 1049 { 1050 char ip_str[INET_ADDRSTRLEN + 1]; 1051 1052 int w = 0; 1053 1054 assert(data_len > 0); 1055 1056 if ((data_len % LDNS_IP4ADDRLEN) == 0) { 1057 if (inet_ntop(AF_INET, data, ip_str, sizeof(ip_str)) == NULL) 1058 return -1; /* wireformat error, incorrect size or inet family */ 1059 1060 w += sldns_str_print(s, slen, "=%s", ip_str); 1061 data += LDNS_IP4ADDRLEN; 1062 1063 while ((data_len -= LDNS_IP4ADDRLEN) > 0) { 1064 if (inet_ntop(AF_INET, data, ip_str, sizeof(ip_str)) == NULL) 1065 return -1; /* wireformat error, incorrect size or inet family */ 1066 1067 w += sldns_str_print(s, slen, ",%s", ip_str); 1068 data += LDNS_IP4ADDRLEN; 1069 } 1070 } else 1071 return -1; 1072 1073 return w; 1074 } 1075 1076 static int sldns_wire2str_svcparam_ipv6hint2str(char** s, 1077 size_t* slen, uint16_t data_len, uint8_t* data) 1078 { 1079 char ip_str[INET6_ADDRSTRLEN + 1]; 1080 1081 int w = 0; 1082 1083 assert(data_len > 0); 1084 1085 if ((data_len % LDNS_IP6ADDRLEN) == 0) { 1086 if (inet_ntop(AF_INET6, data, ip_str, sizeof(ip_str)) == NULL) 1087 return -1; /* wireformat error, incorrect size or inet family */ 1088 1089 w += sldns_str_print(s, slen, "=%s", ip_str); 1090 data += LDNS_IP6ADDRLEN; 1091 1092 while ((data_len -= LDNS_IP6ADDRLEN) > 0) { 1093 if (inet_ntop(AF_INET6, data, ip_str, sizeof(ip_str)) == NULL) 1094 return -1; /* wireformat error, incorrect size or inet family */ 1095 1096 w += sldns_str_print(s, slen, ",%s", ip_str); 1097 data += LDNS_IP6ADDRLEN; 1098 } 1099 } else 1100 return -1; 1101 1102 return w; 1103 } 1104 1105 static int sldns_wire2str_svcparam_mandatory2str(char** s, 1106 size_t* slen, uint16_t data_len, uint8_t* data) 1107 { 1108 int w = 0; 1109 1110 assert(data_len > 0); 1111 1112 if (data_len % sizeof(uint16_t)) 1113 return -1; /* wireformat error, data_len must be multiple of shorts */ 1114 w += sldns_str_print(s, slen, "="); 1115 w += sldns_print_svcparamkey(s, slen, sldns_read_uint16(data)); 1116 data += 2; 1117 1118 while ((data_len -= sizeof(uint16_t))) { 1119 w += sldns_str_print(s, slen, ","); 1120 w += sldns_print_svcparamkey(s, slen, sldns_read_uint16(data)); 1121 data += 2; 1122 } 1123 1124 return w; 1125 } 1126 1127 static int sldns_wire2str_svcparam_alpn2str(char** s, 1128 size_t* slen, uint16_t data_len, uint8_t* data) 1129 { 1130 uint8_t *dp = (void *)data; 1131 int w = 0; 1132 1133 assert(data_len > 0); /* Guaranteed by sldns_wire2str_svcparam_scan */ 1134 1135 w += sldns_str_print(s, slen, "=\""); 1136 while (data_len) { 1137 /* alpn is list of length byte (str_len) followed by a string of that size */ 1138 uint8_t i, str_len = *dp++; 1139 1140 if (str_len > --data_len) 1141 return -1; 1142 1143 for (i = 0; i < str_len; i++) { 1144 if (dp[i] == '"' || dp[i] == '\\') 1145 w += sldns_str_print(s, slen, "\\\\\\%c", dp[i]); 1146 1147 else if (dp[i] == ',') 1148 w += sldns_str_print(s, slen, "\\\\%c", dp[i]); 1149 1150 else if (!isprint(dp[i])) 1151 w += sldns_str_print(s, slen, "\\%03u", (unsigned) dp[i]); 1152 1153 else 1154 w += sldns_str_print(s, slen, "%c", dp[i]); 1155 } 1156 dp += str_len; 1157 if ((data_len -= str_len)) 1158 w += sldns_str_print(s, slen, "%s", ","); 1159 } 1160 w += sldns_str_print(s, slen, "\""); 1161 1162 return w; 1163 } 1164 1165 static int sldns_wire2str_svcparam_ech2str(char** s, 1166 size_t* slen, uint16_t data_len, uint8_t* data) 1167 { 1168 int size; 1169 int w = 0; 1170 1171 assert(data_len > 0); /* Guaranteed by sldns_wire2str_svcparam_scan */ 1172 1173 w += sldns_str_print(s, slen, "=\""); 1174 1175 if ((size = sldns_b64_ntop(data, data_len, *s, *slen)) < 0) 1176 return -1; 1177 1178 (*s) += size; 1179 (*slen) -= size; 1180 1181 w += sldns_str_print(s, slen, "\""); 1182 1183 return w + size; 1184 } 1185 1186 int sldns_wire2str_svcparam_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen) 1187 { 1188 uint8_t ch; 1189 uint16_t svcparamkey, data_len; 1190 int written_chars = 0; 1191 int r, i; 1192 1193 /* verify that we have enough data to read svcparamkey and data_len */ 1194 if(*dlen < 4) 1195 return -1; 1196 1197 svcparamkey = sldns_read_uint16(*d); 1198 data_len = sldns_read_uint16(*d+2); 1199 *d += 4; 1200 *dlen -= 4; 1201 1202 /* verify that we have data_len data */ 1203 if (data_len > *dlen) 1204 return -1; 1205 1206 written_chars += sldns_print_svcparamkey(s, slen, svcparamkey); 1207 if (!data_len) { 1208 1209 /* Some SvcParams MUST have values */ 1210 switch (svcparamkey) { 1211 case SVCB_KEY_ALPN: 1212 case SVCB_KEY_PORT: 1213 case SVCB_KEY_IPV4HINT: 1214 case SVCB_KEY_IPV6HINT: 1215 case SVCB_KEY_MANDATORY: 1216 case SVCB_KEY_DOHPATH: 1217 return -1; 1218 default: 1219 return written_chars; 1220 } 1221 } 1222 1223 switch (svcparamkey) { 1224 case SVCB_KEY_PORT: 1225 r = sldns_wire2str_svcparam_port2str(s, slen, data_len, *d); 1226 break; 1227 case SVCB_KEY_IPV4HINT: 1228 r = sldns_wire2str_svcparam_ipv4hint2str(s, slen, data_len, *d); 1229 break; 1230 case SVCB_KEY_IPV6HINT: 1231 r = sldns_wire2str_svcparam_ipv6hint2str(s, slen, data_len, *d); 1232 break; 1233 case SVCB_KEY_MANDATORY: 1234 r = sldns_wire2str_svcparam_mandatory2str(s, slen, data_len, *d); 1235 break; 1236 case SVCB_KEY_NO_DEFAULT_ALPN: 1237 return -1; /* wireformat error, should not have a value */ 1238 case SVCB_KEY_ALPN: 1239 r = sldns_wire2str_svcparam_alpn2str(s, slen, data_len, *d); 1240 break; 1241 case SVCB_KEY_ECH: 1242 r = sldns_wire2str_svcparam_ech2str(s, slen, data_len, *d); 1243 break; 1244 case SVCB_KEY_DOHPATH: 1245 ATTR_FALLTHROUGH 1246 /* fallthrough */ 1247 default: 1248 r = sldns_str_print(s, slen, "=\""); 1249 1250 for (i = 0; i < data_len; i++) { 1251 ch = (*d)[i]; 1252 1253 if (ch == '"' || ch == '\\') 1254 r += sldns_str_print(s, slen, "\\%c", ch); 1255 1256 else if (!isprint(ch)) 1257 r += sldns_str_print(s, slen, "\\%03u", (unsigned) ch); 1258 1259 else 1260 r += sldns_str_print(s, slen, "%c", ch); 1261 1262 } 1263 r += sldns_str_print(s, slen, "\""); 1264 break; 1265 } 1266 if (r <= 0) 1267 return -1; /* wireformat error */ 1268 1269 written_chars += r; 1270 *d += data_len; 1271 *dlen -= data_len; 1272 return written_chars; 1273 } 1274 1275 int sldns_wire2str_rdf_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen, 1276 int rdftype, uint8_t* pkt, size_t pktlen, int* comprloop) 1277 { 1278 if(*dlen == 0) return 0; 1279 switch(rdftype) { 1280 case LDNS_RDF_TYPE_NONE: 1281 return 0; 1282 case LDNS_RDF_TYPE_DNAME: 1283 return sldns_wire2str_dname_scan(d, dlen, s, slen, pkt, pktlen, comprloop); 1284 case LDNS_RDF_TYPE_INT8: 1285 return sldns_wire2str_int8_scan(d, dlen, s, slen); 1286 case LDNS_RDF_TYPE_INT16: 1287 return sldns_wire2str_int16_scan(d, dlen, s, slen); 1288 case LDNS_RDF_TYPE_INT32: 1289 return sldns_wire2str_int32_scan(d, dlen, s, slen); 1290 case LDNS_RDF_TYPE_PERIOD: 1291 return sldns_wire2str_period_scan(d, dlen, s, slen); 1292 case LDNS_RDF_TYPE_TSIGTIME: 1293 return sldns_wire2str_tsigtime_scan(d, dlen, s, slen); 1294 case LDNS_RDF_TYPE_A: 1295 return sldns_wire2str_a_scan(d, dlen, s, slen); 1296 case LDNS_RDF_TYPE_AAAA: 1297 return sldns_wire2str_aaaa_scan(d, dlen, s, slen); 1298 case LDNS_RDF_TYPE_STR: 1299 return sldns_wire2str_str_scan(d, dlen, s, slen); 1300 case LDNS_RDF_TYPE_APL: 1301 return sldns_wire2str_apl_scan(d, dlen, s, slen); 1302 case LDNS_RDF_TYPE_B32_EXT: 1303 return sldns_wire2str_b32_ext_scan(d, dlen, s, slen); 1304 case LDNS_RDF_TYPE_B64: 1305 return sldns_wire2str_b64_scan(d, dlen, s, slen); 1306 case LDNS_RDF_TYPE_HEX: 1307 return sldns_wire2str_hex_scan(d, dlen, s, slen); 1308 case LDNS_RDF_TYPE_NSEC: 1309 return sldns_wire2str_nsec_scan(d, dlen, s, slen); 1310 case LDNS_RDF_TYPE_NSEC3_SALT: 1311 return sldns_wire2str_nsec3_salt_scan(d, dlen, s, slen); 1312 case LDNS_RDF_TYPE_TYPE: 1313 return sldns_wire2str_type_scan(d, dlen, s, slen); 1314 case LDNS_RDF_TYPE_CLASS: 1315 return sldns_wire2str_class_scan(d, dlen, s, slen); 1316 case LDNS_RDF_TYPE_CERT_ALG: 1317 return sldns_wire2str_cert_alg_scan(d, dlen, s, slen); 1318 case LDNS_RDF_TYPE_ALG: 1319 return sldns_wire2str_alg_scan(d, dlen, s, slen); 1320 case LDNS_RDF_TYPE_UNKNOWN: 1321 return sldns_wire2str_unknown_scan(d, dlen, s, slen); 1322 case LDNS_RDF_TYPE_TIME: 1323 return sldns_wire2str_time_scan(d, dlen, s, slen); 1324 case LDNS_RDF_TYPE_LOC: 1325 return sldns_wire2str_loc_scan(d, dlen, s, slen); 1326 case LDNS_RDF_TYPE_WKS: 1327 case LDNS_RDF_TYPE_SERVICE: 1328 return sldns_wire2str_wks_scan(d, dlen, s, slen); 1329 case LDNS_RDF_TYPE_NSAP: 1330 return sldns_wire2str_nsap_scan(d, dlen, s, slen); 1331 case LDNS_RDF_TYPE_ATMA: 1332 return sldns_wire2str_atma_scan(d, dlen, s, slen); 1333 case LDNS_RDF_TYPE_IPSECKEY: 1334 return sldns_wire2str_ipseckey_scan(d, dlen, s, slen, pkt, 1335 pktlen, comprloop); 1336 case LDNS_RDF_TYPE_HIP: 1337 return sldns_wire2str_hip_scan(d, dlen, s, slen); 1338 case LDNS_RDF_TYPE_INT16_DATA: 1339 return sldns_wire2str_int16_data_scan(d, dlen, s, slen); 1340 case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER: 1341 return sldns_wire2str_b32_ext_scan(d, dlen, s, slen); 1342 case LDNS_RDF_TYPE_ILNP64: 1343 return sldns_wire2str_ilnp64_scan(d, dlen, s, slen); 1344 case LDNS_RDF_TYPE_EUI48: 1345 return sldns_wire2str_eui48_scan(d, dlen, s, slen); 1346 case LDNS_RDF_TYPE_EUI64: 1347 return sldns_wire2str_eui64_scan(d, dlen, s, slen); 1348 case LDNS_RDF_TYPE_UNQUOTED: 1349 return sldns_wire2str_unquoted_scan(d, dlen, s, slen); 1350 case LDNS_RDF_TYPE_TAG: 1351 return sldns_wire2str_tag_scan(d, dlen, s, slen); 1352 case LDNS_RDF_TYPE_LONG_STR: 1353 return sldns_wire2str_long_str_scan(d, dlen, s, slen); 1354 case LDNS_RDF_TYPE_SVCPARAM: 1355 return sldns_wire2str_svcparam_scan(d, dlen, s, slen); 1356 case LDNS_RDF_TYPE_TSIGERROR: 1357 return sldns_wire2str_tsigerror_scan(d, dlen, s, slen); 1358 } 1359 /* unknown rdf type */ 1360 return -1; 1361 } 1362 1363 int sldns_wire2str_int8_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1364 { 1365 int w; 1366 if(*dl < 1) return -1; 1367 w = sldns_str_print(s, sl, "%u", (unsigned)**d); 1368 (*d)++; 1369 (*dl)--; 1370 return w; 1371 } 1372 1373 int sldns_wire2str_int16_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1374 { 1375 int w; 1376 if(*dl < 2) return -1; 1377 w = sldns_str_print(s, sl, "%lu", (unsigned long)sldns_read_uint16(*d)); 1378 (*d)+=2; 1379 (*dl)-=2; 1380 return w; 1381 } 1382 1383 int sldns_wire2str_int32_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1384 { 1385 int w; 1386 if(*dl < 4) return -1; 1387 w = sldns_str_print(s, sl, "%lu", (unsigned long)sldns_read_uint32(*d)); 1388 (*d)+=4; 1389 (*dl)-=4; 1390 return w; 1391 } 1392 1393 int sldns_wire2str_period_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1394 { 1395 int w; 1396 if(*dl < 4) return -1; 1397 w = sldns_str_print(s, sl, "%u", (unsigned)sldns_read_uint32(*d)); 1398 (*d)+=4; 1399 (*dl)-=4; 1400 return w; 1401 } 1402 1403 int sldns_wire2str_tsigtime_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1404 { 1405 /* tsigtime is 48 bits network order unsigned integer */ 1406 int w; 1407 uint64_t tsigtime = 0; 1408 uint64_t d0, d1, d2, d3, d4, d5; 1409 if(*dl < 6) return -1; 1410 d0 = (*d)[0]; /* cast to uint64 for shift operations */ 1411 d1 = (*d)[1]; 1412 d2 = (*d)[2]; 1413 d3 = (*d)[3]; 1414 d4 = (*d)[4]; 1415 d5 = (*d)[5]; 1416 tsigtime = (d0<<40) | (d1<<32) | (d2<<24) | (d3<<16) | (d4<<8) | d5; 1417 #ifndef USE_WINSOCK 1418 w = sldns_str_print(s, sl, "%llu", (long long)tsigtime); 1419 #else 1420 w = sldns_str_print(s, sl, "%I64u", (long long)tsigtime); 1421 #endif 1422 (*d)+=6; 1423 (*dl)-=6; 1424 return w; 1425 } 1426 1427 int sldns_wire2str_a_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1428 { 1429 char buf[32]; 1430 int w; 1431 if(*dl < 4) return -1; 1432 if(!inet_ntop(AF_INET, *d, buf, (socklen_t)sizeof(buf))) 1433 return -1; 1434 w = sldns_str_print(s, sl, "%s", buf); 1435 (*d)+=4; 1436 (*dl)-=4; 1437 return w; 1438 } 1439 1440 int sldns_wire2str_aaaa_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1441 { 1442 #ifdef AF_INET6 1443 char buf[64]; 1444 int w; 1445 if(*dl < 16) return -1; 1446 if(!inet_ntop(AF_INET6, *d, buf, (socklen_t)sizeof(buf))) 1447 return -1; 1448 w = sldns_str_print(s, sl, "%s", buf); 1449 (*d)+=16; 1450 (*dl)-=16; 1451 return w; 1452 #else 1453 return -1; 1454 #endif 1455 } 1456 1457 /** printout escaped TYPE_STR character */ 1458 static int str_char_print(char** s, size_t* sl, uint8_t c) 1459 { 1460 if(isprint((unsigned char)c) || c == '\t') { 1461 if(c == '\"' || c == '\\') 1462 return sldns_str_print(s, sl, "\\%c", c); 1463 if(*sl) { 1464 **s = (char)c; 1465 (*s)++; 1466 (*sl)--; 1467 } 1468 return 1; 1469 } 1470 return sldns_str_print(s, sl, "\\%03u", (unsigned)c); 1471 } 1472 1473 int sldns_wire2str_str_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1474 { 1475 int w = 0; 1476 size_t i, len; 1477 if(*dl < 1) return -1; 1478 len = **d; 1479 if(*dl < 1+len) return -1; 1480 (*d)++; 1481 (*dl)--; 1482 w += sldns_str_print(s, sl, "\""); 1483 for(i=0; i<len; i++) 1484 w += str_char_print(s, sl, (*d)[i]); 1485 w += sldns_str_print(s, sl, "\""); 1486 (*d)+=len; 1487 (*dl)-=len; 1488 return w; 1489 } 1490 1491 int sldns_wire2str_apl_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1492 { 1493 int i, w = 0; 1494 uint16_t family; 1495 uint8_t negation, prefix, adflength; 1496 if(*dl < 4) return -1; 1497 family = sldns_read_uint16(*d); 1498 prefix = (*d)[2]; 1499 negation = ((*d)[3] & LDNS_APL_NEGATION); 1500 adflength = ((*d)[3] & LDNS_APL_MASK); 1501 if(*dl < 4+(size_t)adflength) return -1; 1502 if(family != LDNS_APL_IP4 && family != LDNS_APL_IP6) 1503 return -1; /* unknown address family */ 1504 if(negation) 1505 w += sldns_str_print(s, sl, "!"); 1506 w += sldns_str_print(s, sl, "%u:", (unsigned)family); 1507 if(family == LDNS_APL_IP4) { 1508 /* check if prefix <32 ? */ 1509 /* address is variable length 0 - 4 */ 1510 for(i=0; i<4; i++) { 1511 if(i > 0) 1512 w += sldns_str_print(s, sl, "."); 1513 if(i < (int)adflength) 1514 w += sldns_str_print(s, sl, "%d", (*d)[4+i]); 1515 else w += sldns_str_print(s, sl, "0"); 1516 } 1517 } else if(family == LDNS_APL_IP6) { 1518 /* check if prefix <128 ? */ 1519 /* address is variable length 0 - 16 */ 1520 for(i=0; i<16; i++) { 1521 if(i%2 == 0 && i>0) 1522 w += sldns_str_print(s, sl, ":"); 1523 if(i < (int)adflength) 1524 w += sldns_str_print(s, sl, "%02x", (*d)[4+i]); 1525 else w += sldns_str_print(s, sl, "00"); 1526 } 1527 } 1528 w += sldns_str_print(s, sl, "/%u", (unsigned)prefix); 1529 (*d) += 4+adflength; 1530 (*dl) -= 4+adflength; 1531 return w; 1532 } 1533 1534 int sldns_wire2str_b32_ext_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1535 { 1536 size_t datalen; 1537 size_t sz; 1538 if(*dl < 1) return -1; 1539 datalen = (*d)[0]; 1540 if(*dl < 1+datalen) return -1; 1541 sz = sldns_b32_ntop_calculate_size(datalen); 1542 if(*sl < sz+1) { 1543 (*d) += datalen+1; 1544 (*dl) -= (datalen+1); 1545 return (int)sz; /* out of space really, but would need buffer 1546 in order to truncate the output */ 1547 } 1548 sldns_b32_ntop_extended_hex((*d)+1, datalen, *s, *sl); 1549 (*d) += datalen+1; 1550 (*dl) -= (datalen+1); 1551 (*s) += sz; 1552 (*sl) -= sz; 1553 return (int)sz; 1554 } 1555 1556 /** scan number of bytes from wire into b64 presentation format */ 1557 static int sldns_wire2str_b64_scan_num(uint8_t** d, size_t* dl, char** s, 1558 size_t* sl, size_t num) 1559 { 1560 /* b64_ntop_calculate size includes null at the end */ 1561 size_t sz = sldns_b64_ntop_calculate_size(num)-1; 1562 if(*sl < sz+1) { 1563 (*d) += num; 1564 (*dl) -= num; 1565 return (int)sz; /* out of space really, but would need buffer 1566 in order to truncate the output */ 1567 } 1568 sldns_b64_ntop(*d, num, *s, *sl); 1569 (*d) += num; 1570 (*dl) -= num; 1571 (*s) += sz; 1572 (*sl) -= sz; 1573 return (int)sz; 1574 } 1575 1576 int sldns_wire2str_b64_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1577 { 1578 if(*dl == 0) { 1579 return sldns_str_print(s, sl, "0"); 1580 } 1581 return sldns_wire2str_b64_scan_num(d, dl, s, sl, *dl); 1582 } 1583 1584 int sldns_wire2str_hex_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1585 { 1586 if(*dl == 0) { 1587 return sldns_str_print(s, sl, "0"); 1588 } 1589 return print_remainder_hex("", d, dl, s, sl); 1590 } 1591 1592 int sldns_wire2str_nsec_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1593 { 1594 uint8_t* p = *d; 1595 size_t pl = *dl; 1596 unsigned i, bit, window, block_len; 1597 uint16_t t; 1598 int w = 0; 1599 1600 /* check for errors */ 1601 while(pl) { 1602 if(pl < 2) return -1; 1603 block_len = (unsigned)p[1]; 1604 if(pl < 2+block_len) return -1; 1605 p += block_len+2; 1606 pl -= block_len+2; 1607 } 1608 1609 /* do it */ 1610 p = *d; 1611 pl = *dl; 1612 while(pl) { 1613 if(pl < 2) return -1; /* cannot happen */ 1614 window = (unsigned)p[0]; 1615 block_len = (unsigned)p[1]; 1616 if(pl < 2+block_len) return -1; /* cannot happen */ 1617 p += 2; 1618 for(i=0; i<block_len; i++) { 1619 if(p[i] == 0) continue; 1620 /* base type number for this octet */ 1621 t = ((window)<<8) | (i << 3); 1622 for(bit=0; bit<8; bit++) { 1623 if((p[i]&(0x80>>bit))) { 1624 if(w) w += sldns_str_print(s, sl, " "); 1625 w += sldns_wire2str_type_print(s, sl, 1626 t+bit); 1627 } 1628 } 1629 } 1630 p += block_len; 1631 pl -= block_len+2; 1632 } 1633 (*d) += *dl; 1634 (*dl) = 0; 1635 return w; 1636 } 1637 1638 int sldns_wire2str_nsec3_salt_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1639 { 1640 size_t salt_len; 1641 int w; 1642 if(*dl < 1) return -1; 1643 salt_len = (size_t)(*d)[0]; 1644 if(*dl < 1+salt_len) return -1; 1645 (*d)++; 1646 (*dl)--; 1647 if(salt_len == 0) { 1648 return sldns_str_print(s, sl, "-"); 1649 } 1650 w = print_hex_buf(s, sl, *d, salt_len); 1651 (*dl)-=salt_len; 1652 (*d)+=salt_len; 1653 return w; 1654 } 1655 1656 int sldns_wire2str_cert_alg_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1657 { 1658 sldns_lookup_table *lt; 1659 int data, w; 1660 if(*dl < 2) return -1; 1661 data = (int)sldns_read_uint16(*d); 1662 lt = sldns_lookup_by_id(sldns_cert_algorithms, data); 1663 if(lt && lt->name) 1664 w = sldns_str_print(s, sl, "%s", lt->name); 1665 else w = sldns_str_print(s, sl, "%d", data); 1666 (*dl)-=2; 1667 (*d)+=2; 1668 return w; 1669 } 1670 1671 int sldns_wire2str_alg_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1672 { 1673 /* don't use algorithm mnemonics in the presentation format 1674 * this kind of got sneaked into the rfc's */ 1675 return sldns_wire2str_int8_scan(d, dl, s, sl); 1676 } 1677 1678 int sldns_wire2str_unknown_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1679 { 1680 return sldns_wire2str_rdata_unknown_scan(d, dl, s, sl); 1681 } 1682 1683 int sldns_wire2str_time_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1684 { 1685 /* create a YYYYMMDDHHMMSS string if possible */ 1686 struct tm tm; 1687 char date_buf[16]; 1688 uint32_t t; 1689 memset(&tm, 0, sizeof(tm)); 1690 if(*dl < 4) return -1; 1691 t = sldns_read_uint32(*d); 1692 date_buf[15]=0; 1693 if(sldns_serial_arithmetics_gmtime_r(t, time(NULL), &tm) && 1694 strftime(date_buf, 15, "%Y%m%d%H%M%S", &tm)) { 1695 (*d) += 4; 1696 (*dl) -= 4; 1697 return sldns_str_print(s, sl, "%s", date_buf); 1698 } 1699 return -1; 1700 } 1701 1702 static int 1703 loc_cm_print(char** str, size_t* sl, uint8_t mantissa, uint8_t exponent) 1704 { 1705 int w = 0; 1706 uint8_t i; 1707 /* is it 0.<two digits> ? */ 1708 if(exponent < 2) { 1709 if(exponent == 1) 1710 mantissa *= 10; 1711 return sldns_str_print(str, sl, "0.%02ld", (long)mantissa); 1712 } 1713 /* always <digit><string of zeros> */ 1714 w += sldns_str_print(str, sl, "%d", (int)mantissa); 1715 for(i=0; i<exponent-2; i++) 1716 w += sldns_str_print(str, sl, "0"); 1717 return w; 1718 } 1719 1720 int sldns_wire2str_loc_scan(uint8_t** d, size_t* dl, char** str, size_t* sl) 1721 { 1722 /* we could do checking (ie degrees < 90 etc)? */ 1723 uint8_t version; 1724 uint8_t size; 1725 uint8_t horizontal_precision; 1726 uint8_t vertical_precision; 1727 uint32_t longitude; 1728 uint32_t latitude; 1729 uint32_t altitude; 1730 char northerness; 1731 char easterness; 1732 uint32_t h; 1733 uint32_t m; 1734 double s; 1735 uint32_t equator = (uint32_t)1 << 31; /* 2**31 */ 1736 int w = 0; 1737 1738 if(*dl < 16) return -1; 1739 version = (*d)[0]; 1740 if(version != 0) 1741 return sldns_wire2str_hex_scan(d, dl, str, sl); 1742 size = (*d)[1]; 1743 horizontal_precision = (*d)[2]; 1744 vertical_precision = (*d)[3]; 1745 1746 latitude = sldns_read_uint32((*d)+4); 1747 longitude = sldns_read_uint32((*d)+8); 1748 altitude = sldns_read_uint32((*d)+12); 1749 1750 if (latitude > equator) { 1751 northerness = 'N'; 1752 latitude = latitude - equator; 1753 } else { 1754 northerness = 'S'; 1755 latitude = equator - latitude; 1756 } 1757 h = latitude / (1000 * 60 * 60); 1758 latitude = latitude % (1000 * 60 * 60); 1759 m = latitude / (1000 * 60); 1760 latitude = latitude % (1000 * 60); 1761 s = (double) latitude / 1000.0; 1762 w += sldns_str_print(str, sl, "%02u %02u %06.3f %c ", 1763 h, m, s, northerness); 1764 1765 if (longitude > equator) { 1766 easterness = 'E'; 1767 longitude = longitude - equator; 1768 } else { 1769 easterness = 'W'; 1770 longitude = equator - longitude; 1771 } 1772 h = longitude / (1000 * 60 * 60); 1773 longitude = longitude % (1000 * 60 * 60); 1774 m = longitude / (1000 * 60); 1775 longitude = longitude % (1000 * 60); 1776 s = (double) longitude / (1000.0); 1777 w += sldns_str_print(str, sl, "%02u %02u %06.3f %c ", 1778 h, m, s, easterness); 1779 1780 s = ((double) altitude) / 100; 1781 s -= 100000; 1782 1783 if(altitude%100 != 0) 1784 w += sldns_str_print(str, sl, "%.2f", s); 1785 else 1786 w += sldns_str_print(str, sl, "%.0f", s); 1787 1788 w += sldns_str_print(str, sl, "m "); 1789 1790 w += loc_cm_print(str, sl, (size & 0xf0) >> 4, size & 0x0f); 1791 w += sldns_str_print(str, sl, "m "); 1792 1793 w += loc_cm_print(str, sl, (horizontal_precision & 0xf0) >> 4, 1794 horizontal_precision & 0x0f); 1795 w += sldns_str_print(str, sl, "m "); 1796 1797 w += loc_cm_print(str, sl, (vertical_precision & 0xf0) >> 4, 1798 vertical_precision & 0x0f); 1799 w += sldns_str_print(str, sl, "m"); 1800 1801 (*d)+=16; 1802 (*dl)-=16; 1803 return w; 1804 } 1805 1806 int sldns_wire2str_wks_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1807 { 1808 /* protocol, followed by bitmap of services */ 1809 const char* proto_name = NULL; 1810 struct protoent *protocol; 1811 struct servent *service; 1812 uint8_t protocol_nr; 1813 int bit, port, w = 0; 1814 size_t i; 1815 /* we cannot print with strings because they 1816 * are not portable, the presentation format may 1817 * not be able to be read in on another computer. */ 1818 int print_symbols = 0; 1819 1820 /* protocol */ 1821 if(*dl < 1) return -1; 1822 protocol_nr = (*d)[0]; 1823 (*d)++; 1824 (*dl)--; 1825 protocol = getprotobynumber((int)protocol_nr); 1826 if(protocol && (protocol->p_name != NULL)) { 1827 w += sldns_str_print(s, sl, "%s", protocol->p_name); 1828 proto_name = protocol->p_name; 1829 } else if(protocol_nr == 6) { 1830 w += sldns_str_print(s, sl, "tcp"); 1831 } else if(protocol_nr == 17) { 1832 w += sldns_str_print(s, sl, "udp"); 1833 } else { 1834 w += sldns_str_print(s, sl, "%u", (unsigned)protocol_nr); 1835 } 1836 1837 for(i=0; i<*dl; i++) { 1838 if((*d)[i] == 0) 1839 continue; 1840 for(bit=0; bit<8; bit++) { 1841 if(!(((*d)[i])&(0x80>>bit))) 1842 continue; 1843 port = (int)i*8 + bit; 1844 1845 if(!print_symbols) 1846 service = NULL; 1847 else 1848 service = getservbyport( 1849 (int)htons((uint16_t)port), proto_name); 1850 if(service && service->s_name) 1851 w += sldns_str_print(s, sl, " %s", 1852 service->s_name); 1853 else w += sldns_str_print(s, sl, " %u", 1854 (unsigned)port); 1855 } 1856 } 1857 1858 #ifdef HAVE_ENDSERVENT 1859 endservent(); 1860 #endif 1861 #ifdef HAVE_ENDPROTOENT 1862 endprotoent(); 1863 #endif 1864 (*d) += *dl; 1865 (*dl) = 0; 1866 return w; 1867 } 1868 1869 int sldns_wire2str_nsap_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1870 { 1871 return print_remainder_hex("0x", d, dl, s, sl); 1872 } 1873 1874 int sldns_wire2str_atma_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1875 { 1876 uint8_t format; 1877 int w = 0; 1878 size_t i; 1879 1880 if(*dl < 1) return -1; 1881 format = (*d)[0]; 1882 (*d)+=1; 1883 (*dl)-=1; 1884 1885 if(format == 0) { 1886 /* AESA format (ATM End System Address). */ 1887 return print_remainder_hex("", d, dl, s, sl); 1888 } else if(format == 1) { 1889 /* E.164 format. */ 1890 w += sldns_str_print(s, sl, "+"); 1891 for(i=0; i<*dl; i++) { 1892 if((*d)[i] < '0' || (*d)[0] > '9') 1893 return -1; 1894 w += sldns_str_print(s, sl, "%c", (*d)[i]); 1895 } 1896 (*d) += *dl; 1897 (*dl) = 0; 1898 } else { 1899 /* Unknown format. */ 1900 return -1; 1901 } 1902 return w; 1903 } 1904 1905 /* internal scan routine that can modify arguments on failure */ 1906 static int sldns_wire2str_ipseckey_scan_internal(uint8_t** d, size_t* dl, 1907 char** s, size_t* sl, uint8_t* pkt, size_t pktlen, int* comprloop) 1908 { 1909 /* http://www.ietf.org/internet-drafts/draft-ietf-ipseckey-rr-12.txt*/ 1910 uint8_t precedence, gateway_type, algorithm; 1911 int w = 0; 1912 1913 if(*dl < 3) return -1; 1914 precedence = (*d)[0]; 1915 gateway_type = (*d)[1]; 1916 algorithm = (*d)[2]; 1917 if(gateway_type > 3) 1918 return -1; /* unknown */ 1919 (*d)+=3; 1920 (*dl)-=3; 1921 w += sldns_str_print(s, sl, "%d %d %d ", 1922 (int)precedence, (int)gateway_type, (int)algorithm); 1923 1924 switch(gateway_type) { 1925 case 0: /* no gateway */ 1926 w += sldns_str_print(s, sl, "."); 1927 break; 1928 case 1: /* ip4 */ 1929 w += sldns_wire2str_a_scan(d, dl, s, sl); 1930 break; 1931 case 2: /* ip6 */ 1932 w += sldns_wire2str_aaaa_scan(d, dl, s, sl); 1933 break; 1934 case 3: /* dname */ 1935 w += sldns_wire2str_dname_scan(d, dl, s, sl, pkt, pktlen, comprloop); 1936 break; 1937 default: /* unknown */ 1938 return -1; 1939 } 1940 1941 if(*dl < 1) 1942 return -1; 1943 w += sldns_str_print(s, sl, " "); 1944 w += sldns_wire2str_b64_scan_num(d, dl, s, sl, *dl); 1945 return w; 1946 } 1947 1948 int sldns_wire2str_ipseckey_scan(uint8_t** d, size_t* dl, char** s, size_t* sl, 1949 uint8_t* pkt, size_t pktlen, int* comprloop) 1950 { 1951 uint8_t* od = *d; 1952 char* os = *s; 1953 size_t odl = *dl, osl = *sl; 1954 int w=sldns_wire2str_ipseckey_scan_internal(d, dl, s, sl, pkt, pktlen, comprloop); 1955 if(w == -1) { 1956 *d = od; 1957 *s = os; 1958 *dl = odl; 1959 *sl = osl; 1960 return -1; 1961 } 1962 return w; 1963 } 1964 1965 int sldns_wire2str_hip_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1966 { 1967 int w; 1968 uint8_t algo, hitlen; 1969 uint16_t pklen; 1970 1971 /* read lengths */ 1972 if(*dl < 4) 1973 return -1; 1974 hitlen = (*d)[0]; 1975 algo = (*d)[1]; 1976 pklen = sldns_read_uint16((*d)+2); 1977 if(*dl < (size_t)4 + (size_t)hitlen + (size_t)pklen) 1978 return -1; 1979 1980 /* write: algo hit pubkey */ 1981 w = sldns_str_print(s, sl, "%u ", (unsigned)algo); 1982 w += print_hex_buf(s, sl, (*d)+4, hitlen); 1983 w += sldns_str_print(s, sl, " "); 1984 (*d)+=4+hitlen; 1985 (*dl)-= (4+hitlen); 1986 w += sldns_wire2str_b64_scan_num(d, dl, s, sl, pklen); 1987 return w; 1988 } 1989 1990 int sldns_wire2str_int16_data_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1991 { 1992 int w; 1993 uint16_t n; 1994 if(*dl < 2) 1995 return -1; 1996 n = sldns_read_uint16(*d); 1997 if(*dl < 2+(size_t)n) 1998 return -1; 1999 (*d)+=2; 2000 (*dl)-=2; 2001 if(n == 0) { 2002 return sldns_str_print(s, sl, "0"); 2003 } 2004 w = sldns_str_print(s, sl, "%u ", (unsigned)n); 2005 w += sldns_wire2str_b64_scan_num(d, dl, s, sl, n); 2006 return w; 2007 } 2008 2009 int sldns_wire2str_nsec3_next_owner_scan(uint8_t** d, size_t* dl, char** s, 2010 size_t* sl) 2011 { 2012 return sldns_wire2str_b32_ext_scan(d, dl, s, sl); 2013 } 2014 2015 int sldns_wire2str_ilnp64_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 2016 { 2017 int w; 2018 if(*dl < 8) 2019 return -1; 2020 w = sldns_str_print(s, sl, "%.4x:%.4x:%.4x:%.4x", 2021 sldns_read_uint16(*d), sldns_read_uint16((*d)+2), 2022 sldns_read_uint16((*d)+4), sldns_read_uint16((*d)+6)); 2023 (*d)+=8; 2024 (*dl)-=8; 2025 return w; 2026 } 2027 2028 int sldns_wire2str_eui48_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 2029 { 2030 int w; 2031 if(*dl < 6) 2032 return -1; 2033 w = sldns_str_print(s, sl, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", 2034 (*d)[0], (*d)[1], (*d)[2], (*d)[3], (*d)[4], (*d)[5]); 2035 (*d)+=6; 2036 (*dl)-=6; 2037 return w; 2038 } 2039 2040 int sldns_wire2str_eui64_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 2041 { 2042 int w; 2043 if(*dl < 8) 2044 return -1; 2045 w = sldns_str_print(s, sl, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", 2046 (*d)[0], (*d)[1], (*d)[2], (*d)[3], (*d)[4], (*d)[5], 2047 (*d)[6], (*d)[7]); 2048 (*d)+=8; 2049 (*dl)-=8; 2050 return w; 2051 } 2052 2053 int sldns_wire2str_unquoted_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 2054 { 2055 int w = 0; 2056 size_t i, len; 2057 if(*dl < 1) return -1; 2058 len = **d; 2059 if(*dl < 1+len) return -1; 2060 (*d)++; 2061 (*dl)--; 2062 for(i=0; i<len; i++) { 2063 if(isspace((unsigned char)(*d)[i]) || (*d)[i] == '(' || 2064 (*d)[i] == ')' || (*d)[i] == '\'') 2065 w += sldns_str_print(s, sl, "\\%c", (char)(*d)[i]); 2066 else w += str_char_print(s, sl, (*d)[i]); 2067 } 2068 (*d)+=len; 2069 (*dl)-=len; 2070 return w; 2071 } 2072 2073 int sldns_wire2str_tag_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 2074 { 2075 size_t i, n; 2076 int w = 0; 2077 if(*dl < 1) 2078 return -1; 2079 n = (size_t)((*d)[0]); 2080 if(*dl < 1+n) 2081 return -1; 2082 for(i=0; i<n; i++) 2083 if(!isalnum((unsigned char)(*d)[i+1])) 2084 return -1; 2085 for(i=0; i<n; i++) 2086 w += sldns_str_print(s, sl, "%c", (char)(*d)[i+1]); 2087 (*d)+=n+1; 2088 (*dl)-=(n+1); 2089 return w; 2090 } 2091 2092 int sldns_wire2str_long_str_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 2093 { 2094 size_t i; 2095 int w = 0; 2096 w += sldns_str_print(s, sl, "\""); 2097 for(i=0; i<*dl; i++) 2098 w += str_char_print(s, sl, (*d)[i]); 2099 w += sldns_str_print(s, sl, "\""); 2100 (*d)+=*dl; 2101 (*dl)=0; 2102 return w; 2103 } 2104 2105 int sldns_wire2str_tsigerror_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 2106 { 2107 sldns_lookup_table *lt; 2108 int data, w; 2109 if(*dl < 2) return -1; 2110 data = (int)sldns_read_uint16(*d); 2111 lt = sldns_lookup_by_id(sldns_tsig_errors, data); 2112 if(lt && lt->name) 2113 w = sldns_str_print(s, sl, "%s", lt->name); 2114 else w = sldns_str_print(s, sl, "%d", data); 2115 (*dl)-=2; 2116 (*d)+=2; 2117 return w; 2118 } 2119 2120 int sldns_wire2str_edns_llq_print(char** s, size_t* sl, uint8_t* data, 2121 size_t len) 2122 { 2123 /* LLQ constants */ 2124 const char* llq_errors[] = {"NO-ERROR", "SERV-FULL", "STATIC", 2125 "FORMAT-ERR", "NO-SUCH-LLQ", "BAD-VERS", "UNKNOWN_ERR"}; 2126 const unsigned int llq_errors_num = 7; 2127 const char* llq_opcodes[] = {"LLQ-SETUP", "LLQ-REFRESH", "LLQ-EVENT"}; 2128 const unsigned int llq_opcodes_num = 3; 2129 uint16_t version, llq_opcode, error_code; 2130 uint64_t llq_id; 2131 uint32_t lease_life; /* Requested or granted life of LLQ, in seconds */ 2132 int w = 0; 2133 2134 /* read the record */ 2135 if(len != 18) { 2136 w += sldns_str_print(s, sl, "malformed LLQ "); 2137 w += print_hex_buf(s, sl, data, len); 2138 return w; 2139 } 2140 version = sldns_read_uint16(data); 2141 llq_opcode = sldns_read_uint16(data+2); 2142 error_code = sldns_read_uint16(data+4); 2143 memmove(&llq_id, data+6, sizeof(llq_id)); 2144 lease_life = sldns_read_uint32(data+14); 2145 2146 /* print it */ 2147 w += sldns_str_print(s, sl, "v%d ", (int)version); 2148 if(llq_opcode < llq_opcodes_num) 2149 w += sldns_str_print(s, sl, "%s", llq_opcodes[llq_opcode]); 2150 else w += sldns_str_print(s, sl, "opcode %d", (int)llq_opcode); 2151 if(error_code < llq_errors_num) 2152 w += sldns_str_print(s, sl, " %s", llq_errors[error_code]); 2153 else w += sldns_str_print(s, sl, " error %d", (int)error_code); 2154 #ifndef USE_WINSOCK 2155 w += sldns_str_print(s, sl, " id %llx lease-life %lu", 2156 (unsigned long long)llq_id, (unsigned long)lease_life); 2157 #else 2158 w += sldns_str_print(s, sl, " id %I64x lease-life %lu", 2159 (unsigned long long)llq_id, (unsigned long)lease_life); 2160 #endif 2161 return w; 2162 } 2163 2164 int sldns_wire2str_edns_ul_print(char** s, size_t* sl, uint8_t* data, 2165 size_t len) 2166 { 2167 uint32_t lease; 2168 int w = 0; 2169 if(len != 4) { 2170 w += sldns_str_print(s, sl, "malformed UL "); 2171 w += print_hex_buf(s, sl, data, len); 2172 return w; 2173 } 2174 lease = sldns_read_uint32(data); 2175 w += sldns_str_print(s, sl, "lease %lu", (unsigned long)lease); 2176 return w; 2177 } 2178 2179 int sldns_wire2str_edns_nsid_print(char** s, size_t* sl, uint8_t* data, 2180 size_t len) 2181 { 2182 int w = 0; 2183 size_t i, printed=0; 2184 w += print_hex_buf(s, sl, data, len); 2185 for(i=0; i<len; i++) { 2186 if(isprint((unsigned char)data[i]) || data[i] == '\t') { 2187 if(!printed) { 2188 w += sldns_str_print(s, sl, " ("); 2189 printed = 1; 2190 } 2191 w += sldns_str_print(s, sl, "%c", (char)data[i]); 2192 } 2193 } 2194 if(printed) 2195 w += sldns_str_print(s, sl, ")"); 2196 return w; 2197 } 2198 2199 int sldns_wire2str_edns_dau_print(char** s, size_t* sl, uint8_t* data, 2200 size_t len) 2201 { 2202 sldns_lookup_table *lt; 2203 size_t i; 2204 int w = 0; 2205 for(i=0; i<len; i++) { 2206 lt = sldns_lookup_by_id(sldns_algorithms, (int)data[i]); 2207 if(lt && lt->name) 2208 w += sldns_str_print(s, sl, " %s", lt->name); 2209 else w += sldns_str_print(s, sl, " %d", (int)data[i]); 2210 } 2211 return w; 2212 } 2213 2214 int sldns_wire2str_edns_dhu_print(char** s, size_t* sl, uint8_t* data, 2215 size_t len) 2216 { 2217 sldns_lookup_table *lt; 2218 size_t i; 2219 int w = 0; 2220 for(i=0; i<len; i++) { 2221 lt = sldns_lookup_by_id(sldns_hashes, (int)data[i]); 2222 if(lt && lt->name) 2223 w += sldns_str_print(s, sl, " %s", lt->name); 2224 else w += sldns_str_print(s, sl, " %d", (int)data[i]); 2225 } 2226 return w; 2227 } 2228 2229 int sldns_wire2str_edns_n3u_print(char** s, size_t* sl, uint8_t* data, 2230 size_t len) 2231 { 2232 size_t i; 2233 int w = 0; 2234 for(i=0; i<len; i++) { 2235 if(data[i] == 1) 2236 w += sldns_str_print(s, sl, " SHA1"); 2237 else w += sldns_str_print(s, sl, " %d", (int)data[i]); 2238 } 2239 return w; 2240 } 2241 2242 int sldns_wire2str_edns_subnet_print(char** s, size_t* sl, uint8_t* data, 2243 size_t len) 2244 { 2245 int w = 0; 2246 uint16_t family; 2247 uint8_t source, scope; 2248 if(len < 4) { 2249 w += sldns_str_print(s, sl, "malformed subnet "); 2250 w += print_hex_buf(s, sl, data, len); 2251 return w; 2252 } 2253 family = sldns_read_uint16(data); 2254 source = data[2]; 2255 scope = data[3]; 2256 if(family == 1) { 2257 /* IP4 */ 2258 char buf[64]; 2259 uint8_t ip4[4]; 2260 memset(ip4, 0, sizeof(ip4)); 2261 if(len-4 > 4) { 2262 w += sldns_str_print(s, sl, "trailingdata:"); 2263 w += print_hex_buf(s, sl, data+4+4, len-4-4); 2264 w += sldns_str_print(s, sl, " "); 2265 len = 4+4; 2266 } 2267 memmove(ip4, data+4, len-4); 2268 if(!inet_ntop(AF_INET, ip4, buf, (socklen_t)sizeof(buf))) { 2269 w += sldns_str_print(s, sl, "ip4ntoperror "); 2270 w += print_hex_buf(s, sl, data+4+4, len-4-4); 2271 } else { 2272 w += sldns_str_print(s, sl, "%s", buf); 2273 } 2274 } else if(family == 2) { 2275 /* IP6 */ 2276 char buf[64]; 2277 uint8_t ip6[16]; 2278 memset(ip6, 0, sizeof(ip6)); 2279 if(len-4 > 16) { 2280 w += sldns_str_print(s, sl, "trailingdata:"); 2281 w += print_hex_buf(s, sl, data+4+16, len-4-16); 2282 w += sldns_str_print(s, sl, " "); 2283 len = 4+16; 2284 } 2285 memmove(ip6, data+4, len-4); 2286 #ifdef AF_INET6 2287 if(!inet_ntop(AF_INET6, ip6, buf, (socklen_t)sizeof(buf))) { 2288 w += sldns_str_print(s, sl, "ip6ntoperror "); 2289 w += print_hex_buf(s, sl, data+4+4, len-4-4); 2290 } else { 2291 w += sldns_str_print(s, sl, "%s", buf); 2292 } 2293 #else 2294 w += print_hex_buf(s, sl, data+4+4, len-4-4); 2295 #endif 2296 } else { 2297 /* unknown */ 2298 w += sldns_str_print(s, sl, "family %d ", 2299 (int)family); 2300 w += print_hex_buf(s, sl, data, len); 2301 } 2302 w += sldns_str_print(s, sl, "/%d scope /%d", (int)source, (int)scope); 2303 return w; 2304 } 2305 2306 static int sldns_wire2str_edns_keepalive_print(char** s, size_t* sl, 2307 uint8_t* data, size_t len) 2308 { 2309 int w = 0; 2310 uint16_t timeout; 2311 if(!(len == 0 || len == 2)) { 2312 w += sldns_str_print(s, sl, "malformed keepalive "); 2313 w += print_hex_buf(s, sl, data, len); 2314 return w; 2315 } 2316 if(len == 0 ) { 2317 w += sldns_str_print(s, sl, "no timeout value (only valid for client option) "); 2318 } else { 2319 timeout = sldns_read_uint16(data); 2320 w += sldns_str_print(s, sl, "timeout value in units of 100ms %u", (int)timeout); 2321 } 2322 return w; 2323 } 2324 2325 int sldns_wire2str_edns_ede_print(char** s, size_t* sl, 2326 uint8_t* data, size_t len) 2327 { 2328 uint16_t ede_code; 2329 int w = 0; 2330 sldns_lookup_table *lt; 2331 size_t i; 2332 int printable; 2333 2334 if(len < 2) { 2335 w += sldns_str_print(s, sl, "malformed ede "); 2336 w += print_hex_buf(s, sl, data, len); 2337 return w; 2338 } 2339 2340 ede_code = sldns_read_uint16(data); 2341 lt = sldns_lookup_by_id(sldns_edns_ede_codes, (int)ede_code); 2342 if(lt && lt->name) 2343 w += sldns_str_print(s, sl, "%s", lt->name); 2344 else w += sldns_str_print(s, sl, "%d", (int)ede_code); 2345 2346 if(len == 2) 2347 return w; 2348 2349 w += sldns_str_print(s, sl, " "); 2350 2351 /* If it looks like text, show it as text. */ 2352 printable=1; 2353 for(i=2; i<len; i++) { 2354 if(isprint((unsigned char)data[i]) || data[i] == '\t') 2355 continue; 2356 printable = 0; 2357 break; 2358 } 2359 if(printable) { 2360 w += sldns_str_print(s, sl, "\""); 2361 for(i=2; i<len; i++) { 2362 w += str_char_print(s, sl, data[i]); 2363 } 2364 w += sldns_str_print(s, sl, "\""); 2365 } else { 2366 w += print_hex_buf(s, sl, data+2, len-2); 2367 } 2368 return w; 2369 } 2370 2371 int sldns_wire2str_edns_option_print(char** s, size_t* sl, 2372 uint16_t option_code, uint8_t* optdata, size_t optlen) 2373 { 2374 int w = 0; 2375 w += sldns_wire2str_edns_option_code_print(s, sl, option_code); 2376 w += sldns_str_print(s, sl, ": "); 2377 switch(option_code) { 2378 case LDNS_EDNS_LLQ: 2379 w += sldns_wire2str_edns_llq_print(s, sl, optdata, optlen); 2380 break; 2381 case LDNS_EDNS_UL: 2382 w += sldns_wire2str_edns_ul_print(s, sl, optdata, optlen); 2383 break; 2384 case LDNS_EDNS_NSID: 2385 w += sldns_wire2str_edns_nsid_print(s, sl, optdata, optlen); 2386 break; 2387 case LDNS_EDNS_DAU: 2388 w += sldns_wire2str_edns_dau_print(s, sl, optdata, optlen); 2389 break; 2390 case LDNS_EDNS_DHU: 2391 w += sldns_wire2str_edns_dhu_print(s, sl, optdata, optlen); 2392 break; 2393 case LDNS_EDNS_N3U: 2394 w += sldns_wire2str_edns_n3u_print(s, sl, optdata, optlen); 2395 break; 2396 case LDNS_EDNS_CLIENT_SUBNET: 2397 w += sldns_wire2str_edns_subnet_print(s, sl, optdata, optlen); 2398 break; 2399 case LDNS_EDNS_KEEPALIVE: 2400 w += sldns_wire2str_edns_keepalive_print(s, sl, optdata, optlen); 2401 break; 2402 case LDNS_EDNS_PADDING: 2403 w += print_hex_buf(s, sl, optdata, optlen); 2404 break; 2405 case LDNS_EDNS_EDE: 2406 w += sldns_wire2str_edns_ede_print(s, sl, optdata, optlen); 2407 break; 2408 default: 2409 /* unknown option code */ 2410 w += print_hex_buf(s, sl, optdata, optlen); 2411 break; 2412 } 2413 return w; 2414 } 2415 2416 /** print the edns options to string */ 2417 static int 2418 print_edns_opts(char** s, size_t* sl, uint8_t* rdata, size_t rdatalen) 2419 { 2420 uint16_t option_code, option_len; 2421 int w = 0; 2422 while(rdatalen > 0) { 2423 /* option name */ 2424 if(rdatalen < 4) { 2425 w += sldns_str_print(s, sl, " ; malformed: "); 2426 w += print_hex_buf(s, sl, rdata, rdatalen); 2427 return w; 2428 } 2429 option_code = sldns_read_uint16(rdata); 2430 option_len = sldns_read_uint16(rdata+2); 2431 rdata += 4; 2432 rdatalen -= 4; 2433 2434 /* option value */ 2435 if(rdatalen < (size_t)option_len) { 2436 w += sldns_str_print(s, sl, " ; malformed "); 2437 w += sldns_wire2str_edns_option_code_print(s, sl, 2438 option_code); 2439 w += sldns_str_print(s, sl, ": "); 2440 w += print_hex_buf(s, sl, rdata, rdatalen); 2441 return w; 2442 } 2443 w += sldns_str_print(s, sl, " ; "); 2444 w += sldns_wire2str_edns_option_print(s, sl, option_code, 2445 rdata, option_len); 2446 rdata += option_len; 2447 rdatalen -= option_len; 2448 } 2449 return w; 2450 } 2451 2452 int sldns_wire2str_edns_scan(uint8_t** data, size_t* data_len, char** str, 2453 size_t* str_len, uint8_t* pkt, size_t pktlen) 2454 { 2455 int w = 0; 2456 uint8_t ext_rcode, edns_version; 2457 uint16_t udpsize, edns_bits, rdatalen; 2458 w += sldns_str_print(str, str_len, "; EDNS:"); 2459 2460 /* some input checks, domain name */ 2461 if(*data_len < 1+10) 2462 return w + print_remainder_hex("Error malformed 0x", 2463 data, data_len, str, str_len); 2464 if(*data[0] != 0) { 2465 return w + print_remainder_hex("Error nonrootdname 0x", 2466 data, data_len, str, str_len); 2467 } 2468 (*data)++; 2469 (*data_len)--; 2470 2471 /* check type and read fixed contents */ 2472 if(sldns_read_uint16((*data)) != LDNS_RR_TYPE_OPT) { 2473 return w + print_remainder_hex("Error nottypeOPT 0x", 2474 data, data_len, str, str_len); 2475 } 2476 udpsize = sldns_read_uint16((*data)+2); 2477 ext_rcode = (*data)[4]; 2478 edns_version = (*data)[5]; 2479 edns_bits = sldns_read_uint16((*data)+6); 2480 rdatalen = sldns_read_uint16((*data)+8); 2481 (*data)+=10; 2482 (*data_len)-=10; 2483 2484 w += sldns_str_print(str, str_len, " version: %u;", 2485 (unsigned)edns_version); 2486 w += sldns_str_print(str, str_len, " flags:"); 2487 if((edns_bits & LDNS_EDNS_MASK_DO_BIT)) 2488 w += sldns_str_print(str, str_len, " do"); 2489 if((edns_bits & LDNS_EDNS_MASK_CO_BIT)) 2490 w += sldns_str_print(str, str_len, " co"); 2491 /* the extended rcode is the value set, shifted four bits, 2492 * and or'd with the original rcode */ 2493 if(ext_rcode) { 2494 int rc = ((int)ext_rcode)<<4; 2495 if(pkt && pktlen >= LDNS_HEADER_SIZE) 2496 rc |= LDNS_RCODE_WIRE(pkt); 2497 w += sldns_str_print(str, str_len, " ; ext-rcode: %d", rc); 2498 } 2499 w += sldns_str_print(str, str_len, " ; udp: %u", (unsigned)udpsize); 2500 2501 if(rdatalen) { 2502 if((size_t)*data_len < rdatalen) { 2503 w += sldns_str_print(str, str_len, 2504 " ; Error EDNS rdata too short; "); 2505 rdatalen = (uint16_t)*data_len; 2506 } 2507 w += print_edns_opts(str, str_len, *data, rdatalen); 2508 (*data) += rdatalen; 2509 (*data_len) -= rdatalen; 2510 } 2511 w += sldns_str_print(str, str_len, "\n"); 2512 return w; 2513 } 2514