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