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