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