X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/b638c78b40951d394e14dea3608f87a1cff9786f..2d02497b02b040bd885825dba9230f86a8ffce0e:/print-domain.c diff --git a/print-domain.c b/print-domain.c index 15974bfa..9a2b9e85 100644 --- a/print-domain.c +++ b/print-domain.c @@ -19,11 +19,13 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ +/* \summary: Domain Name System (DNS) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include "nameser.h" @@ -31,6 +33,7 @@ #include "netdissect.h" #include "addrtoname.h" +#include "addrtostr.h" #include "extract.h" static const char *ns_ops[] = { @@ -148,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; @@ -171,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) { @@ -209,14 +215,12 @@ ns_nprint(netdissect_options *ndo, } 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; } @@ -394,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 { @@ -480,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; } @@ -514,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, " ")); @@ -523,7 +524,6 @@ ns_rprint(netdissect_options *ndo, } break; } -#endif /*INET6*/ case T_OPT: ND_PRINT((ndo, " UDPsize=%u", class));