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