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