aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2004-01-01 23:36:50 +0000
committerGuy Harris <guy@alum.mit.edu>2004-01-01 23:36:50 +0000
commit08d8a8d08738c8500934762650aac4a8831249e5 (patch)
tree4d2c79a3c9bf45c3f8d041e59149d38cb50e4af5
parent5eceafcd703a3b5a6e108cd86095315ab657b6e6 (diff)
Make the RTSP packet handling more like the HTTP packet handling.
svn path=/trunk/; revision=9516
-rw-r--r--packet-rtsp.c112
1 files changed, 81 insertions, 31 deletions
diff --git a/packet-rtsp.c b/packet-rtsp.c
index 274c12c6ba..7afbd849b6 100644
--- a/packet-rtsp.c
+++ b/packet-rtsp.c
@@ -4,7 +4,7 @@
* Jason Lango <jal@netapp.com>
* Liberally copied from packet-http.c, by Guy Harris <guy@alum.mit.edu>
*
- * $Id: packet-rtsp.c,v 1.58 2003/12/31 09:58:55 guy Exp $
+ * $Id: packet-rtsp.c,v 1.59 2004/01/01 23:36:50 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -472,7 +472,7 @@ static int
dissect_rtspmessage(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree)
{
- proto_tree *rtsp_tree;
+ proto_tree *rtsp_tree = NULL;
proto_item *ti = NULL;
const guchar *line;
gint next_offset;
@@ -480,6 +480,7 @@ dissect_rtspmessage(tvbuff_t *tvb, int offset, packet_info *pinfo,
int orig_offset;
int first_linelen, linelen;
gboolean is_request_or_reply;
+ gboolean saw_req_resp_or_header;
guchar c;
rtsp_type_t rtsp_type;
gboolean is_mime_header;
@@ -495,8 +496,12 @@ dissect_rtspmessage(tvbuff_t *tvb, int offset, packet_info *pinfo,
* is not longer than what's in the buffer, so the
* "tvb_get_ptr()" call won't throw an exception.
*/
- first_linelen = tvb_find_line_end(tvb, offset, -1, &next_offset,
+ first_linelen = tvb_find_line_end(tvb, offset,
+ tvb_ensure_length_remaining(tvb, offset), &next_offset,
FALSE);
+ /*
+ * Is the first line a request or response?
+ */
line = tvb_get_ptr(tvb, offset, first_linelen);
is_request_or_reply = is_rtsp_request_or_reply(line, first_linelen,
&rtsp_type);
@@ -516,31 +521,34 @@ dissect_rtspmessage(tvbuff_t *tvb, int offset, packet_info *pinfo,
}
}
- orig_offset = offset;
- rtsp_tree = NULL;
- if (tree) {
- ti = proto_tree_add_item(tree, proto_rtsp, tvb, offset, -1,
- FALSE);
- rtsp_tree = proto_item_add_subtree(ti, ett_rtsp);
- }
-
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTSP");
if (check_col(pinfo->cinfo, COL_INFO)) {
/*
* Put the first line from the buffer into the summary
* if it's an RTSP request or reply (but leave out the
* line terminator).
* Otherwise, just call it a continuation.
+ *
+ * Note that "tvb_find_line_end()" will return a value that
+ * is not longer than what's in the buffer, so the
+ * "tvb_get_ptr()" call won't throw an exception.
*/
- linelen = tvb_find_line_end(tvb, offset, -1, &next_offset,
- FALSE);
- line = tvb_get_ptr(tvb, offset, linelen);
+ line = tvb_get_ptr(tvb, offset, first_linelen);
if (is_request_or_reply)
col_add_str(pinfo->cinfo, COL_INFO,
- format_text(line, linelen));
+ format_text(line, first_linelen));
else
col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
}
+ orig_offset = offset;
+ if (tree) {
+ ti = proto_tree_add_item(tree, proto_rtsp, tvb, offset, -1,
+ FALSE);
+ rtsp_tree = proto_item_add_subtree(ti, ett_rtsp);
+ }
+
/*
* We haven't yet seen a Content-Length header.
*/
@@ -549,7 +557,8 @@ dissect_rtspmessage(tvbuff_t *tvb, int offset, packet_info *pinfo,
/*
* Process the packet data, a line at a time.
*/
- while (tvb_offset_exists(tvb, offset)) {
+ saw_req_resp_or_header = FALSE; /* haven't seen anything yet */
+ while (tvb_reported_length_remaining(tvb, offset) != 0) {
/*
* We haven't yet concluded that this is a MIME header.
*/
@@ -558,8 +567,11 @@ dissect_rtspmessage(tvbuff_t *tvb, int offset, packet_info *pinfo,
/*
* Find the end of the line.
*/
- linelen = tvb_find_line_end(tvb, offset, -1, &next_offset,
+ linelen = tvb_find_line_end(tvb, offset,
+ tvb_ensure_length_remaining(tvb, offset), &next_offset,
FALSE);
+ if (linelen < 0)
+ return -1;
/*
* Get a buffer that refers to the line.
@@ -568,8 +580,7 @@ dissect_rtspmessage(tvbuff_t *tvb, int offset, packet_info *pinfo,
lineend = line + linelen;
/*
- * OK, does it look like an RTSP request or
- * response?
+ * OK, does it look like an RTSP request or response?
*/
is_request_or_reply = is_rtsp_request_or_reply(line, linelen,
&rtsp_type);
@@ -577,14 +588,14 @@ dissect_rtspmessage(tvbuff_t *tvb, int offset, packet_info *pinfo,
goto is_rtsp;
/*
- * No. Does it look like a blank line (as would
- * appear at the end of an RTSP request)?
+ * No. Does it look like a blank line (as would appear
+ * at the end of an RTSP request)?
*/
if (linelen == 0)
goto is_rtsp; /* Yes. */
/*
- * No. Does it look like a MIME header?
+ * No. Does it look like a header?
*/
linep = line;
while (linep < lineend) {
@@ -635,6 +646,32 @@ dissect_rtspmessage(tvbuff_t *tvb, int offset, packet_info *pinfo,
}
}
+ /*
+ * We haven't seen the colon, but everything else looks
+ * OK for a header line.
+ *
+ * If we've already seen an RTSP request or response
+ * line, or a header line, and we're at the end of
+ * the tvbuff, we assume this is an incomplete header
+ * line. (We quit this loop after seeing a blank line,
+ * so if we've seen a request or response line, or a
+ * header line, this is probably more of the request
+ * or response we're presumably seeing. There is some
+ * risk of false positives, but the same applies for
+ * full request or response lines or header lines,
+ * although that's less likely.)
+ *
+ * We throw an exception in that case, by checking for
+ * the existence of the next byte after the last one
+ * in the line. If it exists, "tvb_ensure_bytes_exist()"
+ * throws no exception, and we fall through to the
+ * "not RTSP" case. If it doesn't exist,
+ * "tvb_ensure_bytes_exist()" will throw the appropriate
+ * exception.
+ */
+ if (saw_req_resp_or_header)
+ tvb_ensure_bytes_exist(tvb, offset, linelen + 1);
+
not_rtsp:
/*
* We don't consider this part of an RTSP request or
@@ -646,6 +683,24 @@ dissect_rtspmessage(tvbuff_t *tvb, int offset, packet_info *pinfo,
/*
* Process this line.
*/
+ if (linelen == 0) {
+ /*
+ * This is a blank line, which means that
+ * whatever follows it isn't part of this
+ * request or reply.
+ */
+ proto_tree_add_text(rtsp_tree, tvb, offset,
+ next_offset - offset, "%s",
+ tvb_format_text(tvb, offset, next_offset - offset));
+ offset = next_offset;
+ break;
+ }
+
+ /*
+ * Not a blank line - either a request, a reply, or a header
+ * line.
+ */
+ saw_req_resp_or_header = TRUE;
if (rtsp_tree) {
switch (rtsp_type) {
@@ -718,8 +773,9 @@ dissect_rtspmessage(tvbuff_t *tvb, int offset, packet_info *pinfo,
* processed as RTSP payload is the minimum of the content
* length and the amount of data remaining in the frame.
*
- * If no content length was supplied, the amount of data to be
- * processed is the amount of data remaining in the frame.
+ * If no content length was supplied (or if a bad content length
+ * was supplied), the amount of data to be processed is the amount
+ * of data remaining in the frame.
*
* XXX - RFC 2326 says that a content length must be specified
* in requests that have a body, although section 4.4 speaks
@@ -809,8 +865,7 @@ dissect_rtspmessage(tvbuff_t *tvb, int offset, packet_info *pinfo,
/*
* We've processed "datalen" bytes worth of data
* (which may be no data at all); advance the
- * offset past whatever data we've processed, so they
- * don't process it.
+ * offset past whatever data we've processed.
*/
offset += datalen;
}
@@ -892,11 +947,6 @@ dissect_rtsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
int offset = 0;
int len;
- if (check_col(pinfo->cinfo, COL_PROTOCOL))
- col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTSP");
- if (check_col(pinfo->cinfo, COL_INFO))
- col_clear(pinfo->cinfo, COL_INFO);
-
while (tvb_reported_length_remaining(tvb, offset) != 0) {
len = (tvb_get_guint8(tvb, offset) == RTSP_FRAMEHDR)
? dissect_rtspinterleaved(tvb, offset, pinfo, tree)