1 /* $OpenBSD: print-domain.c,v 1.20 2014/08/14 12:44:44 mpi Exp $ */ 2 3 /* 4 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that: (1) source code distributions 9 * retain the above copyright notice and this paragraph in its entirety, (2) 10 * distributions including binary code include the above copyright notice and 11 * this paragraph in its entirety in the documentation or other materials 12 * provided with the distribution, and (3) all advertising materials mentioning 13 * features or use of this software display the following acknowledgement: 14 * ``This product includes software developed by the University of California, 15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 16 * the University nor the names of its contributors may be used to endorse 17 * or promote products derived from this software without specific prior 18 * written permission. 19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 22 */ 23 24 #include <sys/param.h> 25 #include <sys/time.h> 26 #include <sys/socket.h> 27 28 #include <net/if.h> 29 30 #include <netinet/in.h> 31 #include <netinet/if_ether.h> 32 #include <netinet/ip.h> 33 #include <netinet/ip_var.h> 34 #include <netinet/udp.h> 35 #include <netinet/udp_var.h> 36 #include <netinet/tcp.h> 37 38 #ifdef NOERROR 39 #undef NOERROR /* Solaris sucks */ 40 #endif 41 #ifdef NOERROR 42 #undef T_UNSPEC /* SINIX does too */ 43 #endif 44 #include "nameser.h" 45 46 #include <stdio.h> 47 #include <string.h> 48 49 #include "interface.h" 50 #include "addrtoname.h" 51 #include "extract.h" /* must come after interface.h */ 52 53 static const char *ns_ops[] = { 54 "", " inv_q", " stat", " op3", " notify", " update", " op6", " op7", 55 " op8", " updataA", " updateD", " updateDA", 56 " updateM", " updateMA", " zoneInit", " zoneRef", 57 }; 58 59 static const char *ns_resp[] = { 60 "", " FormErr", " ServFail", " NXDomain", 61 " NotImp", " Refused", " YXDomain", " YXRRSet", 62 " NXRRSet", " NotAuth", " NotZone", " Resp11", 63 " Resp12", " Resp13", " Resp14", " NoChange", 64 }; 65 66 /* skip over a domain name */ 67 static const u_char * 68 ns_nskip(register const u_char *cp) 69 { 70 register u_char i; 71 72 if (!TTEST2(*cp, 1)) 73 return (NULL); 74 i = *cp++; 75 while (i) { 76 if ((i & INDIR_MASK) == INDIR_MASK) 77 return (cp + 1); 78 if ((i & INDIR_MASK) == EDNS0_MASK) { 79 int bitlen, bytelen; 80 81 if ((i & ~INDIR_MASK) != EDNS0_ELT_BITLABEL) 82 return(NULL); /* unknown ELT */ 83 if (!TTEST2(*cp, 1)) 84 return (NULL); 85 if ((bitlen = *cp++) == 0) 86 bitlen = 256; 87 bytelen = (bitlen + 7) / 8; 88 cp += bytelen; 89 } else 90 cp += i; 91 if (!TTEST2(*cp, 1)) 92 return (NULL); 93 i = *cp++; 94 } 95 return (cp); 96 } 97 98 /* print a <domain-name> */ 99 static const u_char * 100 blabel_print(const u_char *cp) 101 { 102 int bitlen, slen, b; 103 const u_char *bitp, *lim; 104 char tc; 105 106 if (!TTEST2(*cp, 1)) 107 return(NULL); 108 if ((bitlen = *cp) == 0) 109 bitlen = 256; 110 slen = (bitlen + 3) / 4; 111 lim = cp + 1 + slen; 112 113 /* print the bit string as a hex string */ 114 printf("\\[x"); 115 for (bitp = cp + 1, b = bitlen; bitp < lim && b > 7; b -= 8, bitp++) { 116 TCHECK(*bitp); 117 printf("%02x", *bitp); 118 } 119 if (b > 4) { 120 TCHECK(*bitp); 121 tc = *bitp++; 122 printf("%02x", tc & (0xff << (8 - b))); 123 } else if (b > 0) { 124 TCHECK(*bitp); 125 tc = *bitp++; 126 printf("%1x", ((tc >> 4) & 0x0f) & (0x0f << (4 - b))); 127 } 128 printf("/%d]", bitlen); 129 return lim; 130 trunc: 131 printf(".../%d]", bitlen); 132 return NULL; 133 } 134 135 static int 136 labellen(const u_char *cp) 137 { 138 register u_int i; 139 140 if (!TTEST2(*cp, 1)) 141 return(-1); 142 i = *cp; 143 if ((i & INDIR_MASK) == EDNS0_MASK) { 144 int bitlen, elt; 145 if ((elt = (i & ~INDIR_MASK)) != EDNS0_ELT_BITLABEL) { 146 printf("<ELT %d>", elt); 147 return(-1); 148 } 149 if (!TTEST2(*(cp + 1), 1)) 150 return(-1); 151 if ((bitlen = *(cp + 1)) == 0) 152 bitlen = 256; 153 return(((bitlen + 7) / 8) + 1); 154 } else 155 return(i); 156 } 157 158 static const u_char * 159 ns_nprint(register const u_char *cp, register const u_char *bp) 160 { 161 register u_int i, l; 162 register const u_char *rp = NULL; 163 register int compress = 0; 164 int chars_processed; 165 int elt; 166 int data_size = snapend - bp; 167 168 if ((l = labellen(cp)) == (u_int)-1) 169 return(NULL); 170 if (!TTEST2(*cp, 1)) 171 return(NULL); 172 chars_processed = 1; 173 if (((i = *cp++) & INDIR_MASK) != INDIR_MASK) { 174 compress = 0; 175 rp = cp + l; 176 } 177 178 if (i != 0) 179 while (i && cp < snapend) { 180 if ((i & INDIR_MASK) == INDIR_MASK) { 181 if (!compress) { 182 rp = cp + 1; 183 compress = 1; 184 } 185 if (!TTEST2(*cp, 1)) 186 return(NULL); 187 cp = bp + (((i << 8) | *cp) & 0x3fff); 188 if ((l = labellen(cp)) == (u_int)-1) 189 return(NULL); 190 if (!TTEST2(*cp, 1)) 191 return(NULL); 192 i = *cp++; 193 chars_processed++; 194 195 /* 196 * If we've looked at every character in 197 * the message, this pointer will make 198 * us look at some character again, 199 * which means we're looping. 200 */ 201 if (chars_processed >= data_size) { 202 printf("<LOOP>"); 203 return (NULL); 204 } 205 continue; 206 } 207 if ((i & INDIR_MASK) == EDNS0_MASK) { 208 elt = (i & ~INDIR_MASK); 209 switch(elt) { 210 case EDNS0_ELT_BITLABEL: 211 if (blabel_print(cp) == NULL) 212 return (NULL); 213 break; 214 default: 215 /* unknown ELT */ 216 printf("<ELT %d>", elt); 217 return(NULL); 218 } 219 } else { 220 if (fn_printn(cp, l, snapend)) 221 return(NULL); 222 } 223 224 cp += l; 225 chars_processed += l; 226 putchar('.'); 227 if ((l = labellen(cp)) == (u_int)-1) 228 return(NULL); 229 if (!TTEST2(*cp, 1)) 230 return(NULL); 231 i = *cp++; 232 chars_processed++; 233 if (!compress) 234 rp += l + 1; 235 } 236 else 237 putchar('.'); 238 return (rp); 239 } 240 241 /* print a <character-string> */ 242 static const u_char * 243 ns_cprint(register const u_char *cp) 244 { 245 register u_int i; 246 247 if (!TTEST2(*cp, 1)) 248 return (NULL); 249 i = *cp++; 250 if (fn_printn(cp, i, snapend)) 251 return (NULL); 252 return (cp + i); 253 } 254 255 /* http://www.iana.org/assignments/dns-parameters */ 256 struct tok ns_type2str[] = { 257 { T_A, "A" }, /* RFC 1035 */ 258 { T_NS, "NS" }, /* RFC 1035 */ 259 { T_MD, "MD" }, /* RFC 1035 */ 260 { T_MF, "MF" }, /* RFC 1035 */ 261 { T_CNAME, "CNAME" }, /* RFC 1035 */ 262 { T_SOA, "SOA" }, /* RFC 1035 */ 263 { T_MB, "MB" }, /* RFC 1035 */ 264 { T_MG, "MG" }, /* RFC 1035 */ 265 { T_MR, "MR" }, /* RFC 1035 */ 266 { T_NULL, "NULL" }, /* RFC 1035 */ 267 { T_WKS, "WKS" }, /* RFC 1035 */ 268 { T_PTR, "PTR" }, /* RFC 1035 */ 269 { T_HINFO, "HINFO" }, /* RFC 1035 */ 270 { T_MINFO, "MINFO" }, /* RFC 1035 */ 271 { T_MX, "MX" }, /* RFC 1035 */ 272 { T_TXT, "TXT" }, /* RFC 1035 */ 273 { T_RP, "RP" }, /* RFC 1183 */ 274 { T_AFSDB, "AFSDB" }, /* RFC 1183 */ 275 { T_X25, "X25" }, /* RFC 1183 */ 276 { T_ISDN, "ISDN" }, /* RFC 1183 */ 277 { T_RT, "RT" }, /* RFC 1183 */ 278 { T_NSAP, "NSAP" }, /* RFC 1706 */ 279 { T_NSAP_PTR, "NSAP_PTR" }, 280 { T_SIG, "SIG" }, /* RFC 2535 */ 281 { T_KEY, "KEY" }, /* RFC 2535 */ 282 { T_PX, "PX" }, /* RFC 2163 */ 283 { T_GPOS, "GPOS" }, /* RFC 1712 */ 284 { T_AAAA, "AAAA" }, /* RFC 1886 */ 285 { T_LOC, "LOC" }, /* RFC 1876 */ 286 { T_NXT, "NXT" }, /* RFC 2535 */ 287 { T_EID, "EID" }, /* Nimrod */ 288 { T_NIMLOC, "NIMLOC" }, /* Nimrod */ 289 { T_SRV, "SRV" }, /* RFC 2782 */ 290 { T_ATMA, "ATMA" }, /* ATM Forum */ 291 { T_NAPTR, "NAPTR" }, /* RFC 2168, RFC 2915 */ 292 { T_KX, "KX" }, /* RFC 2230 */ 293 { T_CERT, "CERT" }, /* RFC 2538 */ 294 { T_A6, "A6" }, /* RFC 2874 */ 295 { T_DNAME, "DNAME" }, /* RFC 2672 */ 296 { T_SINK, "SINK" }, 297 { T_OPT, "OPT" }, /* RFC 2671 */ 298 { T_APL, "APL" }, /* RFC 3123 */ 299 { T_DS, "DS" }, /* RFC 4034 */ 300 { T_SSHFP, "SSHFP" }, /* RFC 4255 */ 301 { T_IPSECKEY, "IPSECKEY" }, /* RFC 4025 */ 302 { T_RRSIG, "RRSIG" }, /* RFC 4034 */ 303 { T_NSEC, "NSEC" }, /* RFC 4034 */ 304 { T_DNSKEY, "DNSKEY" }, /* RFC 4034 */ 305 { T_SPF, "SPF" }, /* RFC-schlitt-spf-classic-02.txt */ 306 { T_UINFO, "UINFO" }, 307 { T_UID, "UID" }, 308 { T_GID, "GID" }, 309 { T_UNSPEC, "UNSPEC" }, 310 { T_UNSPECA, "UNSPECA" }, 311 { T_TKEY, "TKEY" }, /* RFC 2930 */ 312 { T_TSIG, "TSIG" }, /* RFC 2845 */ 313 { T_IXFR, "IXFR" }, /* RFC 1995 */ 314 { T_AXFR, "AXFR" }, /* RFC 1035 */ 315 { T_MAILB, "MAILB" }, /* RFC 1035 */ 316 { T_MAILA, "MAILA" }, /* RFC 1035 */ 317 { T_ANY, "ANY" }, 318 { 0, NULL } 319 }; 320 321 struct tok ns_class2str[] = { 322 { C_IN, "IN" }, /* Not used */ 323 { C_CHAOS, "CHAOS" }, 324 { C_HS, "HS" }, 325 { C_ANY, "ANY" }, 326 { 0, NULL } 327 }; 328 329 /* print a query */ 330 static const u_char * 331 ns_qprint(register const u_char *cp, register const u_char *bp, int is_mdns) 332 { 333 register const u_char *np = cp; 334 register u_int i, class; 335 336 cp = ns_nskip(cp); 337 338 if (cp == NULL || !TTEST2(*cp, 4)) 339 return(NULL); 340 341 /* print the qtype */ 342 i = EXTRACT_16BITS(cp); 343 cp += 2; 344 printf(" %s", tok2str(ns_type2str, "Type%d", i)); 345 /* print the qclass (if it's not IN) */ 346 i = EXTRACT_16BITS(cp); 347 cp += 2; 348 if (is_mdns) 349 class = (i & ~C_QU); 350 else 351 class = i; 352 if (class != C_IN) 353 printf(" %s", tok2str(ns_class2str, "(Class %d)", class)); 354 if (is_mdns && (i & C_QU)) 355 printf(" (QU)"); 356 357 fputs("? ", stdout); 358 cp = ns_nprint(np, bp); 359 return(cp ? cp + 4 : NULL); 360 } 361 362 /* print a reply */ 363 static const u_char * 364 ns_rprint(register const u_char *cp, register const u_char *bp, int is_mdns) 365 { 366 register u_int i, class, opt_flags = 0; 367 register u_short typ, len; 368 register const u_char *rp; 369 370 if (vflag) { 371 putchar(' '); 372 if ((cp = ns_nprint(cp, bp)) == NULL) 373 return NULL; 374 } else 375 cp = ns_nskip(cp); 376 377 if (cp == NULL || !TTEST2(*cp, 10)) 378 return (snapend); 379 380 /* print the type/qtype */ 381 typ = EXTRACT_16BITS(cp); 382 cp += 2; 383 /* print the class (if it's not IN and the type isn't OPT) */ 384 i = EXTRACT_16BITS(cp); 385 cp += 2; 386 if (is_mdns) 387 class = (i & ~C_CACHE_FLUSH); 388 else 389 class = i; 390 if (class != C_IN && typ != T_OPT) 391 printf(" %s", tok2str(ns_class2str, "(Class %d)", class)); 392 if (is_mdns) { 393 if (i & C_CACHE_FLUSH) 394 printf(" (Cache flush)"); 395 } 396 397 if (typ == T_OPT) { 398 /* get opt flags */ 399 cp += 2; 400 opt_flags = EXTRACT_16BITS(cp); 401 /* ignore rest of ttl field */ 402 cp += 2; 403 } else if (vflag > 2) { 404 /* print ttl */ 405 printf(" ["); 406 relts_print(EXTRACT_32BITS(cp)); 407 printf("]"); 408 cp += 4; 409 } else { 410 /* ignore ttl */ 411 cp += 4; 412 } 413 414 len = EXTRACT_16BITS(cp); 415 cp += 2; 416 417 rp = cp + len; 418 419 printf(" %s", tok2str(ns_type2str, "Type%d", typ)); 420 if (rp > snapend) 421 return(NULL); 422 423 switch (typ) { 424 case T_A: 425 if (!TTEST2(*cp, sizeof(struct in_addr))) 426 return(NULL); 427 printf(" %s", ipaddr_string(cp)); 428 break; 429 430 case T_NS: 431 case T_CNAME: 432 case T_PTR: 433 #ifdef T_DNAME 434 case T_DNAME: 435 #endif 436 putchar(' '); 437 if (ns_nprint(cp, bp) == NULL) 438 return(NULL); 439 break; 440 441 case T_SOA: 442 if (!vflag) 443 break; 444 putchar(' '); 445 if ((cp = ns_nprint(cp, bp)) == NULL) 446 return(NULL); 447 putchar(' '); 448 if ((cp = ns_nprint(cp, bp)) == NULL) 449 return(NULL); 450 if (!TTEST2(*cp, 5 * 4)) 451 return(NULL); 452 printf(" %u", EXTRACT_32BITS(cp)); 453 cp += 4; 454 printf(" %u", EXTRACT_32BITS(cp)); 455 cp += 4; 456 printf(" %u", EXTRACT_32BITS(cp)); 457 cp += 4; 458 printf(" %u", EXTRACT_32BITS(cp)); 459 cp += 4; 460 printf(" %u", EXTRACT_32BITS(cp)); 461 cp += 4; 462 break; 463 case T_MX: 464 putchar(' '); 465 if (!TTEST2(*cp, 2)) 466 return(NULL); 467 if (ns_nprint(cp + 2, bp) == NULL) 468 return(NULL); 469 printf(" %d", EXTRACT_16BITS(cp)); 470 break; 471 472 case T_TXT: 473 while (cp < rp) { 474 printf(" \""); 475 cp = ns_cprint(cp); 476 if (cp == NULL) 477 return(NULL); 478 putchar('"'); 479 } 480 break; 481 482 case T_SRV: 483 putchar(' '); 484 if (!TTEST2(*cp, 6)) 485 return(NULL); 486 if (ns_nprint(cp + 6, bp) == NULL) 487 return(NULL); 488 printf(":%d %d %d", EXTRACT_16BITS(cp + 4), 489 EXTRACT_16BITS(cp), EXTRACT_16BITS(cp + 2)); 490 break; 491 492 #ifdef INET6 493 case T_AAAA: 494 if (!TTEST2(*cp, sizeof(struct in6_addr))) 495 return(NULL); 496 printf(" %s", ip6addr_string(cp)); 497 break; 498 499 case T_A6: 500 { 501 struct in6_addr a; 502 int pbit, pbyte; 503 504 if (!TTEST2(*cp, 1)) 505 return(NULL); 506 pbit = *cp; 507 pbyte = (pbit & ~7) / 8; 508 if (pbit > 128) { 509 printf(" %u(bad plen)", pbit); 510 break; 511 } else if (pbit < 128) { 512 if (!TTEST2(*(cp + 1), sizeof(a) - pbyte)) 513 return(NULL); 514 memset(&a, 0, sizeof(a)); 515 memcpy(&a.s6_addr[pbyte], cp + 1, sizeof(a) - pbyte); 516 printf(" %u %s", pbit, ip6addr_string(&a)); 517 } 518 if (pbit > 0) { 519 putchar(' '); 520 if (ns_nprint(cp + 1 + sizeof(a) - pbyte, bp) == NULL) 521 return(NULL); 522 } 523 break; 524 } 525 #endif /*INET6*/ 526 527 case T_OPT: 528 printf(" UDPsize=%u", class); 529 if (opt_flags & 0x8000) 530 printf(" OK"); 531 break; 532 533 case T_UNSPECA: /* One long string */ 534 if (!TTEST2(*cp, len)) 535 return(NULL); 536 if (fn_printn(cp, len, snapend)) 537 return(NULL); 538 break; 539 540 case T_TSIG: 541 { 542 if (cp + len > snapend) 543 return(NULL); 544 if (!vflag) 545 break; 546 putchar(' '); 547 if ((cp = ns_nprint(cp, bp)) == NULL) 548 return(NULL); 549 cp += 6; 550 if (!TTEST2(*cp, 2)) 551 return(NULL); 552 printf(" fudge=%u", EXTRACT_16BITS(cp)); 553 cp += 2; 554 if (!TTEST2(*cp, 2)) 555 return(NULL); 556 printf(" maclen=%u", EXTRACT_16BITS(cp)); 557 cp += 2 + EXTRACT_16BITS(cp); 558 if (!TTEST2(*cp, 2)) 559 return(NULL); 560 printf(" origid=%u", EXTRACT_16BITS(cp)); 561 cp += 2; 562 if (!TTEST2(*cp, 2)) 563 return(NULL); 564 printf(" error=%u", EXTRACT_16BITS(cp)); 565 cp += 2; 566 if (!TTEST2(*cp, 2)) 567 return(NULL); 568 printf(" otherlen=%u", EXTRACT_16BITS(cp)); 569 cp += 2; 570 } 571 } 572 return (rp); /* XXX This isn't always right */ 573 } 574 575 void 576 ns_print(register const u_char *bp, u_int length, int is_mdns) 577 { 578 register const HEADER *np; 579 register int qdcount, ancount, nscount, arcount; 580 register const u_char *cp; 581 u_int16_t b2; 582 583 np = (const HEADER *)bp; 584 TCHECK(*np); 585 /* get the byte-order right */ 586 qdcount = EXTRACT_16BITS(&np->qdcount); 587 ancount = EXTRACT_16BITS(&np->ancount); 588 nscount = EXTRACT_16BITS(&np->nscount); 589 arcount = EXTRACT_16BITS(&np->arcount); 590 591 if (DNS_QR(np)) { 592 /* this is a response */ 593 printf(" %d%s%s%s%s%s%s", 594 EXTRACT_16BITS(&np->id), 595 ns_ops[DNS_OPCODE(np)], 596 ns_resp[DNS_RCODE(np)], 597 DNS_AA(np)? "*" : "", 598 DNS_RA(np)? "" : "-", 599 DNS_TC(np)? "|" : "", 600 DNS_AD(np)? "$" : ""); 601 602 if (qdcount != 1) 603 printf(" [%dq]", qdcount); 604 /* Print QUESTION section on -vv */ 605 cp = (const u_char *)(np + 1); 606 while (qdcount--) { 607 if (qdcount < EXTRACT_16BITS(&np->qdcount) - 1) 608 putchar(','); 609 if (vflag > 1) { 610 fputs(" q:", stdout); 611 if ((cp = ns_qprint(cp, bp, is_mdns)) == NULL) 612 goto trunc; 613 } else { 614 if ((cp = ns_nskip(cp)) == NULL) 615 goto trunc; 616 cp += 4; /* skip QTYPE and QCLASS */ 617 } 618 } 619 printf(" %d/%d/%d", ancount, nscount, arcount); 620 if (ancount--) { 621 if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) 622 goto trunc; 623 while (cp < snapend && ancount--) { 624 putchar(','); 625 if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) 626 goto trunc; 627 } 628 } 629 if (ancount > 0) 630 goto trunc; 631 /* Print NS and AR sections on -vv */ 632 if (vflag > 1) { 633 if (cp < snapend && nscount--) { 634 fputs(" ns:", stdout); 635 if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) 636 goto trunc; 637 while (cp < snapend && nscount--) { 638 putchar(','); 639 if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) 640 goto trunc; 641 } 642 } 643 if (nscount > 0) 644 goto trunc; 645 if (cp < snapend && arcount--) { 646 fputs(" ar:", stdout); 647 if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) 648 goto trunc; 649 while (cp < snapend && arcount--) { 650 putchar(','); 651 if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) 652 goto trunc; 653 } 654 } 655 if (arcount > 0) 656 goto trunc; 657 } 658 } 659 else { 660 /* this is a request */ 661 printf(" %d%s%s%s", EXTRACT_16BITS(&np->id), ns_ops[DNS_OPCODE(np)], 662 DNS_RD(np) ? "+" : "", 663 DNS_CD(np) ? "%" : ""); 664 665 /* any weirdness? AA is expected in NOTIFY. */ 666 b2 = EXTRACT_16BITS(((u_short *)np)+1); 667 if ((b2 & 0x6cf) != 668 (DNS_OPCODE(np) == NS_NOTIFY_OP ? htons(0x400) : 0)) 669 printf(" [b2&3=0x%x]", b2); 670 671 if (DNS_OPCODE(np) == IQUERY) { 672 if (qdcount) 673 printf(" [%dq]", qdcount); 674 if (ancount != 1) 675 printf(" [%da]", ancount); 676 } 677 else { 678 if (ancount) 679 printf(" [%da]", ancount); 680 if (qdcount != 1) 681 printf(" [%dq]", qdcount); 682 } 683 if (nscount) 684 printf(" [%dn]", nscount); 685 if (arcount) 686 printf(" [%dau]", arcount); 687 688 cp = (const u_char *)(np + 1); 689 if (qdcount--) { 690 cp = ns_qprint(cp, (const u_char *)np, is_mdns); 691 if (!cp) 692 goto trunc; 693 while (cp < snapend && qdcount--) { 694 cp = ns_qprint((const u_char *)cp, 695 (const u_char *)np, 696 is_mdns); 697 if (!cp) 698 goto trunc; 699 } 700 } 701 if (qdcount > 0) 702 goto trunc; 703 704 /* Print remaining sections on -vv */ 705 if (vflag > 1) { 706 if (ancount--) { 707 if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) 708 goto trunc; 709 while (cp < snapend && ancount--) { 710 putchar(','); 711 if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) 712 goto trunc; 713 } 714 } 715 if (ancount > 0) 716 goto trunc; 717 if (cp < snapend && nscount--) { 718 fputs(" ns:", stdout); 719 if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) 720 goto trunc; 721 while (nscount-- && cp < snapend) { 722 putchar(','); 723 if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) 724 goto trunc; 725 } 726 } 727 if (nscount > 0) 728 goto trunc; 729 if (cp < snapend && arcount--) { 730 fputs(" ar:", stdout); 731 if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) 732 goto trunc; 733 while (cp < snapend && arcount--) { 734 putchar(','); 735 if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) 736 goto trunc; 737 } 738 } 739 if (arcount > 0) 740 goto trunc; 741 } 742 } 743 printf(" (%d)", length); 744 return; 745 746 trunc: 747 printf("[|domain]"); 748 return; 749 } 750