X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/11f73ad248fa22461ca040baa8dc94b864509efa..5287bffd3f4fa1fda9d7734b45f8cf02391d3855:/print-domain.c diff --git a/print-domain.c b/print-domain.c index c3066f7d..3eea6ac7 100644 --- a/print-domain.c +++ b/print-domain.c @@ -19,6 +19,8 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ +/* \summary: Domain Name System (DNS) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -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) { @@ -210,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; } @@ -329,11 +332,11 @@ ns_qprint(netdissect_options *ndo, return(NULL); /* print the qtype */ - i = EXTRACT_16BITS(cp); + i = EXTRACT_BE_16BITS(cp); cp += 2; ND_PRINT((ndo, " %s", tok2str(ns_type2str, "Type%d", i))); /* print the qclass (if it's not IN) */ - i = EXTRACT_16BITS(cp); + i = EXTRACT_BE_16BITS(cp); cp += 2; if (is_mdns) class = (i & ~C_QU); @@ -370,10 +373,10 @@ ns_rprint(netdissect_options *ndo, return (ndo->ndo_snapend); /* print the type/qtype */ - typ = EXTRACT_16BITS(cp); + typ = EXTRACT_BE_16BITS(cp); cp += 2; /* print the class (if it's not IN and the type isn't OPT) */ - i = EXTRACT_16BITS(cp); + i = EXTRACT_BE_16BITS(cp); cp += 2; if (is_mdns) class = (i & ~C_CACHE_FLUSH); @@ -389,13 +392,13 @@ ns_rprint(netdissect_options *ndo, if (typ == T_OPT) { /* get opt flags */ cp += 2; - opt_flags = EXTRACT_16BITS(cp); + opt_flags = EXTRACT_BE_16BITS(cp); /* ignore rest of ttl field */ cp += 2; } else if (ndo->ndo_vflag > 2) { /* print ttl */ ND_PRINT((ndo, " [")); - relts_print(ndo, EXTRACT_32BITS(cp)); + unsigned_relts_print(ndo, EXTRACT_BE_32BITS(cp)); ND_PRINT((ndo, "]")); cp += 4; } else { @@ -403,7 +406,7 @@ ns_rprint(netdissect_options *ndo, cp += 4; } - len = EXTRACT_16BITS(cp); + len = EXTRACT_BE_16BITS(cp); cp += 2; rp = cp + len; @@ -416,7 +419,7 @@ ns_rprint(netdissect_options *ndo, case T_A: if (!ND_TTEST2(*cp, sizeof(struct in_addr))) return(NULL); - ND_PRINT((ndo, " %s", intoa(htonl(EXTRACT_32BITS(cp))))); + ND_PRINT((ndo, " %s", intoa(htonl(EXTRACT_BE_32BITS(cp))))); break; case T_NS: @@ -441,15 +444,15 @@ ns_rprint(netdissect_options *ndo, return(NULL); if (!ND_TTEST2(*cp, 5 * 4)) return(NULL); - ND_PRINT((ndo, " %u", EXTRACT_32BITS(cp))); + ND_PRINT((ndo, " %u", EXTRACT_BE_32BITS(cp))); cp += 4; - ND_PRINT((ndo, " %u", EXTRACT_32BITS(cp))); + ND_PRINT((ndo, " %u", EXTRACT_BE_32BITS(cp))); cp += 4; - ND_PRINT((ndo, " %u", EXTRACT_32BITS(cp))); + ND_PRINT((ndo, " %u", EXTRACT_BE_32BITS(cp))); cp += 4; - ND_PRINT((ndo, " %u", EXTRACT_32BITS(cp))); + ND_PRINT((ndo, " %u", EXTRACT_BE_32BITS(cp))); cp += 4; - ND_PRINT((ndo, " %u", EXTRACT_32BITS(cp))); + ND_PRINT((ndo, " %u", EXTRACT_BE_32BITS(cp))); cp += 4; break; case T_MX: @@ -458,7 +461,7 @@ ns_rprint(netdissect_options *ndo, return(NULL); if (ns_nprint(ndo, cp + 2, bp) == NULL) return(NULL); - ND_PRINT((ndo, " %d", EXTRACT_16BITS(cp))); + ND_PRINT((ndo, " %d", EXTRACT_BE_16BITS(cp))); break; case T_TXT: @@ -477,8 +480,8 @@ ns_rprint(netdissect_options *ndo, return(NULL); if (ns_nprint(ndo, cp + 6, bp) == NULL) return(NULL); - ND_PRINT((ndo, ":%d %d %d", EXTRACT_16BITS(cp + 4), - EXTRACT_16BITS(cp), EXTRACT_16BITS(cp + 2))); + ND_PRINT((ndo, ":%d %d %d", EXTRACT_BE_16BITS(cp + 4), + EXTRACT_BE_16BITS(cp), EXTRACT_BE_16BITS(cp + 2))); break; case T_AAAA: @@ -547,23 +550,23 @@ ns_rprint(netdissect_options *ndo, cp += 6; if (!ND_TTEST2(*cp, 2)) return(NULL); - ND_PRINT((ndo, " fudge=%u", EXTRACT_16BITS(cp))); + ND_PRINT((ndo, " fudge=%u", EXTRACT_BE_16BITS(cp))); cp += 2; if (!ND_TTEST2(*cp, 2)) return(NULL); - ND_PRINT((ndo, " maclen=%u", EXTRACT_16BITS(cp))); - cp += 2 + EXTRACT_16BITS(cp); + ND_PRINT((ndo, " maclen=%u", EXTRACT_BE_16BITS(cp))); + cp += 2 + EXTRACT_BE_16BITS(cp); if (!ND_TTEST2(*cp, 2)) return(NULL); - ND_PRINT((ndo, " origid=%u", EXTRACT_16BITS(cp))); + ND_PRINT((ndo, " origid=%u", EXTRACT_BE_16BITS(cp))); cp += 2; if (!ND_TTEST2(*cp, 2)) return(NULL); - ND_PRINT((ndo, " error=%u", EXTRACT_16BITS(cp))); + ND_PRINT((ndo, " error=%u", EXTRACT_BE_16BITS(cp))); cp += 2; if (!ND_TTEST2(*cp, 2)) return(NULL); - ND_PRINT((ndo, " otherlen=%u", EXTRACT_16BITS(cp))); + ND_PRINT((ndo, " otherlen=%u", EXTRACT_BE_16BITS(cp))); cp += 2; } } @@ -571,7 +574,7 @@ ns_rprint(netdissect_options *ndo, } void -ns_print(netdissect_options *ndo, +domain_print(netdissect_options *ndo, register const u_char *bp, u_int length, int is_mdns) { register const HEADER *np; @@ -582,15 +585,15 @@ ns_print(netdissect_options *ndo, np = (const HEADER *)bp; ND_TCHECK(*np); /* get the byte-order right */ - qdcount = EXTRACT_16BITS(&np->qdcount); - ancount = EXTRACT_16BITS(&np->ancount); - nscount = EXTRACT_16BITS(&np->nscount); - arcount = EXTRACT_16BITS(&np->arcount); + qdcount = EXTRACT_BE_16BITS(&np->qdcount); + ancount = EXTRACT_BE_16BITS(&np->ancount); + nscount = EXTRACT_BE_16BITS(&np->nscount); + arcount = EXTRACT_BE_16BITS(&np->arcount); if (DNS_QR(np)) { /* this is a response */ ND_PRINT((ndo, "%d%s%s%s%s%s%s", - EXTRACT_16BITS(&np->id), + EXTRACT_BE_16BITS(&np->id), ns_ops[DNS_OPCODE(np)], ns_resp[DNS_RCODE(np)], DNS_AA(np)? "*" : "", @@ -603,7 +606,7 @@ ns_print(netdissect_options *ndo, /* Print QUESTION section on -vv */ cp = (const u_char *)(np + 1); while (qdcount--) { - if (qdcount < EXTRACT_16BITS(&np->qdcount) - 1) + if (qdcount < EXTRACT_BE_16BITS(&np->qdcount) - 1) ND_PRINT((ndo, ",")); if (ndo->ndo_vflag > 1) { ND_PRINT((ndo, " q:")); @@ -657,12 +660,12 @@ ns_print(netdissect_options *ndo, } else { /* this is a request */ - ND_PRINT((ndo, "%d%s%s%s", EXTRACT_16BITS(&np->id), ns_ops[DNS_OPCODE(np)], - DNS_RD(np) ? "+" : "", - DNS_CD(np) ? "%" : "")); + ND_PRINT((ndo, "%d%s%s%s", EXTRACT_BE_16BITS(&np->id), ns_ops[DNS_OPCODE(np)], + DNS_RD(np) ? "+" : "", + DNS_CD(np) ? "%" : "")); /* any weirdness? */ - b2 = EXTRACT_16BITS(((const u_short *)np)+1); + b2 = EXTRACT_BE_16BITS(((const u_short *)np) + 1); if (b2 & 0x6cf) ND_PRINT((ndo, " [b2&3=0x%x]", b2));