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