summaryrefslogtreecommitdiff
path: root/packet-dns.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2000-04-12 06:59:28 +0000
committerGuy Harris <guy@alum.mit.edu>2000-04-12 06:59:28 +0000
commit8512fc4d739dd902f60e29a0a1b76e3c8b47ea8d (patch)
treeb5c710fb945f4171c5ff1d1509e14ee7d4ef8dd9 /packet-dns.c
parentdf5f3b52ceb29d5be3feb40180c7f22ea2f60728 (diff)
downloadwireshark-8512fc4d739dd902f60e29a0a1b76e3c8b47ea8d.tar.gz
Catch "loops" in compressed DNS names the same way the BSD DNS resolver,
and BIND, do, by counting the number of characters we look at and, if when we see a pointer, we see we've already looked at as many characters as there are in the DNS packet, we conclude that we're looping. Also, check for pointers that point past the end of the packet (not just past the end of the captured portion of the packet, i.e. cases where we didn't capture all of the packet, but cases where the packet is actually malformed). svn path=/trunk/; revision=1830
Diffstat (limited to 'packet-dns.c')
-rw-r--r--packet-dns.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/packet-dns.c b/packet-dns.c
index f744baa3ac..c82625943a 100644
--- a/packet-dns.c
+++ b/packet-dns.c
@@ -1,7 +1,7 @@
/* packet-dns.c
* Routines for DNS packet disassembly
*
- * $Id: packet-dns.c,v 1.41 2000/04/04 06:17:28 guy Exp $
+ * $Id: packet-dns.c,v 1.42 2000/04/12 06:59:28 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -330,6 +330,8 @@ get_dns_name(const u_char *pd, int offset, int dns_data_offset,
const u_char *dptr = dp;
char *np = name;
int len = -1;
+ int chars_processed = 0;
+ int data_size = pi.len - dns_data_offset;
u_int component_len;
maxname--; /* reserve space for the trailing '\0' */
@@ -340,6 +342,7 @@ get_dns_name(const u_char *pd, int offset, int dns_data_offset,
offset++;
if (component_len == 0)
break;
+ chars_processed++;
switch (component_len & 0xc0) {
case 0x00:
@@ -361,6 +364,7 @@ get_dns_name(const u_char *pd, int offset, int dns_data_offset,
component_len--;
dp++;
offset++;
+ chars_processed++;
}
break;
@@ -370,18 +374,30 @@ get_dns_name(const u_char *pd, int offset, int dns_data_offset,
case 0xc0:
/* Pointer. */
- /* XXX - check to make sure we aren't looping, by keeping track
- of how many characters are in the DNS packet, and of how many
- characters we've looked at, and quitting if the latter
- becomes bigger than the former. */
if (!BYTES_ARE_IN_FRAME(offset, 1))
goto overflow;
offset = dns_data_offset + (((component_len & ~0xc0) << 8) | (*dp++));
+ chars_processed++;
+
/* If "len" is negative, we are still working on the original name,
not something pointed to by a pointer, and so we should set "len"
to the length of the original name. */
if (len < 0)
len = dp - dptr;
+
+ if (offset >= pi.len) {
+ strcpy(name, "<Name contains a pointer that goes past the end of the packet>");
+ return len;
+ }
+
+ /* 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) {
+ strcpy(name, "<Name contains a pointer that loops>");
+ return len;
+ }
+
dp = pd + offset;
break; /* now continue processing from there */
}