diff options
author | Guy Harris <guy@alum.mit.edu> | 2002-02-22 08:45:02 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2002-02-22 08:45:02 +0000 |
commit | 7b176b7096acc08e3f158311ac31a8b1f7239a4a (patch) | |
tree | 8d43ad1b61f6c22a9368e5d787724376de737931 /packet-dns.c | |
parent | cbda24e6120166fcd0f40399114f98531924275d (diff) |
Redo the DNS-over-TCP code to handle the DNS-over-TCP header being split
across segment boundaries and to, for each DNS-over-TCP PDU, create a
tvbuff containing the header and the body of the PDU, handing that to
the DNS PDU dissector.
svn path=/trunk/; revision=4776
Diffstat (limited to 'packet-dns.c')
-rw-r--r-- | packet-dns.c | 91 |
1 files changed, 59 insertions, 32 deletions
diff --git a/packet-dns.c b/packet-dns.c index ed615dc920..6b8ec359f0 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.80 2002/01/21 07:36:33 guy Exp $ + * $Id: packet-dns.c,v 1.81 2002/02/22 08:45:02 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -1751,10 +1751,11 @@ dissect_answer_records(tvbuff_t *tvb, int cur_off, int dns_data_offset, return cur_off - start_off; } -static int -dissect_dns_common(tvbuff_t *tvb, int offset, int msg_len, packet_info *pinfo, +static void +dissect_dns_common(tvbuff_t *tvb, int msg_len, packet_info *pinfo, proto_tree *tree, gboolean is_tcp) { + int offset = is_tcp ? 2 : 0; int dns_data_offset; column_info *cinfo; proto_tree *dns_tree = NULL, *field_tree; @@ -1807,7 +1808,7 @@ dissect_dns_common(tvbuff_t *tvb, int offset, int msg_len, packet_info *pinfo, isupdate = 0; if (tree) { - ti = proto_tree_add_protocol_format(tree, proto_dns, tvb, offset, msg_len, + ti = proto_tree_add_protocol_format(tree, proto_dns, tvb, 0, -1, "Domain Name System (%s)", (flags & F_RESPONSE) ? "response" : "query"); dns_tree = proto_item_add_subtree(ti, ett_dns); @@ -1939,67 +1940,93 @@ dissect_dns_common(tvbuff_t *tvb, int offset, int msg_len, packet_info *pinfo, cur_off += dissect_answer_records(tvb, cur_off, dns_data_offset, add, NULL, dns_tree, "Additional records"); } - - return cur_off; } static void dissect_dns_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { - dissect_dns_common(tvb, 0, tvb_length(tvb), pinfo, tree, FALSE); + dissect_dns_common(tvb, -1, pinfo, tree, FALSE); } static void dissect_dns_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { int offset = 0; + int length_remaining; guint16 plen; + int length; + tvbuff_t *next_tvb; + + while (tvb_reported_length_remaining(tvb, offset) != 0) { + length_remaining = tvb_length_remaining(tvb, offset); - for (;;) { /* - * XXX - should handle a length field split across segment - * boundaries. + * Can we do reassembly? + */ + if (dns_desegment && pinfo->can_desegment) { + /* + * Yes - is the DNS-over-TCP header split across + * segment boundaries? + */ + if (length_remaining < 2) { + /* + * Yes. Tell the TCP dissector where + * the data for this message starts in + * the data it handed us, and how many + * more bytes we need, and return. + */ + pinfo->desegment_offset = offset; + pinfo->desegment_len = 2 - length_remaining; + return; + } + } + + /* + * Get the length of the DNS packet. */ - if (!tvb_bytes_exist(tvb, offset, 2)) - break; plen = tvb_get_ntohs(tvb, offset); /* - * Desegmentation check. + * Can we do reassembly? */ - if (dns_desegment) { - if (pinfo->can_desegment - && plen > tvb_length_remaining(tvb, offset+2)) { + if (dns_desegment && pinfo->can_desegment) { + /* + * Yes - is the DNS packet split across segment + * boundaries? + */ + if (length_remaining < plen + 2) { /* - * This frame doesn't have all of the data - * for this message, but we can do reassembly - * on it. - * - * Tell the TCP dissector where the data for - * this message starts in the data it handed - * us, and how many more bytes we need, and - * return. + * Yes. Tell the TCP dissector where + * the data for this message starts in + * the data it handed us, and how many + * more bytes we need, and return. */ pinfo->desegment_offset = offset; pinfo->desegment_len = - plen - tvb_length_remaining(tvb, offset+2); + (plen + 2) - length_remaining; return; } } - offset += 2; + /* + * Construct a tvbuff containing the amount of the payload + * we have available. Make its reported length the + * amount of data in the DNS-over-TCP packet. + */ + length = length_remaining; + if (length > plen + 2) + length = plen + 2; + next_tvb = tvb_new_subset(tvb, offset, length, plen + 2); /* - * Is all of the DNS message in this TCP segment? + * Dissect the DNS-over-TCP packet. */ - if (tvb_reported_length_remaining(tvb, offset) < plen) - break; + dissect_dns_common(next_tvb, plen, pinfo, tree, TRUE); /* - * Yes - dissect it. + * Skip the DNS-over-TCP header and the payload. */ - offset = dissect_dns_common(tvb, offset, plen, pinfo, tree, - TRUE); + offset += plen + 2; } } |