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