aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am4
-rw-r--r--Makefile.nmake3
-rw-r--r--packet-http.c124
-rw-r--r--rreh.c171
-rw-r--r--rreh.h37
5 files changed, 224 insertions, 115 deletions
diff --git a/Makefile.am b/Makefile.am
index 275c458c78..bd5ee9ac6f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,7 @@
# Makefile.am
# Automake file for Ethereal
#
-# $Id: Makefile.am,v 1.676 2003/12/21 04:27:04 jmayer Exp $
+# $Id: Makefile.am,v 1.677 2003/12/22 00:57:33 guy Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@ethereal.com>
@@ -843,6 +843,8 @@ ETHEREAL_COMMON_SRC = \
ringbuffer.c \
ringbuffer.h \
rpc_defrag.h \
+ rreh.c \
+ rreh.h \
rtp_pt.h \
sctpppids.h \
smb.h \
diff --git a/Makefile.nmake b/Makefile.nmake
index c76747fed6..03c5ce91f0 100644
--- a/Makefile.nmake
+++ b/Makefile.nmake
@@ -1,7 +1,7 @@
## Makefile for building ethereal.exe with Microsoft C and nmake
## Use: $(MAKE) /$(MAKEFLAGS) -f makefile.nmake
#
-# $Id: Makefile.nmake,v 1.376 2003/12/16 05:07:48 guy Exp $
+# $Id: Makefile.nmake,v 1.377 2003/12/22 00:57:33 guy Exp $
include config.nmake
include <win32.mak>
@@ -472,6 +472,7 @@ ETHEREAL_COMMON_OBJECTS = \
reassemble.obj \
register.obj \
ringbuffer.obj \
+ rreh.obj \
t35.obj \
tap.obj \
timestats.obj \
diff --git a/packet-http.c b/packet-http.c
index 269f02019c..13d7925da4 100644
--- a/packet-http.c
+++ b/packet-http.c
@@ -6,7 +6,7 @@
* Copyright 2002, Tim Potter <tpot@samba.org>
* Copyright 1999, Andrew Tridgell <tridge@samba.org>
*
- * $Id: packet-http.c,v 1.76 2003/12/07 03:34:36 guy Exp $
+ * $Id: packet-http.c,v 1.77 2003/12/22 00:57:33 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -39,6 +39,7 @@
#include <epan/strutil.h>
#include "util.h"
+#include "rreh.h"
#include "packet-http.h"
#include "prefs.h"
@@ -184,7 +185,6 @@ dissect_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
gint offset = 0;
const guchar *line;
gint next_offset;
- gint next_offset_sav;
const guchar *linep, *lineend;
int first_linelen, linelen;
gboolean is_request_or_reply;
@@ -196,8 +196,6 @@ dissect_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
int req_strlen;
proto_tree *req_tree;
int colon_offset;
- long int content_length;
- gboolean content_length_found = FALSE;
entity_headers_t entity_headers;
dissector_handle_t handle;
gboolean dissected;
@@ -216,117 +214,17 @@ dissect_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
is_request_or_reply = is_http_request_or_reply(line, first_linelen,
&http_type, NULL, NULL);
if (is_request_or_reply) {
- /*
+ /*
* Yes, it's a request or response.
- * Do header desegmentation if we've been told to.
- *
- * RFC 2616 defines HTTP messages as being either of the
- * Request or the Response type
- * (HTTP-message = Request | Response).
- * Request and Response are defined as:
- * Request = Request-Line
- * *(( general-header
- * | request-header
- * | entity-header ) CRLF)
- * CRLF
- * [ message-body ]
- * Response = Status-Line
- * *(( general-header
- * | response-header
- * | entity-header ) CRLF)
- * CRLF
- * [ message-body ]
- * that's why we can always assume two consecutive line
- * endings (we allow CR, LF, or CRLF, as some clients
- * or servers might not use a full CRLF) to mark the end
- * of the headers. The worst thing that would happen
- * otherwise would be the packet not being desegmented
- * or being interpreted as only headers.
- */
-
- /*
- * If header desegmentation is activated, check that all
- * headers are in this tvbuff (search for an empty line
- * marking end of headers) or request one more byte (we
- * don't know how many bytes we'll need, so we just ask
- * for one).
+ * Do header desegmentation if we've been told to,
+ * and do body desegmentation if we've been told to and
+ * we find a Content-Length header.
*/
- if (http_desegment_headers && pinfo->can_desegment) {
- next_offset = offset;
- for (;;) {
- next_offset_sav = next_offset;
-
- /*
- * Request one more byte if there're no
- * bytes left.
- */
- if (tvb_offset_exists(tvb, next_offset) == FALSE) {
- pinfo->desegment_offset = offset;
- pinfo->desegment_len = 1;
- return;
- }
-
- /*
- * Request one more byte if we cannot find a
- * header (i.e. a line end).
- */
- linelen = tvb_find_line_end(tvb, next_offset,
- -1, &next_offset, TRUE);
- if (linelen == -1) {
- /*
- * Not enough data; ask for one more
- * byte.
- */
- pinfo->desegment_offset = offset;
- pinfo->desegment_len = 1;
- return;
- } else if (linelen == 0) {
- /*
- * We found the end of the headers.
- */
- break;
- }
-
- /*
- * Is this a Content-Length header?
- * If not, it either means that we are in
- * a different header line, or that we are
- * at the end of the headers, or that there
- * isn't enough data; the two latter cases
- * have already been handled above.
- */
- if (http_desegment_body) {
- /*
- * Check if we've found Content-Length.
- */
- if (tvb_strneql(tvb, next_offset_sav,
- "Content-Length:", 15) == 0) {
- if (sscanf(
- tvb_get_string(tvb,
- next_offset_sav + 15,
- linelen - 15),
- "%li", &content_length)
- == 1)
- content_length_found = TRUE;
- }
- }
- }
- }
- }
-
- /*
- * The above loop ends when we reached the end of the headers, so
- * there should be content_length byte after the 4 terminating bytes
- * and next_offset points to after the end of the headers.
- */
- if (http_desegment_body && content_length_found) {
- /* next_offset has been set because content-length was found */
- if (!tvb_bytes_exist(tvb, next_offset, content_length)) {
- gint length = tvb_length_remaining(tvb, next_offset);
- if (length == -1)
- length = 0;
- pinfo->desegment_offset = offset;
- pinfo->desegment_len = content_length - length;
+ if (!rreh_do_reassembly(tvb, pinfo, http_desegment_headers,
+ http_desegment_body)) {
+ /*
+ * More data needed for desegmentation.
+ */
return;
}
}
diff --git a/rreh.c b/rreh.c
new file mode 100644
index 0000000000..49d2efbed3
--- /dev/null
+++ b/rreh.c
@@ -0,0 +1,171 @@
+/* rreh.c
+ * Routines handling protocols with a request/response line, entity headers,
+ * a blank line, and an optional body.
+ *
+ * $Id: rreh.c,v 1.1 2003/12/22 00:57:34 guy Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib.h>
+#include <epan/packet.h>
+#include <epan/strutil.h>
+
+#include "rreh.h"
+
+/*
+ * Optionally do reassembly of the request/response line, entity headers,
+ * and body.
+ */
+gboolean
+rreh_do_reassembly(tvbuff_t *tvb, packet_info *pinfo,
+ gboolean desegment_headers, gboolean desegment_body)
+{
+ gint offset = 0;
+ gint next_offset;
+ gint next_offset_sav;
+ int linelen;
+ long int content_length;
+ gboolean content_length_found = FALSE;
+
+ /*
+ * Do header desegmentation if we've been told to.
+ *
+ * RFC 2616 defines HTTP messages as being either of the
+ * Request or the Response type
+ * (HTTP-message = Request | Response).
+ * Request and Response are defined as:
+ * Request = Request-Line
+ * *(( general-header
+ * | request-header
+ * | entity-header ) CRLF)
+ * CRLF
+ * [ message-body ]
+ * Response = Status-Line
+ * *(( general-header
+ * | response-header
+ * | entity-header ) CRLF)
+ * CRLF
+ * [ message-body ]
+ * that's why we can always assume two consecutive line
+ * endings (we allow CR, LF, or CRLF, as some clients
+ * or servers might not use a full CRLF) to mark the end
+ * of the headers. The worst thing that would happen
+ * otherwise would be the packet not being desegmented
+ * or being interpreted as only headers.
+ *
+ * RFC 2326 says RTSP works the same way; RFC 3261 says SIP
+ * works the same way.
+ */
+
+ /*
+ * If header desegmentation is activated, check that all
+ * headers are in this tvbuff (search for an empty line
+ * marking end of headers) or request one more byte (we
+ * don't know how many bytes we'll need, so we just ask
+ * for one).
+ */
+ if (desegment_headers && pinfo->can_desegment) {
+ next_offset = offset;
+ for (;;) {
+ next_offset_sav = next_offset;
+
+ /*
+ * Request one more byte if there're no
+ * bytes left.
+ */
+ if (tvb_offset_exists(tvb, next_offset) == FALSE) {
+ pinfo->desegment_offset = offset;
+ pinfo->desegment_len = 1;
+ return FALSE;
+ }
+
+ /*
+ * Request one more byte if we cannot find a
+ * header (i.e. a line end).
+ */
+ linelen = tvb_find_line_end(tvb, next_offset,
+ -1, &next_offset, TRUE);
+ if (linelen == -1) {
+ /*
+ * Not enough data; ask for one more
+ * byte.
+ */
+ pinfo->desegment_offset = offset;
+ pinfo->desegment_len = 1;
+ return FALSE;
+ } else if (linelen == 0) {
+ /*
+ * We found the end of the headers.
+ */
+ break;
+ }
+
+ /*
+ * Is this a Content-Length header?
+ * If not, it either means that we are in
+ * a different header line, or that we are
+ * at the end of the headers, or that there
+ * isn't enough data; the two latter cases
+ * have already been handled above.
+ */
+ if (desegment_body) {
+ /*
+ * Check if we've found Content-Length.
+ */
+ if (tvb_strneql(tvb, next_offset_sav,
+ "Content-Length:", 15) == 0) {
+ if (sscanf(
+ tvb_get_string(tvb,
+ next_offset_sav + 15,
+ linelen - 15),
+ "%li", &content_length)
+ == 1)
+ content_length_found = TRUE;
+ }
+ }
+ }
+ }
+
+ /*
+ * The above loop ends when we reached the end of the headers, so
+ * there should be content_length byte after the 4 terminating bytes
+ * and next_offset points to after the end of the headers.
+ */
+ if (desegment_body && content_length_found) {
+ /* next_offset has been set because content-length was found */
+ if (!tvb_bytes_exist(tvb, next_offset, content_length)) {
+ gint length = tvb_length_remaining(tvb, next_offset);
+ if (length == -1)
+ length = 0;
+ pinfo->desegment_offset = offset;
+ pinfo->desegment_len = content_length - length;
+ return FALSE;
+ }
+ }
+
+ /*
+ * No further desegmentation needed.
+ */
+ return TRUE;
+}
diff --git a/rreh.h b/rreh.h
new file mode 100644
index 0000000000..f76038c551
--- /dev/null
+++ b/rreh.h
@@ -0,0 +1,37 @@
+/* rreh.h
+ * Declarations of routines handling protocols with a request/response line,
+ * entity headers, a blank line, and an optional body.
+ *
+ * $Id: rreh.h,v 1.1 2003/12/22 00:57:34 guy Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __RREH_H__
+#define __RREH_H__
+
+/*
+ * Optionally do reassembly of the request/response line, entity headers,
+ * and body.
+ */
+extern gboolean
+rreh_do_reassembly(tvbuff_t *tvb, packet_info *pinfo,
+ gboolean desegment_headers, gboolean desegment_body);
+
+#endif