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 if(comprloop) { 821 if(*comprloop != 0) 822 maxcompr = 30; /* for like ipv6 reverse name, per label */ 823 if(*comprloop > 4) 824 maxcompr = 4; /* just don't want to spend time, any more */ 825 } 826 if(*dlen == 0) return sldns_str_print(s, slen, "ErrorMissingDname"); 827 if(*pos == 0) { 828 (*d)++; 829 (*dlen)--; 830 return sldns_str_print(s, slen, "."); 831 } 832 while((!pkt || pos < pkt+pktlen) && *pos) { 833 /* read label length */ 834 uint8_t labellen = *pos++; 835 if(in_buf) { (*d)++; (*dlen)--; } 836 837 /* find out what sort of label we have */ 838 if((labellen&0xc0) == 0xc0) { 839 /* compressed */ 840 uint16_t target = 0; 841 if(in_buf && *dlen == 0) 842 return w + sldns_str_print(s, slen, 843 "ErrorPartialDname"); 844 else if(!in_buf && pos+1 > pkt+pktlen) 845 return w + sldns_str_print(s, slen, 846 "ErrorPartialDname"); 847 target = ((labellen&0x3f)<<8) | *pos; 848 if(in_buf) { (*d)++; (*dlen)--; } 849 /* move to target, if possible */ 850 if(!pkt || target >= pktlen) 851 return w + sldns_str_print(s, slen, 852 "ErrorComprPtrOutOfBounds"); 853 if(counter++ > maxcompr) { 854 if(comprloop && *comprloop < 10) 855 (*comprloop)++; 856 return w + sldns_str_print(s, slen, 857 "ErrorComprPtrLooped"); 858 } 859 in_buf = 0; 860 pos = pkt+target; 861 continue; 862 } else if((labellen&0xc0)) { 863 /* notimpl label type */ 864 w += sldns_str_print(s, slen, 865 "ErrorLABELTYPE%xIsUnknown", 866 (int)(labellen&0xc0)); 867 return w; 868 } 869 870 /* spool label characters, end with '.' */ 871 if(in_buf && *dlen < (size_t)labellen) 872 labellen = (uint8_t)*dlen; 873 else if(!in_buf && pos+(size_t)labellen > pkt+pktlen) 874 labellen = (uint8_t)(pkt + pktlen - pos); 875 for(i=0; i<(unsigned)labellen; i++) { 876 w += dname_char_print(s, slen, *pos++); 877 } 878 if(in_buf) { 879 (*d) += labellen; 880 (*dlen) -= labellen; 881 if(*dlen == 0) break; 882 } 883 w += sldns_str_print(s, slen, "."); 884 } 885 /* skip over final root label */ 886 if(in_buf && *dlen > 0) { (*d)++; (*dlen)--; } 887 /* in case we printed no labels, terminate dname */ 888 if(w == 0) w += sldns_str_print(s, slen, "."); 889 return w; 890 } 891 892 int sldns_wire2str_opcode_print(char** s, size_t* slen, int opcode) 893 { 894 sldns_lookup_table *lt = sldns_lookup_by_id(sldns_opcodes, opcode); 895 if (lt && lt->name) { 896 return sldns_str_print(s, slen, "%s", lt->name); 897 } 898 return sldns_str_print(s, slen, "OPCODE%u", (unsigned)opcode); 899 } 900 901 int sldns_wire2str_rcode_print(char** s, size_t* slen, int rcode) 902 { 903 sldns_lookup_table *lt = sldns_lookup_by_id(sldns_rcodes, rcode); 904 if (lt && lt->name) { 905 return sldns_str_print(s, slen, "%s", lt->name); 906 } 907 return sldns_str_print(s, slen, "RCODE%u", (unsigned)rcode); 908 } 909 910 int sldns_wire2str_class_print(char** s, size_t* slen, uint16_t rrclass) 911 { 912 sldns_lookup_table *lt = sldns_lookup_by_id(sldns_rr_classes, 913 (int)rrclass); 914 if (lt && lt->name) { 915 return sldns_str_print(s, slen, "%s", lt->name); 916 } 917 return sldns_str_print(s, slen, "CLASS%u", (unsigned)rrclass); 918 } 919 920 int sldns_wire2str_type_print(char** s, size_t* slen, uint16_t rrtype) 921 { 922 const sldns_rr_descriptor *descriptor = sldns_rr_descript(rrtype); 923 if (descriptor && descriptor->_name) { 924 return sldns_str_print(s, slen, "%s", descriptor->_name); 925 } 926 return sldns_str_print(s, slen, "TYPE%u", (unsigned)rrtype); 927 } 928 929 int sldns_wire2str_edns_option_code_print(char** s, size_t* slen, 930 uint16_t opcode) 931 { 932 sldns_lookup_table *lt = sldns_lookup_by_id(sldns_edns_options, 933 (int)opcode); 934 if (lt && lt->name) { 935 return sldns_str_print(s, slen, "%s", lt->name); 936 } 937 return sldns_str_print(s, slen, "OPT%u", (unsigned)opcode); 938 } 939 940 int sldns_wire2str_class_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen) 941 { 942 uint16_t c; 943 if(*dlen == 0) return 0; 944 if(*dlen < 2) return print_remainder_hex("Error malformed 0x", d, dlen, s, slen); 945 c = sldns_read_uint16(*d); 946 (*d)+=2; 947 (*dlen)-=2; 948 return sldns_wire2str_class_print(s, slen, c); 949 } 950 951 int sldns_wire2str_type_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen) 952 { 953 uint16_t t; 954 if(*dlen == 0) return 0; 955 if(*dlen < 2) return print_remainder_hex("Error malformed 0x", d, dlen, s, slen); 956 t = sldns_read_uint16(*d); 957 (*d)+=2; 958 (*dlen)-=2; 959 return sldns_wire2str_type_print(s, slen, t); 960 } 961 962 int sldns_wire2str_ttl_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen) 963 { 964 uint32_t ttl; 965 if(*dlen == 0) return 0; 966 if(*dlen < 4) return print_remainder_hex("Error malformed 0x", d, dlen, s, slen); 967 ttl = sldns_read_uint32(*d); 968 (*d)+=4; 969 (*dlen)-=4; 970 return sldns_str_print(s, slen, "%u", (unsigned)ttl); 971 } 972 973 static int 974 sldns_print_svcparamkey(char** s, size_t* slen, uint16_t svcparamkey) 975 { 976 if (svcparamkey < SVCPARAMKEY_COUNT) { 977 return sldns_str_print(s, slen, "%s", svcparamkey_strs[svcparamkey]); 978 } 979 else { 980 return sldns_str_print(s, slen, "key%d", (int)svcparamkey); 981 } 982 } 983 984 static int sldns_wire2str_svcparam_port2str(char** s, 985 size_t* slen, uint16_t data_len, uint8_t* data) 986 { 987 int w = 0; 988 989 if (data_len != 2) 990 return -1; /* wireformat error, a short is 2 bytes */ 991 w = sldns_str_print(s, slen, "=%d", (int)sldns_read_uint16(data)); 992 993 return w; 994 } 995 996 static int sldns_wire2str_svcparam_ipv4hint2str(char** s, 997 size_t* slen, uint16_t data_len, uint8_t* data) 998 { 999 char ip_str[INET_ADDRSTRLEN + 1]; 1000 1001 int w = 0; 1002 1003 assert(data_len > 0); 1004 1005 if ((data_len % LDNS_IP4ADDRLEN) == 0) { 1006 if (inet_ntop(AF_INET, data, ip_str, sizeof(ip_str)) == NULL) 1007 return -1; /* wireformat error, incorrect size or inet family */ 1008 1009 w += sldns_str_print(s, slen, "=%s", ip_str); 1010 data += LDNS_IP4ADDRLEN; 1011 1012 while ((data_len -= LDNS_IP4ADDRLEN) > 0) { 1013 if (inet_ntop(AF_INET, data, ip_str, sizeof(ip_str)) == NULL) 1014 return -1; /* wireformat error, incorrect size or inet family */ 1015 1016 w += sldns_str_print(s, slen, ",%s", ip_str); 1017 data += LDNS_IP4ADDRLEN; 1018 } 1019 } else 1020 return -1; 1021 1022 return w; 1023 } 1024 1025 static int sldns_wire2str_svcparam_ipv6hint2str(char** s, 1026 size_t* slen, uint16_t data_len, uint8_t* data) 1027 { 1028 char ip_str[INET6_ADDRSTRLEN + 1]; 1029 1030 int w = 0; 1031 1032 assert(data_len > 0); 1033 1034 if ((data_len % LDNS_IP6ADDRLEN) == 0) { 1035 if (inet_ntop(AF_INET6, data, ip_str, sizeof(ip_str)) == NULL) 1036 return -1; /* wireformat error, incorrect size or inet family */ 1037 1038 w += sldns_str_print(s, slen, "=%s", ip_str); 1039 data += LDNS_IP6ADDRLEN; 1040 1041 while ((data_len -= LDNS_IP6ADDRLEN) > 0) { 1042 if (inet_ntop(AF_INET6, data, ip_str, sizeof(ip_str)) == NULL) 1043 return -1; /* wireformat error, incorrect size or inet family */ 1044 1045 w += sldns_str_print(s, slen, ",%s", ip_str); 1046 data += LDNS_IP6ADDRLEN; 1047 } 1048 } else 1049 return -1; 1050 1051 return w; 1052 } 1053 1054 static int sldns_wire2str_svcparam_mandatory2str(char** s, 1055 size_t* slen, uint16_t data_len, uint8_t* data) 1056 { 1057 int w = 0; 1058 1059 assert(data_len > 0); 1060 1061 if (data_len % sizeof(uint16_t)) 1062 return -1; // wireformat error, data_len must be multiple of shorts 1063 w += sldns_str_print(s, slen, "="); 1064 w += sldns_print_svcparamkey(s, slen, sldns_read_uint16(data)); 1065 data += 2; 1066 1067 while ((data_len -= sizeof(uint16_t))) { 1068 w += sldns_str_print(s, slen, ","); 1069 w += sldns_print_svcparamkey(s, slen, sldns_read_uint16(data)); 1070 data += 2; 1071 } 1072 1073 return w; 1074 } 1075 1076 static int sldns_wire2str_svcparam_alpn2str(char** s, 1077 size_t* slen, uint16_t data_len, uint8_t* data) 1078 { 1079 uint8_t *dp = (void *)data; 1080 int w = 0; 1081 1082 assert(data_len > 0); /* Guaranteed by sldns_wire2str_svcparam_scan */ 1083 1084 w += sldns_str_print(s, slen, "=\""); 1085 while (data_len) { 1086 /* alpn is list of length byte (str_len) followed by a string of that size */ 1087 uint8_t i, str_len = *dp++; 1088 1089 if (str_len > --data_len) 1090 return -1; 1091 1092 for (i = 0; i < str_len; i++) { 1093 if (dp[i] == '"' || dp[i] == '\\') 1094 w += sldns_str_print(s, slen, "\\\\\\%c", dp[i]); 1095 1096 else if (dp[i] == ',') 1097 w += sldns_str_print(s, slen, "\\\\%c", dp[i]); 1098 1099 else if (!isprint(dp[i])) 1100 w += sldns_str_print(s, slen, "\\%03u", (unsigned) dp[i]); 1101 1102 else 1103 w += sldns_str_print(s, slen, "%c", dp[i]); 1104 } 1105 dp += str_len; 1106 if ((data_len -= str_len)) 1107 w += sldns_str_print(s, slen, "%s", ","); 1108 } 1109 w += sldns_str_print(s, slen, "\""); 1110 1111 return w; 1112 } 1113 1114 static int sldns_wire2str_svcparam_ech2str(char** s, 1115 size_t* slen, uint16_t data_len, uint8_t* data) 1116 { 1117 int size; 1118 int w = 0; 1119 1120 assert(data_len > 0); /* Guaranteed by sldns_wire2str_svcparam_scan */ 1121 1122 w += sldns_str_print(s, slen, "=\""); 1123 1124 if ((size = sldns_b64_ntop(data, data_len, *s, *slen)) < 0) 1125 return -1; 1126 1127 (*s) += size; 1128 (*slen) -= size; 1129 1130 w += sldns_str_print(s, slen, "\""); 1131 1132 return w + size; 1133 } 1134 1135 int sldns_wire2str_svcparam_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen) 1136 { 1137 uint8_t ch; 1138 uint16_t svcparamkey, data_len; 1139 int written_chars = 0; 1140 int r, i; 1141 1142 /* verify that we have enough data to read svcparamkey and data_len */ 1143 if(*dlen < 4) 1144 return -1; 1145 1146 svcparamkey = sldns_read_uint16(*d); 1147 data_len = sldns_read_uint16(*d+2); 1148 *d += 4; 1149 *dlen -= 4; 1150 1151 /* verify that we have data_len data */ 1152 if (data_len > *dlen) 1153 return -1; 1154 1155 written_chars += sldns_print_svcparamkey(s, slen, svcparamkey); 1156 if (!data_len) { 1157 1158 /* Some SvcParams MUST have values */ 1159 switch (svcparamkey) { 1160 case SVCB_KEY_ALPN: 1161 case SVCB_KEY_PORT: 1162 case SVCB_KEY_IPV4HINT: 1163 case SVCB_KEY_IPV6HINT: 1164 case SVCB_KEY_MANDATORY: 1165 return -1; 1166 default: 1167 return written_chars; 1168 } 1169 } 1170 1171 switch (svcparamkey) { 1172 case SVCB_KEY_PORT: 1173 r = sldns_wire2str_svcparam_port2str(s, slen, data_len, *d); 1174 break; 1175 case SVCB_KEY_IPV4HINT: 1176 r = sldns_wire2str_svcparam_ipv4hint2str(s, slen, data_len, *d); 1177 break; 1178 case SVCB_KEY_IPV6HINT: 1179 r = sldns_wire2str_svcparam_ipv6hint2str(s, slen, data_len, *d); 1180 break; 1181 case SVCB_KEY_MANDATORY: 1182 r = sldns_wire2str_svcparam_mandatory2str(s, slen, data_len, *d); 1183 break; 1184 case SVCB_KEY_NO_DEFAULT_ALPN: 1185 return -1; /* wireformat error, should not have a value */ 1186 case SVCB_KEY_ALPN: 1187 r = sldns_wire2str_svcparam_alpn2str(s, slen, data_len, *d); 1188 break; 1189 case SVCB_KEY_ECH: 1190 r = sldns_wire2str_svcparam_ech2str(s, slen, data_len, *d); 1191 break; 1192 default: 1193 r = sldns_str_print(s, slen, "=\""); 1194 1195 for (i = 0; i < data_len; i++) { 1196 ch = (*d)[i]; 1197 1198 if (ch == '"' || ch == '\\') 1199 r += sldns_str_print(s, slen, "\\%c", ch); 1200 1201 else if (!isprint(ch)) 1202 r += sldns_str_print(s, slen, "\\%03u", (unsigned) ch); 1203 1204 else 1205 r += sldns_str_print(s, slen, "%c", ch); 1206 1207 } 1208 r += sldns_str_print(s, slen, "\""); 1209 break; 1210 } 1211 if (r <= 0) 1212 return -1; /* wireformat error */ 1213 1214 written_chars += r; 1215 *d += data_len; 1216 *dlen -= data_len; 1217 return written_chars; 1218 } 1219 1220 int sldns_wire2str_rdf_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen, 1221 int rdftype, uint8_t* pkt, size_t pktlen, int* comprloop) 1222 { 1223 if(*dlen == 0) return 0; 1224 switch(rdftype) { 1225 case LDNS_RDF_TYPE_NONE: 1226 return 0; 1227 case LDNS_RDF_TYPE_DNAME: 1228 return sldns_wire2str_dname_scan(d, dlen, s, slen, pkt, pktlen, comprloop); 1229 case LDNS_RDF_TYPE_INT8: 1230 return sldns_wire2str_int8_scan(d, dlen, s, slen); 1231 case LDNS_RDF_TYPE_INT16: 1232 return sldns_wire2str_int16_scan(d, dlen, s, slen); 1233 case LDNS_RDF_TYPE_INT32: 1234 return sldns_wire2str_int32_scan(d, dlen, s, slen); 1235 case LDNS_RDF_TYPE_PERIOD: 1236 return sldns_wire2str_period_scan(d, dlen, s, slen); 1237 case LDNS_RDF_TYPE_TSIGTIME: 1238 return sldns_wire2str_tsigtime_scan(d, dlen, s, slen); 1239 case LDNS_RDF_TYPE_A: 1240 return sldns_wire2str_a_scan(d, dlen, s, slen); 1241 case LDNS_RDF_TYPE_AAAA: 1242 return sldns_wire2str_aaaa_scan(d, dlen, s, slen); 1243 case LDNS_RDF_TYPE_STR: 1244 return sldns_wire2str_str_scan(d, dlen, s, slen); 1245 case LDNS_RDF_TYPE_APL: 1246 return sldns_wire2str_apl_scan(d, dlen, s, slen); 1247 case LDNS_RDF_TYPE_B32_EXT: 1248 return sldns_wire2str_b32_ext_scan(d, dlen, s, slen); 1249 case LDNS_RDF_TYPE_B64: 1250 return sldns_wire2str_b64_scan(d, dlen, s, slen); 1251 case LDNS_RDF_TYPE_HEX: 1252 return sldns_wire2str_hex_scan(d, dlen, s, slen); 1253 case LDNS_RDF_TYPE_NSEC: 1254 return sldns_wire2str_nsec_scan(d, dlen, s, slen); 1255 case LDNS_RDF_TYPE_NSEC3_SALT: 1256 return sldns_wire2str_nsec3_salt_scan(d, dlen, s, slen); 1257 case LDNS_RDF_TYPE_TYPE: 1258 return sldns_wire2str_type_scan(d, dlen, s, slen); 1259 case LDNS_RDF_TYPE_CLASS: 1260 return sldns_wire2str_class_scan(d, dlen, s, slen); 1261 case LDNS_RDF_TYPE_CERT_ALG: 1262 return sldns_wire2str_cert_alg_scan(d, dlen, s, slen); 1263 case LDNS_RDF_TYPE_ALG: 1264 return sldns_wire2str_alg_scan(d, dlen, s, slen); 1265 case LDNS_RDF_TYPE_UNKNOWN: 1266 return sldns_wire2str_unknown_scan(d, dlen, s, slen); 1267 case LDNS_RDF_TYPE_TIME: 1268 return sldns_wire2str_time_scan(d, dlen, s, slen); 1269 case LDNS_RDF_TYPE_LOC: 1270 return sldns_wire2str_loc_scan(d, dlen, s, slen); 1271 case LDNS_RDF_TYPE_WKS: 1272 case LDNS_RDF_TYPE_SERVICE: 1273 return sldns_wire2str_wks_scan(d, dlen, s, slen); 1274 case LDNS_RDF_TYPE_NSAP: 1275 return sldns_wire2str_nsap_scan(d, dlen, s, slen); 1276 case LDNS_RDF_TYPE_ATMA: 1277 return sldns_wire2str_atma_scan(d, dlen, s, slen); 1278 case LDNS_RDF_TYPE_IPSECKEY: 1279 return sldns_wire2str_ipseckey_scan(d, dlen, s, slen, pkt, 1280 pktlen, comprloop); 1281 case LDNS_RDF_TYPE_HIP: 1282 return sldns_wire2str_hip_scan(d, dlen, s, slen); 1283 case LDNS_RDF_TYPE_INT16_DATA: 1284 return sldns_wire2str_int16_data_scan(d, dlen, s, slen); 1285 case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER: 1286 return sldns_wire2str_b32_ext_scan(d, dlen, s, slen); 1287 case LDNS_RDF_TYPE_ILNP64: 1288 return sldns_wire2str_ilnp64_scan(d, dlen, s, slen); 1289 case LDNS_RDF_TYPE_EUI48: 1290 return sldns_wire2str_eui48_scan(d, dlen, s, slen); 1291 case LDNS_RDF_TYPE_EUI64: 1292 return sldns_wire2str_eui64_scan(d, dlen, s, slen); 1293 case LDNS_RDF_TYPE_TAG: 1294 return sldns_wire2str_tag_scan(d, dlen, s, slen); 1295 case LDNS_RDF_TYPE_LONG_STR: 1296 return sldns_wire2str_long_str_scan(d, dlen, s, slen); 1297 case LDNS_RDF_TYPE_SVCPARAM: 1298 return sldns_wire2str_svcparam_scan(d, dlen, s, slen); 1299 case LDNS_RDF_TYPE_TSIGERROR: 1300 return sldns_wire2str_tsigerror_scan(d, dlen, s, slen); 1301 } 1302 /* unknown rdf type */ 1303 return -1; 1304 } 1305 1306 int sldns_wire2str_int8_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1307 { 1308 int w; 1309 if(*dl < 1) return -1; 1310 w = sldns_str_print(s, sl, "%u", (unsigned)**d); 1311 (*d)++; 1312 (*dl)--; 1313 return w; 1314 } 1315 1316 int sldns_wire2str_int16_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1317 { 1318 int w; 1319 if(*dl < 2) return -1; 1320 w = sldns_str_print(s, sl, "%lu", (unsigned long)sldns_read_uint16(*d)); 1321 (*d)+=2; 1322 (*dl)-=2; 1323 return w; 1324 } 1325 1326 int sldns_wire2str_int32_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1327 { 1328 int w; 1329 if(*dl < 4) return -1; 1330 w = sldns_str_print(s, sl, "%lu", (unsigned long)sldns_read_uint32(*d)); 1331 (*d)+=4; 1332 (*dl)-=4; 1333 return w; 1334 } 1335 1336 int sldns_wire2str_period_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1337 { 1338 int w; 1339 if(*dl < 4) return -1; 1340 w = sldns_str_print(s, sl, "%u", (unsigned)sldns_read_uint32(*d)); 1341 (*d)+=4; 1342 (*dl)-=4; 1343 return w; 1344 } 1345 1346 int sldns_wire2str_tsigtime_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1347 { 1348 /* tsigtime is 48 bits network order unsigned integer */ 1349 int w; 1350 uint64_t tsigtime = 0; 1351 uint64_t d0, d1, d2, d3, d4, d5; 1352 if(*dl < 6) return -1; 1353 d0 = (*d)[0]; /* cast to uint64 for shift operations */ 1354 d1 = (*d)[1]; 1355 d2 = (*d)[2]; 1356 d3 = (*d)[3]; 1357 d4 = (*d)[4]; 1358 d5 = (*d)[5]; 1359 tsigtime = (d0<<40) | (d1<<32) | (d2<<24) | (d3<<16) | (d4<<8) | d5; 1360 #ifndef USE_WINSOCK 1361 w = sldns_str_print(s, sl, "%llu", (long long)tsigtime); 1362 #else 1363 w = sldns_str_print(s, sl, "%I64u", (long long)tsigtime); 1364 #endif 1365 (*d)+=6; 1366 (*dl)-=6; 1367 return w; 1368 } 1369 1370 int sldns_wire2str_a_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1371 { 1372 char buf[32]; 1373 int w; 1374 if(*dl < 4) return -1; 1375 if(!inet_ntop(AF_INET, *d, buf, (socklen_t)sizeof(buf))) 1376 return -1; 1377 w = sldns_str_print(s, sl, "%s", buf); 1378 (*d)+=4; 1379 (*dl)-=4; 1380 return w; 1381 } 1382 1383 int sldns_wire2str_aaaa_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1384 { 1385 #ifdef AF_INET6 1386 char buf[64]; 1387 int w; 1388 if(*dl < 16) return -1; 1389 if(!inet_ntop(AF_INET6, *d, buf, (socklen_t)sizeof(buf))) 1390 return -1; 1391 w = sldns_str_print(s, sl, "%s", buf); 1392 (*d)+=16; 1393 (*dl)-=16; 1394 return w; 1395 #else 1396 return -1; 1397 #endif 1398 } 1399 1400 /** printout escaped TYPE_STR character */ 1401 static int str_char_print(char** s, size_t* sl, uint8_t c) 1402 { 1403 if(isprint((unsigned char)c) || c == '\t') { 1404 if(c == '\"' || c == '\\') 1405 return sldns_str_print(s, sl, "\\%c", c); 1406 if(*sl) { 1407 **s = (char)c; 1408 (*s)++; 1409 (*sl)--; 1410 } 1411 return 1; 1412 } 1413 return sldns_str_print(s, sl, "\\%03u", (unsigned)c); 1414 } 1415 1416 int sldns_wire2str_str_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1417 { 1418 int w = 0; 1419 size_t i, len; 1420 if(*dl < 1) return -1; 1421 len = **d; 1422 if(*dl < 1+len) return -1; 1423 (*d)++; 1424 (*dl)--; 1425 w += sldns_str_print(s, sl, "\""); 1426 for(i=0; i<len; i++) 1427 w += str_char_print(s, sl, (*d)[i]); 1428 w += sldns_str_print(s, sl, "\""); 1429 (*d)+=len; 1430 (*dl)-=len; 1431 return w; 1432 } 1433 1434 int sldns_wire2str_apl_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1435 { 1436 int i, w = 0; 1437 uint16_t family; 1438 uint8_t negation, prefix, adflength; 1439 if(*dl < 4) return -1; 1440 family = sldns_read_uint16(*d); 1441 prefix = (*d)[2]; 1442 negation = ((*d)[3] & LDNS_APL_NEGATION); 1443 adflength = ((*d)[3] & LDNS_APL_MASK); 1444 if(*dl < 4+(size_t)adflength) return -1; 1445 if(family != LDNS_APL_IP4 && family != LDNS_APL_IP6) 1446 return -1; /* unknown address family */ 1447 if(negation) 1448 w += sldns_str_print(s, sl, "!"); 1449 w += sldns_str_print(s, sl, "%u:", (unsigned)family); 1450 if(family == LDNS_APL_IP4) { 1451 /* check if prefix <32 ? */ 1452 /* address is variable length 0 - 4 */ 1453 for(i=0; i<4; i++) { 1454 if(i > 0) 1455 w += sldns_str_print(s, sl, "."); 1456 if(i < (int)adflength) 1457 w += sldns_str_print(s, sl, "%d", (*d)[4+i]); 1458 else w += sldns_str_print(s, sl, "0"); 1459 } 1460 } else if(family == LDNS_APL_IP6) { 1461 /* check if prefix <128 ? */ 1462 /* address is variable length 0 - 16 */ 1463 for(i=0; i<16; i++) { 1464 if(i%2 == 0 && i>0) 1465 w += sldns_str_print(s, sl, ":"); 1466 if(i < (int)adflength) 1467 w += sldns_str_print(s, sl, "%02x", (*d)[4+i]); 1468 else w += sldns_str_print(s, sl, "00"); 1469 } 1470 } 1471 w += sldns_str_print(s, sl, "/%u", (unsigned)prefix); 1472 (*d) += 4+adflength; 1473 (*dl) -= 4+adflength; 1474 return w; 1475 } 1476 1477 int sldns_wire2str_b32_ext_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1478 { 1479 size_t datalen; 1480 size_t sz; 1481 if(*dl < 1) return -1; 1482 datalen = (*d)[0]; 1483 if(*dl < 1+datalen) return -1; 1484 sz = sldns_b32_ntop_calculate_size(datalen); 1485 if(*sl < sz+1) { 1486 (*d) += datalen+1; 1487 (*dl) -= (datalen+1); 1488 return (int)sz; /* out of space really, but would need buffer 1489 in order to truncate the output */ 1490 } 1491 sldns_b32_ntop_extended_hex((*d)+1, datalen, *s, *sl); 1492 (*d) += datalen+1; 1493 (*dl) -= (datalen+1); 1494 (*s) += sz; 1495 (*sl) -= sz; 1496 return (int)sz; 1497 } 1498 1499 /** scan number of bytes from wire into b64 presentation format */ 1500 static int sldns_wire2str_b64_scan_num(uint8_t** d, size_t* dl, char** s, 1501 size_t* sl, size_t num) 1502 { 1503 /* b64_ntop_calculate size includes null at the end */ 1504 size_t sz = sldns_b64_ntop_calculate_size(num)-1; 1505 if(*sl < sz+1) { 1506 (*d) += num; 1507 (*dl) -= num; 1508 return (int)sz; /* out of space really, but would need buffer 1509 in order to truncate the output */ 1510 } 1511 sldns_b64_ntop(*d, num, *s, *sl); 1512 (*d) += num; 1513 (*dl) -= num; 1514 (*s) += sz; 1515 (*sl) -= sz; 1516 return (int)sz; 1517 } 1518 1519 int sldns_wire2str_b64_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1520 { 1521 if(*dl == 0) { 1522 return sldns_str_print(s, sl, "0"); 1523 } 1524 return sldns_wire2str_b64_scan_num(d, dl, s, sl, *dl); 1525 } 1526 1527 int sldns_wire2str_hex_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1528 { 1529 if(*dl == 0) { 1530 return sldns_str_print(s, sl, "0"); 1531 } 1532 return print_remainder_hex("", d, dl, s, sl); 1533 } 1534 1535 int sldns_wire2str_nsec_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1536 { 1537 uint8_t* p = *d; 1538 size_t pl = *dl; 1539 unsigned i, bit, window, block_len; 1540 uint16_t t; 1541 int w = 0; 1542 1543 /* check for errors */ 1544 while(pl) { 1545 if(pl < 2) return -1; 1546 block_len = (unsigned)p[1]; 1547 if(pl < 2+block_len) return -1; 1548 p += block_len+2; 1549 pl -= block_len+2; 1550 } 1551 1552 /* do it */ 1553 p = *d; 1554 pl = *dl; 1555 while(pl) { 1556 if(pl < 2) return -1; /* cannot happen */ 1557 window = (unsigned)p[0]; 1558 block_len = (unsigned)p[1]; 1559 if(pl < 2+block_len) return -1; /* cannot happen */ 1560 p += 2; 1561 for(i=0; i<block_len; i++) { 1562 if(p[i] == 0) continue; 1563 /* base type number for this octet */ 1564 t = ((window)<<8) | (i << 3); 1565 for(bit=0; bit<8; bit++) { 1566 if((p[i]&(0x80>>bit))) { 1567 if(w) w += sldns_str_print(s, sl, " "); 1568 w += sldns_wire2str_type_print(s, sl, 1569 t+bit); 1570 } 1571 } 1572 } 1573 p += block_len; 1574 pl -= block_len+2; 1575 } 1576 (*d) += *dl; 1577 (*dl) = 0; 1578 return w; 1579 } 1580 1581 int sldns_wire2str_nsec3_salt_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1582 { 1583 size_t salt_len; 1584 int w; 1585 if(*dl < 1) return -1; 1586 salt_len = (size_t)(*d)[0]; 1587 if(*dl < 1+salt_len) return -1; 1588 (*d)++; 1589 (*dl)--; 1590 if(salt_len == 0) { 1591 return sldns_str_print(s, sl, "-"); 1592 } 1593 w = print_hex_buf(s, sl, *d, salt_len); 1594 (*dl)-=salt_len; 1595 (*d)+=salt_len; 1596 return w; 1597 } 1598 1599 int sldns_wire2str_cert_alg_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1600 { 1601 sldns_lookup_table *lt; 1602 int data, w; 1603 if(*dl < 2) return -1; 1604 data = (int)sldns_read_uint16(*d); 1605 lt = sldns_lookup_by_id(sldns_cert_algorithms, data); 1606 if(lt && lt->name) 1607 w = sldns_str_print(s, sl, "%s", lt->name); 1608 else w = sldns_str_print(s, sl, "%d", data); 1609 (*dl)-=2; 1610 (*d)+=2; 1611 return w; 1612 } 1613 1614 int sldns_wire2str_alg_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1615 { 1616 /* don't use algorithm mnemonics in the presentation format 1617 * this kind of got sneaked into the rfc's */ 1618 return sldns_wire2str_int8_scan(d, dl, s, sl); 1619 } 1620 1621 int sldns_wire2str_unknown_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1622 { 1623 return sldns_wire2str_rdata_unknown_scan(d, dl, s, sl); 1624 } 1625 1626 int sldns_wire2str_time_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1627 { 1628 /* create a YYYYMMDDHHMMSS string if possible */ 1629 struct tm tm; 1630 char date_buf[16]; 1631 uint32_t t; 1632 memset(&tm, 0, sizeof(tm)); 1633 if(*dl < 4) return -1; 1634 t = sldns_read_uint32(*d); 1635 date_buf[15]=0; 1636 if(sldns_serial_arithmetics_gmtime_r(t, time(NULL), &tm) && 1637 strftime(date_buf, 15, "%Y%m%d%H%M%S", &tm)) { 1638 (*d) += 4; 1639 (*dl) -= 4; 1640 return sldns_str_print(s, sl, "%s", date_buf); 1641 } 1642 return -1; 1643 } 1644 1645 static int 1646 loc_cm_print(char** str, size_t* sl, uint8_t mantissa, uint8_t exponent) 1647 { 1648 int w = 0; 1649 uint8_t i; 1650 /* is it 0.<two digits> ? */ 1651 if(exponent < 2) { 1652 if(exponent == 1) 1653 mantissa *= 10; 1654 return sldns_str_print(str, sl, "0.%02ld", (long)mantissa); 1655 } 1656 /* always <digit><string of zeros> */ 1657 w += sldns_str_print(str, sl, "%d", (int)mantissa); 1658 for(i=0; i<exponent-2; i++) 1659 w += sldns_str_print(str, sl, "0"); 1660 return w; 1661 } 1662 1663 int sldns_wire2str_loc_scan(uint8_t** d, size_t* dl, char** str, size_t* sl) 1664 { 1665 /* we could do checking (ie degrees < 90 etc)? */ 1666 uint8_t version; 1667 uint8_t size; 1668 uint8_t horizontal_precision; 1669 uint8_t vertical_precision; 1670 uint32_t longitude; 1671 uint32_t latitude; 1672 uint32_t altitude; 1673 char northerness; 1674 char easterness; 1675 uint32_t h; 1676 uint32_t m; 1677 double s; 1678 uint32_t equator = (uint32_t)1 << 31; /* 2**31 */ 1679 int w = 0; 1680 1681 if(*dl < 16) return -1; 1682 version = (*d)[0]; 1683 if(version != 0) 1684 return sldns_wire2str_hex_scan(d, dl, str, sl); 1685 size = (*d)[1]; 1686 horizontal_precision = (*d)[2]; 1687 vertical_precision = (*d)[3]; 1688 1689 latitude = sldns_read_uint32((*d)+4); 1690 longitude = sldns_read_uint32((*d)+8); 1691 altitude = sldns_read_uint32((*d)+12); 1692 1693 if (latitude > equator) { 1694 northerness = 'N'; 1695 latitude = latitude - equator; 1696 } else { 1697 northerness = 'S'; 1698 latitude = equator - latitude; 1699 } 1700 h = latitude / (1000 * 60 * 60); 1701 latitude = latitude % (1000 * 60 * 60); 1702 m = latitude / (1000 * 60); 1703 latitude = latitude % (1000 * 60); 1704 s = (double) latitude / 1000.0; 1705 w += sldns_str_print(str, sl, "%02u %02u %06.3f %c ", 1706 h, m, s, northerness); 1707 1708 if (longitude > equator) { 1709 easterness = 'E'; 1710 longitude = longitude - equator; 1711 } else { 1712 easterness = 'W'; 1713 longitude = equator - longitude; 1714 } 1715 h = longitude / (1000 * 60 * 60); 1716 longitude = longitude % (1000 * 60 * 60); 1717 m = longitude / (1000 * 60); 1718 longitude = longitude % (1000 * 60); 1719 s = (double) longitude / (1000.0); 1720 w += sldns_str_print(str, sl, "%02u %02u %06.3f %c ", 1721 h, m, s, easterness); 1722 1723 s = ((double) altitude) / 100; 1724 s -= 100000; 1725 1726 if(altitude%100 != 0) 1727 w += sldns_str_print(str, sl, "%.2f", s); 1728 else 1729 w += sldns_str_print(str, sl, "%.0f", s); 1730 1731 w += sldns_str_print(str, sl, "m "); 1732 1733 w += loc_cm_print(str, sl, (size & 0xf0) >> 4, size & 0x0f); 1734 w += sldns_str_print(str, sl, "m "); 1735 1736 w += loc_cm_print(str, sl, (horizontal_precision & 0xf0) >> 4, 1737 horizontal_precision & 0x0f); 1738 w += sldns_str_print(str, sl, "m "); 1739 1740 w += loc_cm_print(str, sl, (vertical_precision & 0xf0) >> 4, 1741 vertical_precision & 0x0f); 1742 w += sldns_str_print(str, sl, "m"); 1743 1744 (*d)+=16; 1745 (*dl)-=16; 1746 return w; 1747 } 1748 1749 int sldns_wire2str_wks_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1750 { 1751 /* protocol, followed by bitmap of services */ 1752 const char* proto_name = NULL; 1753 struct protoent *protocol; 1754 struct servent *service; 1755 uint8_t protocol_nr; 1756 int bit, port, w = 0; 1757 size_t i; 1758 /* we cannot print with strings because they 1759 * are not portable, the presentation format may 1760 * not be able to be read in on another computer. */ 1761 int print_symbols = 0; 1762 1763 /* protocol */ 1764 if(*dl < 1) return -1; 1765 protocol_nr = (*d)[0]; 1766 (*d)++; 1767 (*dl)--; 1768 protocol = getprotobynumber((int)protocol_nr); 1769 if(protocol && (protocol->p_name != NULL)) { 1770 w += sldns_str_print(s, sl, "%s", protocol->p_name); 1771 proto_name = protocol->p_name; 1772 } else if(protocol_nr == 6) { 1773 w += sldns_str_print(s, sl, "tcp"); 1774 } else if(protocol_nr == 17) { 1775 w += sldns_str_print(s, sl, "udp"); 1776 } else { 1777 w += sldns_str_print(s, sl, "%u", (unsigned)protocol_nr); 1778 } 1779 1780 for(i=0; i<*dl; i++) { 1781 if((*d)[i] == 0) 1782 continue; 1783 for(bit=0; bit<8; bit++) { 1784 if(!(((*d)[i])&(0x80>>bit))) 1785 continue; 1786 port = (int)i*8 + bit; 1787 1788 if(!print_symbols) 1789 service = NULL; 1790 else 1791 service = getservbyport( 1792 (int)htons((uint16_t)port), proto_name); 1793 if(service && service->s_name) 1794 w += sldns_str_print(s, sl, " %s", 1795 service->s_name); 1796 else w += sldns_str_print(s, sl, " %u", 1797 (unsigned)port); 1798 } 1799 } 1800 1801 #ifdef HAVE_ENDSERVENT 1802 endservent(); 1803 #endif 1804 #ifdef HAVE_ENDPROTOENT 1805 endprotoent(); 1806 #endif 1807 (*d) += *dl; 1808 (*dl) = 0; 1809 return w; 1810 } 1811 1812 int sldns_wire2str_nsap_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1813 { 1814 return print_remainder_hex("0x", d, dl, s, sl); 1815 } 1816 1817 int sldns_wire2str_atma_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1818 { 1819 return print_remainder_hex("", d, dl, s, sl); 1820 } 1821 1822 /* internal scan routine that can modify arguments on failure */ 1823 static int sldns_wire2str_ipseckey_scan_internal(uint8_t** d, size_t* dl, 1824 char** s, size_t* sl, uint8_t* pkt, size_t pktlen, int* comprloop) 1825 { 1826 /* http://www.ietf.org/internet-drafts/draft-ietf-ipseckey-rr-12.txt*/ 1827 uint8_t precedence, gateway_type, algorithm; 1828 int w = 0; 1829 1830 if(*dl < 3) return -1; 1831 precedence = (*d)[0]; 1832 gateway_type = (*d)[1]; 1833 algorithm = (*d)[2]; 1834 if(gateway_type > 3) 1835 return -1; /* unknown */ 1836 (*d)+=3; 1837 (*dl)-=3; 1838 w += sldns_str_print(s, sl, "%d %d %d ", 1839 (int)precedence, (int)gateway_type, (int)algorithm); 1840 1841 switch(gateway_type) { 1842 case 0: /* no gateway */ 1843 w += sldns_str_print(s, sl, "."); 1844 break; 1845 case 1: /* ip4 */ 1846 w += sldns_wire2str_a_scan(d, dl, s, sl); 1847 break; 1848 case 2: /* ip6 */ 1849 w += sldns_wire2str_aaaa_scan(d, dl, s, sl); 1850 break; 1851 case 3: /* dname */ 1852 w += sldns_wire2str_dname_scan(d, dl, s, sl, pkt, pktlen, comprloop); 1853 break; 1854 default: /* unknown */ 1855 return -1; 1856 } 1857 1858 if(*dl < 1) 1859 return -1; 1860 w += sldns_str_print(s, sl, " "); 1861 w += sldns_wire2str_b64_scan_num(d, dl, s, sl, *dl); 1862 return w; 1863 } 1864 1865 int sldns_wire2str_ipseckey_scan(uint8_t** d, size_t* dl, char** s, size_t* sl, 1866 uint8_t* pkt, size_t pktlen, int* comprloop) 1867 { 1868 uint8_t* od = *d; 1869 char* os = *s; 1870 size_t odl = *dl, osl = *sl; 1871 int w=sldns_wire2str_ipseckey_scan_internal(d, dl, s, sl, pkt, pktlen, comprloop); 1872 if(w == -1) { 1873 *d = od; 1874 *s = os; 1875 *dl = odl; 1876 *sl = osl; 1877 return -1; 1878 } 1879 return w; 1880 } 1881 1882 int sldns_wire2str_hip_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1883 { 1884 int w; 1885 uint8_t algo, hitlen; 1886 uint16_t pklen; 1887 1888 /* read lengths */ 1889 if(*dl < 4) 1890 return -1; 1891 hitlen = (*d)[0]; 1892 algo = (*d)[1]; 1893 pklen = sldns_read_uint16((*d)+2); 1894 if(*dl < (size_t)4 + (size_t)hitlen + (size_t)pklen) 1895 return -1; 1896 1897 /* write: algo hit pubkey */ 1898 w = sldns_str_print(s, sl, "%u ", (unsigned)algo); 1899 w += print_hex_buf(s, sl, (*d)+4, hitlen); 1900 w += sldns_str_print(s, sl, " "); 1901 (*d)+=4+hitlen; 1902 (*dl)-= (4+hitlen); 1903 w += sldns_wire2str_b64_scan_num(d, dl, s, sl, pklen); 1904 return w; 1905 } 1906 1907 int sldns_wire2str_int16_data_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1908 { 1909 int w; 1910 uint16_t n; 1911 if(*dl < 2) 1912 return -1; 1913 n = sldns_read_uint16(*d); 1914 if(*dl < 2+(size_t)n) 1915 return -1; 1916 (*d)+=2; 1917 (*dl)-=2; 1918 if(n == 0) { 1919 return sldns_str_print(s, sl, "0"); 1920 } 1921 w = sldns_str_print(s, sl, "%u ", (unsigned)n); 1922 w += sldns_wire2str_b64_scan_num(d, dl, s, sl, n); 1923 return w; 1924 } 1925 1926 int sldns_wire2str_nsec3_next_owner_scan(uint8_t** d, size_t* dl, char** s, 1927 size_t* sl) 1928 { 1929 return sldns_wire2str_b32_ext_scan(d, dl, s, sl); 1930 } 1931 1932 int sldns_wire2str_ilnp64_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1933 { 1934 int w; 1935 if(*dl < 8) 1936 return -1; 1937 w = sldns_str_print(s, sl, "%.4x:%.4x:%.4x:%.4x", 1938 sldns_read_uint16(*d), sldns_read_uint16((*d)+2), 1939 sldns_read_uint16((*d)+4), sldns_read_uint16((*d)+6)); 1940 (*d)+=8; 1941 (*dl)-=8; 1942 return w; 1943 } 1944 1945 int sldns_wire2str_eui48_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1946 { 1947 int w; 1948 if(*dl < 6) 1949 return -1; 1950 w = sldns_str_print(s, sl, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", 1951 (*d)[0], (*d)[1], (*d)[2], (*d)[3], (*d)[4], (*d)[5]); 1952 (*d)+=6; 1953 (*dl)-=6; 1954 return w; 1955 } 1956 1957 int sldns_wire2str_eui64_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1958 { 1959 int w; 1960 if(*dl < 8) 1961 return -1; 1962 w = sldns_str_print(s, sl, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", 1963 (*d)[0], (*d)[1], (*d)[2], (*d)[3], (*d)[4], (*d)[5], 1964 (*d)[6], (*d)[7]); 1965 (*d)+=8; 1966 (*dl)-=8; 1967 return w; 1968 } 1969 1970 int sldns_wire2str_tag_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1971 { 1972 size_t i, n; 1973 int w = 0; 1974 if(*dl < 1) 1975 return -1; 1976 n = (size_t)((*d)[0]); 1977 if(*dl < 1+n) 1978 return -1; 1979 for(i=0; i<n; i++) 1980 if(!isalnum((unsigned char)(*d)[i+1])) 1981 return -1; 1982 for(i=0; i<n; i++) 1983 w += sldns_str_print(s, sl, "%c", (char)(*d)[i+1]); 1984 (*d)+=n+1; 1985 (*dl)-=(n+1); 1986 return w; 1987 } 1988 1989 int sldns_wire2str_long_str_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 1990 { 1991 size_t i; 1992 int w = 0; 1993 w += sldns_str_print(s, sl, "\""); 1994 for(i=0; i<*dl; i++) 1995 w += str_char_print(s, sl, (*d)[i]); 1996 w += sldns_str_print(s, sl, "\""); 1997 (*d)+=*dl; 1998 (*dl)=0; 1999 return w; 2000 } 2001 2002 int sldns_wire2str_tsigerror_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) 2003 { 2004 sldns_lookup_table *lt; 2005 int data, w; 2006 if(*dl < 2) return -1; 2007 data = (int)sldns_read_uint16(*d); 2008 lt = sldns_lookup_by_id(sldns_tsig_errors, data); 2009 if(lt && lt->name) 2010 w = sldns_str_print(s, sl, "%s", lt->name); 2011 else w = sldns_str_print(s, sl, "%d", data); 2012 (*dl)-=2; 2013 (*d)+=2; 2014 return w; 2015 } 2016 2017 int sldns_wire2str_edns_llq_print(char** s, size_t* sl, uint8_t* data, 2018 size_t len) 2019 { 2020 /* LLQ constants */ 2021 const char* llq_errors[] = {"NO-ERROR", "SERV-FULL", "STATIC", 2022 "FORMAT-ERR", "NO-SUCH-LLQ", "BAD-VERS", "UNKNOWN_ERR"}; 2023 const unsigned int llq_errors_num = 7; 2024 const char* llq_opcodes[] = {"LLQ-SETUP", "LLQ-REFRESH", "LLQ-EVENT"}; 2025 const unsigned int llq_opcodes_num = 3; 2026 uint16_t version, llq_opcode, error_code; 2027 uint64_t llq_id; 2028 uint32_t lease_life; /* Requested or granted life of LLQ, in seconds */ 2029 int w = 0; 2030 2031 /* read the record */ 2032 if(len != 18) { 2033 w += sldns_str_print(s, sl, "malformed LLQ "); 2034 w += print_hex_buf(s, sl, data, len); 2035 return w; 2036 } 2037 version = sldns_read_uint16(data); 2038 llq_opcode = sldns_read_uint16(data+2); 2039 error_code = sldns_read_uint16(data+4); 2040 memmove(&llq_id, data+6, sizeof(llq_id)); 2041 lease_life = sldns_read_uint32(data+14); 2042 2043 /* print it */ 2044 w += sldns_str_print(s, sl, "v%d ", (int)version); 2045 if(llq_opcode < llq_opcodes_num) 2046 w += sldns_str_print(s, sl, "%s", llq_opcodes[llq_opcode]); 2047 else w += sldns_str_print(s, sl, "opcode %d", (int)llq_opcode); 2048 if(error_code < llq_errors_num) 2049 w += sldns_str_print(s, sl, " %s", llq_errors[error_code]); 2050 else w += sldns_str_print(s, sl, " error %d", (int)error_code); 2051 #ifndef USE_WINSOCK 2052 w += sldns_str_print(s, sl, " id %llx lease-life %lu", 2053 (unsigned long long)llq_id, (unsigned long)lease_life); 2054 #else 2055 w += sldns_str_print(s, sl, " id %I64x lease-life %lu", 2056 (unsigned long long)llq_id, (unsigned long)lease_life); 2057 #endif 2058 return w; 2059 } 2060 2061 int sldns_wire2str_edns_ul_print(char** s, size_t* sl, uint8_t* data, 2062 size_t len) 2063 { 2064 uint32_t lease; 2065 int w = 0; 2066 if(len != 4) { 2067 w += sldns_str_print(s, sl, "malformed UL "); 2068 w += print_hex_buf(s, sl, data, len); 2069 return w; 2070 } 2071 lease = sldns_read_uint32(data); 2072 w += sldns_str_print(s, sl, "lease %lu", (unsigned long)lease); 2073 return w; 2074 } 2075 2076 int sldns_wire2str_edns_nsid_print(char** s, size_t* sl, uint8_t* data, 2077 size_t len) 2078 { 2079 int w = 0; 2080 size_t i, printed=0; 2081 w += print_hex_buf(s, sl, data, len); 2082 for(i=0; i<len; i++) { 2083 if(isprint((unsigned char)data[i]) || data[i] == '\t') { 2084 if(!printed) { 2085 w += sldns_str_print(s, sl, " ("); 2086 printed = 1; 2087 } 2088 w += sldns_str_print(s, sl, "%c", (char)data[i]); 2089 } 2090 } 2091 if(printed) 2092 w += sldns_str_print(s, sl, ")"); 2093 return w; 2094 } 2095 2096 int sldns_wire2str_edns_dau_print(char** s, size_t* sl, uint8_t* data, 2097 size_t len) 2098 { 2099 sldns_lookup_table *lt; 2100 size_t i; 2101 int w = 0; 2102 for(i=0; i<len; i++) { 2103 lt = sldns_lookup_by_id(sldns_algorithms, (int)data[i]); 2104 if(lt && lt->name) 2105 w += sldns_str_print(s, sl, " %s", lt->name); 2106 else w += sldns_str_print(s, sl, " %d", (int)data[i]); 2107 } 2108 return w; 2109 } 2110 2111 int sldns_wire2str_edns_dhu_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_hashes, (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_n3u_print(char** s, size_t* sl, uint8_t* data, 2127 size_t len) 2128 { 2129 size_t i; 2130 int w = 0; 2131 for(i=0; i<len; i++) { 2132 if(data[i] == 1) 2133 w += sldns_str_print(s, sl, " SHA1"); 2134 else w += sldns_str_print(s, sl, " %d", (int)data[i]); 2135 } 2136 return w; 2137 } 2138 2139 int sldns_wire2str_edns_subnet_print(char** s, size_t* sl, uint8_t* data, 2140 size_t len) 2141 { 2142 int w = 0; 2143 uint16_t family; 2144 uint8_t source, scope; 2145 if(len < 4) { 2146 w += sldns_str_print(s, sl, "malformed subnet "); 2147 w += print_hex_buf(s, sl, data, len); 2148 return w; 2149 } 2150 family = sldns_read_uint16(data); 2151 source = data[2]; 2152 scope = data[3]; 2153 if(family == 1) { 2154 /* IP4 */ 2155 char buf[64]; 2156 uint8_t ip4[4]; 2157 memset(ip4, 0, sizeof(ip4)); 2158 if(len-4 > 4) { 2159 w += sldns_str_print(s, sl, "trailingdata:"); 2160 w += print_hex_buf(s, sl, data+4+4, len-4-4); 2161 w += sldns_str_print(s, sl, " "); 2162 len = 4+4; 2163 } 2164 memmove(ip4, data+4, len-4); 2165 if(!inet_ntop(AF_INET, ip4, buf, (socklen_t)sizeof(buf))) { 2166 w += sldns_str_print(s, sl, "ip4ntoperror "); 2167 w += print_hex_buf(s, sl, data+4+4, len-4-4); 2168 } else { 2169 w += sldns_str_print(s, sl, "%s", buf); 2170 } 2171 } else if(family == 2) { 2172 /* IP6 */ 2173 char buf[64]; 2174 uint8_t ip6[16]; 2175 memset(ip6, 0, sizeof(ip6)); 2176 if(len-4 > 16) { 2177 w += sldns_str_print(s, sl, "trailingdata:"); 2178 w += print_hex_buf(s, sl, data+4+16, len-4-16); 2179 w += sldns_str_print(s, sl, " "); 2180 len = 4+16; 2181 } 2182 memmove(ip6, data+4, len-4); 2183 #ifdef AF_INET6 2184 if(!inet_ntop(AF_INET6, ip6, buf, (socklen_t)sizeof(buf))) { 2185 w += sldns_str_print(s, sl, "ip6ntoperror "); 2186 w += print_hex_buf(s, sl, data+4+4, len-4-4); 2187 } else { 2188 w += sldns_str_print(s, sl, "%s", buf); 2189 } 2190 #else 2191 w += print_hex_buf(s, sl, data+4+4, len-4-4); 2192 #endif 2193 } else { 2194 /* unknown */ 2195 w += sldns_str_print(s, sl, "family %d ", 2196 (int)family); 2197 w += print_hex_buf(s, sl, data, len); 2198 } 2199 w += sldns_str_print(s, sl, "/%d scope /%d", (int)source, (int)scope); 2200 return w; 2201 } 2202 2203 static int sldns_wire2str_edns_keepalive_print(char** s, size_t* sl, 2204 uint8_t* data, size_t len) 2205 { 2206 int w = 0; 2207 uint16_t timeout; 2208 if(!(len == 0 || len == 2)) { 2209 w += sldns_str_print(s, sl, "malformed keepalive "); 2210 w += print_hex_buf(s, sl, data, len); 2211 return w; 2212 } 2213 if(len == 0 ) { 2214 w += sldns_str_print(s, sl, "no timeout value (only valid for client option) "); 2215 } else { 2216 timeout = sldns_read_uint16(data); 2217 w += sldns_str_print(s, sl, "timeout value in units of 100ms %u", (int)timeout); 2218 } 2219 return w; 2220 } 2221 2222 int sldns_wire2str_edns_option_print(char** s, size_t* sl, 2223 uint16_t option_code, uint8_t* optdata, size_t optlen) 2224 { 2225 int w = 0; 2226 w += sldns_wire2str_edns_option_code_print(s, sl, option_code); 2227 w += sldns_str_print(s, sl, ": "); 2228 switch(option_code) { 2229 case LDNS_EDNS_LLQ: 2230 w += sldns_wire2str_edns_llq_print(s, sl, optdata, optlen); 2231 break; 2232 case LDNS_EDNS_UL: 2233 w += sldns_wire2str_edns_ul_print(s, sl, optdata, optlen); 2234 break; 2235 case LDNS_EDNS_NSID: 2236 w += sldns_wire2str_edns_nsid_print(s, sl, optdata, optlen); 2237 break; 2238 case LDNS_EDNS_DAU: 2239 w += sldns_wire2str_edns_dau_print(s, sl, optdata, optlen); 2240 break; 2241 case LDNS_EDNS_DHU: 2242 w += sldns_wire2str_edns_dhu_print(s, sl, optdata, optlen); 2243 break; 2244 case LDNS_EDNS_N3U: 2245 w += sldns_wire2str_edns_n3u_print(s, sl, optdata, optlen); 2246 break; 2247 case LDNS_EDNS_CLIENT_SUBNET: 2248 w += sldns_wire2str_edns_subnet_print(s, sl, optdata, optlen); 2249 break; 2250 case LDNS_EDNS_KEEPALIVE: 2251 w += sldns_wire2str_edns_keepalive_print(s, sl, optdata, optlen); 2252 break; 2253 case LDNS_EDNS_PADDING: 2254 w += print_hex_buf(s, sl, optdata, optlen); 2255 break; 2256 default: 2257 /* unknown option code */ 2258 w += print_hex_buf(s, sl, optdata, optlen); 2259 break; 2260 } 2261 return w; 2262 } 2263 2264 /** print the edns options to string */ 2265 static int 2266 print_edns_opts(char** s, size_t* sl, uint8_t* rdata, size_t rdatalen) 2267 { 2268 uint16_t option_code, option_len; 2269 int w = 0; 2270 while(rdatalen > 0) { 2271 /* option name */ 2272 if(rdatalen < 4) { 2273 w += sldns_str_print(s, sl, " ; malformed: "); 2274 w += print_hex_buf(s, sl, rdata, rdatalen); 2275 return w; 2276 } 2277 option_code = sldns_read_uint16(rdata); 2278 option_len = sldns_read_uint16(rdata+2); 2279 rdata += 4; 2280 rdatalen -= 4; 2281 2282 /* option value */ 2283 if(rdatalen < (size_t)option_len) { 2284 w += sldns_str_print(s, sl, " ; malformed "); 2285 w += sldns_wire2str_edns_option_code_print(s, sl, 2286 option_code); 2287 w += sldns_str_print(s, sl, ": "); 2288 w += print_hex_buf(s, sl, rdata, rdatalen); 2289 return w; 2290 } 2291 w += sldns_str_print(s, sl, " ; "); 2292 w += sldns_wire2str_edns_option_print(s, sl, option_code, 2293 rdata, option_len); 2294 rdata += option_len; 2295 rdatalen -= option_len; 2296 } 2297 return w; 2298 } 2299 2300 int sldns_wire2str_edns_scan(uint8_t** data, size_t* data_len, char** str, 2301 size_t* str_len, uint8_t* pkt, size_t pktlen) 2302 { 2303 int w = 0; 2304 uint8_t ext_rcode, edns_version; 2305 uint16_t udpsize, edns_bits, rdatalen; 2306 w += sldns_str_print(str, str_len, "; EDNS:"); 2307 2308 /* some input checks, domain name */ 2309 if(*data_len < 1+10) 2310 return w + print_remainder_hex("Error malformed 0x", 2311 data, data_len, str, str_len); 2312 if(*data[0] != 0) { 2313 return w + print_remainder_hex("Error nonrootdname 0x", 2314 data, data_len, str, str_len); 2315 } 2316 (*data)++; 2317 (*data_len)--; 2318 2319 /* check type and read fixed contents */ 2320 if(sldns_read_uint16((*data)) != LDNS_RR_TYPE_OPT) { 2321 return w + print_remainder_hex("Error nottypeOPT 0x", 2322 data, data_len, str, str_len); 2323 } 2324 udpsize = sldns_read_uint16((*data)+2); 2325 ext_rcode = (*data)[4]; 2326 edns_version = (*data)[5]; 2327 edns_bits = sldns_read_uint16((*data)+6); 2328 rdatalen = sldns_read_uint16((*data)+8); 2329 (*data)+=10; 2330 (*data_len)-=10; 2331 2332 w += sldns_str_print(str, str_len, " version: %u;", 2333 (unsigned)edns_version); 2334 w += sldns_str_print(str, str_len, " flags:"); 2335 if((edns_bits & LDNS_EDNS_MASK_DO_BIT)) 2336 w += sldns_str_print(str, str_len, " do"); 2337 /* the extended rcode is the value set, shifted four bits, 2338 * and or'd with the original rcode */ 2339 if(ext_rcode) { 2340 int rc = ((int)ext_rcode)<<4; 2341 if(pkt && pktlen >= LDNS_HEADER_SIZE) 2342 rc |= LDNS_RCODE_WIRE(pkt); 2343 w += sldns_str_print(str, str_len, " ; ext-rcode: %d", rc); 2344 } 2345 w += sldns_str_print(str, str_len, " ; udp: %u", (unsigned)udpsize); 2346 2347 if(rdatalen) { 2348 if((size_t)*data_len < rdatalen) { 2349 w += sldns_str_print(str, str_len, 2350 " ; Error EDNS rdata too short; "); 2351 rdatalen = (uint16_t)*data_len; 2352 } 2353 w += print_edns_opts(str, str_len, *data, rdatalen); 2354 (*data) += rdatalen; 2355 (*data_len) -= rdatalen; 2356 } 2357 w += sldns_str_print(str, str_len, "\n"); 2358 return w; 2359 } 2360