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