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