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