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