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