2 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
3 * The Regents of the University of California. All rights reserved.
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
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.
25 static const char rcsid[] =
26 "@(#) $Header: /tcpdump/master/tcpdump/print-domain.c,v 1.64.2.1 2001/02/21 09:01:20 guy Exp $ (LBL)";
33 #include <sys/param.h>
36 #include <netinet/in.h>
39 #undef NOERROR /* Solaris sucks */
42 #undef T_UNSPEC /* SINIX does too */
49 #include "interface.h"
50 #include "addrtoname.h"
51 #include "extract.h" /* must come after interface.h */
55 #define T_TXT 16 /* text strings */
58 #define T_RP 17 /* responsible person */
61 #define T_AFSDB 18 /* AFS cell database */
64 #define T_X25 19 /* X_25 calling address */
67 #define T_ISDN 20 /* ISDN calling address */
70 #define T_RT 21 /* router */
73 #define T_NSAP 22 /* NSAP address */
76 #define T_NSAP_PTR 23 /* reverse NSAP lookup (deprecated) */
79 #define T_SIG 24 /* security signature */
82 #define T_KEY 25 /* security key */
85 #define T_PX 26 /* X.400 mail mapping */
88 #define T_GPOS 27 /* geographical position (withdrawn) */
91 #define T_AAAA 28 /* IP6 Address */
94 #define T_LOC 29 /* Location Information */
97 #define T_NXT 30 /* Next Valid Name in Zone */
100 #define T_EID 31 /* Endpoint identifier */
103 #define T_NIMLOC 32 /* Nimrod locator */
106 #define T_SRV 33 /* Server selection */
109 #define T_ATMA 34 /* ATM Address */
112 #define T_NAPTR 35 /* Naming Authority PoinTeR */
115 #define T_A6 38 /* IP6 address */
118 #define T_DNAME 39 /* non-terminal redirection */
122 #define T_OPT 41 /* EDNS0 option (meta-RR) */
126 #define T_UNSPEC 103 /* Unspecified format (binary data) */
129 #define T_UNSPECA 104 /* "unspecified ascii". Ugly MIT hack */
133 #define C_CHAOS 3 /* for chaos net (MIT) */
136 #define C_HS 4 /* for Hesiod name server (MIT) (XXX) */
139 static char *ns_ops[] = {
140 "", " inv_q", " stat", " op3", " notify", " op5", " op6", " op7",
141 " op8", " updataA", " updateD", " updateDA",
142 " updateM", " updateMA", " zoneInit", " zoneRef",
145 static char *ns_resp[] = {
146 "", " FormErr", " ServFail", " NXDomain",
147 " NotImp", " Refused", " Resp6", " Resp7",
148 " Resp8", " Resp9", " Resp10", " Resp11",
149 " Resp12", " Resp13", " Resp14", " NoChange",
152 /* skip over a domain name */
153 static const u_char *
154 ns_nskip(register const u_char *cp, register const u_char *bp)
158 if (((i = *cp++) & INDIR_MASK) == INDIR_MASK)
162 while (i && cp < snapend) {
163 if ((i & INDIR_MASK) == EDNS0_MASK) {
166 if ((i & ~INDIR_MASK) != EDNS0_ELT_BITLABEL)
167 return(NULL); /* unknown ELT */
168 if ((bitlen = *cp++) == 0)
170 bytelen = (bitlen + 7) / 8;
181 /* print a <domain-name> */
182 static const u_char *
183 blabel_print(const u_char *cp)
187 const u_char *bitp, *lim;
192 if ((bitlen = *cp) == 0)
194 slen = (bitlen + 3) / 4;
195 if ((lim = cp + 1 + slen) > snapend) {
200 /* print the bit string as a hex string */
202 for (bitp = cp + 1, b = bitlen; bitp < lim && b > 7; b -= 8, bitp++)
203 printf("%02x", *bitp);
208 printf("%02x", tc & (0xff << (8 - b)));
211 printf("%1x", ((tc >> 4) & 0x0f) & (0x0f << (4 - b)));
213 printf("/%d]", bitlen);
215 return(truncated ? NULL : lim);
219 labellen(const u_char *cp)
226 if ((i & INDIR_MASK) == EDNS0_MASK) {
229 if ((elt = (i & ~INDIR_MASK)) != EDNS0_ELT_BITLABEL)
231 if (cp + 1 >= snapend)
233 if ((bitlen = *(cp + 1)) == 0)
235 return(((bitlen + 7) / 8) + 1);
240 static const u_char *
241 ns_nprint(register const u_char *cp, register const u_char *bp)
244 register const u_char *rp = NULL;
245 register int compress = 0;
248 int data_size = snapend - bp;
250 if ((l = labellen(cp)) < 0)
255 if (((i = *cp++) & INDIR_MASK) != INDIR_MASK) {
261 while (i && cp < snapend) {
262 if ((i & INDIR_MASK) == INDIR_MASK) {
267 cp = bp + (((i << 8) | *cp) & 0x3fff);
270 if ((l = labellen(cp)) < 0)
276 * If we've looked at every character in
277 * the message, this pointer will make
278 * us look at some character again,
279 * which means we're looping.
281 if (chars_processed >= data_size) {
287 if ((i & INDIR_MASK) == EDNS0_MASK) {
288 elt = (i & ~INDIR_MASK);
290 case EDNS0_ELT_BITLABEL:
295 printf("<ELT %d>", elt);
299 if (fn_printn(cp, l, snapend))
304 chars_processed += l;
306 if (cp >= snapend || (l = labellen(cp)) < 0)
318 /* print a <character-string> */
319 static const u_char *
320 ns_cprint(register const u_char *cp, register const u_char *bp)
327 (void)fn_printn(cp, i, snapend);
331 static struct tok type2str[] = {
336 { T_CNAME, "CNAME" },
344 { T_HINFO, "HINFO" },
345 { T_MINFO, "MINFO" },
349 { T_AFSDB, "AFSDB" },
354 { T_NSAP_PTR, "NSAP_PTR" },
363 { T_NIMLOC, "NIMLOC " },
366 { T_NAPTR, "NAPTR " },
368 { T_DNAME, "DNAME " },
370 { T_UINFO, "UINFO" },
373 { T_UNSPEC, "UNSPEC" },
374 { T_UNSPECA, "UNSPECA" },
376 { T_MAILB, "MAILB" },
377 { T_MAILA, "MAILA" },
382 static struct tok class2str[] = {
383 { C_IN, "IN" }, /* Not used */
384 { C_CHAOS, "CHAOS)" },
391 static const u_char *
392 ns_qprint(register const u_char *cp, register const u_char *bp)
394 register const u_char *np = cp;
397 cp = ns_nskip(cp, bp);
399 if (cp + 4 > snapend || cp == NULL)
402 /* print the qtype and qclass (if it's not IN) */
405 printf(" %s", tok2str(type2str, "Type%d", i));
409 printf(" %s", tok2str(class2str, "(Class %d)", i));
412 cp = ns_nprint(np, bp);
413 return(cp ? cp + 4 : NULL);
417 static const u_char *
418 ns_rprint(register const u_char *cp, register const u_char *bp)
420 register u_int class;
421 register u_short typ, len;
422 register const u_char *rp;
426 if ((cp = ns_nprint(cp, bp)) == NULL)
429 cp = ns_nskip(cp, bp);
431 if (cp + 10 > snapend || cp == NULL)
434 /* print the type/qtype and class (if it's not IN) */
439 if (class != C_IN && typ != T_OPT)
440 printf(" %s", tok2str(class2str, "(Class %d)", class));
450 printf(" %s", tok2str(type2str, "Type%d", typ));
456 if (cp + sizeof(struct in_addr) > snapend)
458 printf(" %s", ipaddr_string(cp));
468 if (ns_nprint(cp, bp) == NULL)
476 if ((cp = ns_nprint(cp, bp)) == NULL)
479 if ((cp = ns_nprint(cp, bp)) == NULL)
481 if (cp + 5 * 4 > snapend)
483 printf(" %u", EXTRACT_32BITS(cp));
485 printf(" %u", EXTRACT_32BITS(cp));
487 printf(" %u", EXTRACT_32BITS(cp));
489 printf(" %u", EXTRACT_32BITS(cp));
491 printf(" %u", EXTRACT_32BITS(cp));
496 if (cp + 2 > snapend)
498 if (ns_nprint(cp + 2, bp) == NULL)
500 printf(" %d", EXTRACT_16BITS(cp));
505 (void)ns_cprint(cp, bp);
510 if (cp + sizeof(struct in6_addr) > snapend)
512 printf(" %s", ip6addr_string(cp));
521 pbyte = (pbit & ~7) / 8;
523 printf(" %u(bad plen)", pbit);
525 } else if (pbit < 128) {
526 memset(&a, 0, sizeof(a));
527 memcpy(&a.s6_addr[pbyte], cp + 1, sizeof(a) - pbyte);
528 printf(" %u %s", pbit, ip6addr_string(&a));
532 if (ns_nprint(cp + 1 + sizeof(a) - pbyte, bp) == NULL)
540 printf(" UDPsize=%u", class);
543 case T_UNSPECA: /* One long string */
544 if (cp + len > snapend)
546 fn_printn(cp, len, snapend);
549 return (rp); /* XXX This isn't always right */
553 ns_print(register const u_char *bp, u_int length)
555 register const HEADER *np;
556 register int qdcount, ancount, nscount, arcount;
557 register const u_char *cp = NULL;
559 np = (const HEADER *)bp;
561 /* get the byte-order right */
562 qdcount = ntohs(np->qdcount);
563 ancount = ntohs(np->ancount);
564 nscount = ntohs(np->nscount);
565 arcount = ntohs(np->arcount);
568 /* this is a response */
569 printf(" %d%s%s%s%s%s%s",
571 ns_ops[DNS_OPCODE(np)],
572 ns_resp[DNS_RCODE(np)],
573 DNS_AA(np)? "*" : "",
574 DNS_RA(np)? "" : "-",
575 DNS_TC(np)? "|" : "",
576 DNS_CD(np)? "%" : "");
579 printf(" [%dq]", qdcount);
580 /* Print QUESTION section on -vv */
582 fputs(" q:", stdout);
583 if ((cp = ns_qprint((const u_char *)(np + 1), bp))
587 if ((cp = ns_nskip((const u_char *)(np + 1), bp))
592 printf(" %d/%d/%d", ancount, nscount, arcount);
594 if ((cp = ns_rprint(cp, bp)) == NULL)
596 while (ancount-- && cp < snapend) {
598 if ((cp = ns_rprint(cp, bp)) == NULL)
602 /* Print NS and AR sections on -vv */
604 if (nscount-- && cp < snapend) {
605 fputs(" ns:", stdout);
606 if ((cp = ns_rprint(cp, bp)) == NULL)
608 while (nscount-- && cp < snapend) {
610 if ((cp = ns_rprint(cp, bp)) == NULL)
614 if (arcount-- && cp < snapend) {
615 fputs(" ar:", stdout);
616 if ((cp = ns_rprint(cp, bp)) == NULL)
618 while (arcount-- && cp < snapend) {
620 if ((cp = ns_rprint(cp, bp)) == NULL)
627 /* this is a request */
628 printf(" %d%s%s%s", ntohs(np->id), ns_ops[DNS_OPCODE(np)],
629 DNS_RD(np) ? "+" : "",
630 DNS_AD(np) ? "$" : "");
633 if (*(((u_short *)np)+1) & htons(0x6cf))
634 printf(" [b2&3=0x%x]", ntohs(*(((u_short *)np)+1)));
636 if (DNS_OPCODE(np) == IQUERY) {
638 printf(" [%dq]", qdcount);
640 printf(" [%da]", ancount);
644 printf(" [%da]", ancount);
646 printf(" [%dq]", qdcount);
649 printf(" [%dn]", nscount);
651 printf(" [%dau]", arcount);
654 cp = ns_qprint((const u_char *)(np + 1),
658 if ((cp = ns_rprint(cp, bp)) == NULL)
660 while (qdcount-- && cp < snapend) {
661 cp = ns_qprint((const u_char *)cp,
665 if ((cp = ns_rprint(cp, bp)) == NULL)
670 /* Print remaining sections on -vv */
673 if ((cp = ns_rprint(cp, bp)) == NULL)
675 while (ancount-- && cp < snapend) {
677 if ((cp = ns_rprint(cp, bp)) == NULL)
681 if (nscount-- && cp < snapend) {
682 fputs(" ns:", stdout);
683 if ((cp = ns_rprint(cp, bp)) == NULL)
685 while (nscount-- && cp < snapend) {
687 if ((cp = ns_rprint(cp, bp)) == NULL)
691 if (arcount-- && cp < snapend) {
692 fputs(" ar:", stdout);
693 if ((cp = ns_rprint(cp, bp)) == NULL)
695 while (arcount-- && cp < snapend) {
697 if ((cp = ns_rprint(cp, bp)) == NULL)
703 printf(" (%d)", length);