X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/8863fc0e5d6cc6bf64875fa4156ddfd54c6cf9c9..2d02497b02b040bd885825dba9230f86a8ffce0e:/print-domain.c diff --git a/print-domain.c b/print-domain.c index 00119568..9a2b9e85 100644 --- a/print-domain.c +++ b/print-domain.c @@ -19,20 +19,22 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define NETDISSECT_REWORKED +/* \summary: Domain Name System (DNS) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include "nameser.h" #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" -#include "extract.h" /* must come after interface.h */ +#include "addrtostr.h" +#include "extract.h" static const char *ns_ops[] = { "", " inv_q", " stat", " op3", " notify", " update", " op6", " op7", @@ -149,15 +151,14 @@ ns_nprint(netdissect_options *ndo, register u_int i, l; register const u_char *rp = NULL; register int compress = 0; - int chars_processed; int elt; - int data_size = ndo->ndo_snapend - bp; + u_int offset, max_offset; if ((l = labellen(ndo, cp)) == (u_int)-1) return(NULL); if (!ND_TTEST2(*cp, 1)) return(NULL); - chars_processed = 1; + max_offset = (u_int)(cp - bp); if (((i = *cp++) & INDIR_MASK) != INDIR_MASK) { compress = 0; rp = cp + l; @@ -172,24 +173,28 @@ ns_nprint(netdissect_options *ndo, } if (!ND_TTEST2(*cp, 1)) return(NULL); - cp = bp + (((i << 8) | *cp) & 0x3fff); + offset = (((i << 8) | *cp) & 0x3fff); + /* + * This must move backwards in the packet. + * No RFC explicitly says that, but BIND's + * name decompression code requires it, + * as a way of preventing infinite loops + * and other bad behavior, and it's probably + * what was intended (compress by pointing + * to domain name suffixes already seen in + * the packet). + */ + if (offset >= max_offset) { + ND_PRINT((ndo, "")); + return(NULL); + } + max_offset = offset; + cp = bp + offset; if ((l = labellen(ndo, cp)) == (u_int)-1) return(NULL); if (!ND_TTEST2(*cp, 1)) return(NULL); i = *cp++; - chars_processed++; - - /* - * If we've looked at every character in - * the message, this pointer will make - * us look at some character again, - * which means we're looping. - */ - if (chars_processed >= data_size) { - ND_PRINT((ndo, "")); - return (NULL); - } continue; } if ((i & INDIR_MASK) == EDNS0_MASK) { @@ -205,19 +210,17 @@ ns_nprint(netdissect_options *ndo, return(NULL); } } else { - if (fn_printn(cp, l, ndo->ndo_snapend)) + if (fn_printn(ndo, cp, l, ndo->ndo_snapend)) return(NULL); } cp += l; - chars_processed += l; ND_PRINT((ndo, ".")); if ((l = labellen(ndo, cp)) == (u_int)-1) return(NULL); if (!ND_TTEST2(*cp, 1)) return(NULL); i = *cp++; - chars_processed++; if (!compress) rp += l + 1; } @@ -236,7 +239,7 @@ ns_cprint(netdissect_options *ndo, if (!ND_TTEST2(*cp, 1)) return (NULL); i = *cp++; - if (fn_printn(cp, i, ndo->ndo_snapend)) + if (fn_printn(ndo, cp, i, ndo->ndo_snapend)) return (NULL); return (cp + i); } @@ -395,7 +398,7 @@ ns_rprint(netdissect_options *ndo, } else if (ndo->ndo_vflag > 2) { /* print ttl */ ND_PRINT((ndo, " [")); - relts_print(ndo, EXTRACT_32BITS(cp)); + unsigned_relts_print(ndo, EXTRACT_32BITS(cp)); ND_PRINT((ndo, "]")); cp += 4; } else { @@ -481,17 +484,14 @@ ns_rprint(netdissect_options *ndo, EXTRACT_16BITS(cp), EXTRACT_16BITS(cp + 2))); break; -#ifdef INET6 case T_AAAA: { - struct in6_addr addr; char ntop_buf[INET6_ADDRSTRLEN]; if (!ND_TTEST2(*cp, sizeof(struct in6_addr))) return(NULL); - memcpy(&addr, cp, sizeof(struct in6_addr)); ND_PRINT((ndo, " %s", - inet_ntop(AF_INET6, &addr, ntop_buf, sizeof(ntop_buf)))); + addrtostr6(cp, ntop_buf, sizeof(ntop_buf)))); break; } @@ -515,7 +515,7 @@ ns_rprint(netdissect_options *ndo, memset(&a, 0, sizeof(a)); memcpy(&a.s6_addr[pbyte], cp + 1, sizeof(a) - pbyte); ND_PRINT((ndo, " %u %s", pbit, - inet_ntop(AF_INET6, &a, ntop_buf, sizeof(ntop_buf)))); + addrtostr6(&a, ntop_buf, sizeof(ntop_buf)))); } if (pbit > 0) { ND_PRINT((ndo, " ")); @@ -524,18 +524,17 @@ ns_rprint(netdissect_options *ndo, } break; } -#endif /*INET6*/ case T_OPT: ND_PRINT((ndo, " UDPsize=%u", class)); if (opt_flags & 0x8000) - ND_PRINT((ndo, " OK")); + ND_PRINT((ndo, " DO")); break; case T_UNSPECA: /* One long string */ if (!ND_TTEST2(*cp, len)) return(NULL); - if (fn_printn(cp, len, ndo->ndo_snapend)) + if (fn_printn(ndo, cp, len, ndo->ndo_snapend)) return(NULL); break; @@ -581,7 +580,7 @@ ns_print(netdissect_options *ndo, register const HEADER *np; register int qdcount, ancount, nscount, arcount; register const u_char *cp; - u_int16_t b2; + uint16_t b2; np = (const HEADER *)bp; ND_TCHECK(*np); @@ -666,7 +665,7 @@ ns_print(netdissect_options *ndo, DNS_CD(np) ? "%" : "")); /* any weirdness? */ - b2 = EXTRACT_16BITS(((u_short *)np)+1); + b2 = EXTRACT_16BITS(((const u_short *)np)+1); if (b2 & 0x6cf) ND_PRINT((ndo, " [b2&3=0x%x]", b2));