Pass an HTTP message type to all HTTP subdissectors.

This gets complicated, because those subdissectors might be called by
other dissectors as well.  We need a better way of passing that sort of
out-of-bound information.

Pull some routines used for processing Content-Type parameters into
common code; we can't guarantee that the media parameters passed in
would be writable (passing it as *the* data hid that; passing a
structure with that *and* the HTTP message type revealed it), so don't
convert it to lower-case in place.

Use that information, if available, to determine whether an IPP message
is a requet or a response.

Change-Id: I4bccc9f05cd0b14ad445be7ab37b3d884d841325
Reviewed-on: https://code.wireshark.org/review/17216
Reviewed-by: Guy Harris <guy@alum.mit.edu>
This commit is contained in:
Guy Harris 2016-08-21 23:33:23 -07:00
parent efdcb25360
commit 5825f59ddc
18 changed files with 379 additions and 174 deletions

View File

@ -127,6 +127,7 @@ set(LIBWIRESHARK_FILES
in_cksum.c
ipproto.c
ipv4.c
media_params.c
next_tvb.c
oids.c
osi-utils.c

View File

@ -89,6 +89,7 @@ LIBWIRESHARK_SRC = \
in_cksum.c \
ipproto.c \
ipv4.c \
media_params.c \
next_tvb.c \
oids.c \
osi-utils.c \
@ -237,6 +238,7 @@ LIBWIRESHARK_INCLUDES = \
ipv6.h \
lapd_sapi.h \
llcsaps.h \
media_params.h \
next_tvb.h \
nlpid.h \
oids.h \

View File

@ -27,6 +27,8 @@
#include <epan/packet.h>
#include <wsutil/str_util.h>
#include "packet-http.h"
void proto_register_http_urlencoded(void);
void proto_reg_handoff_http_urlencoded(void);
@ -123,18 +125,27 @@ dissect_form_urlencoded(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, voi
proto_item *ti;
gint offset = 0, next_offset;
const char *data_name;
http_message_info_t *message_info;
data_name = pinfo->match_string;
if (! (data_name && data_name[0])) {
/*
* No information from "match_string"
*/
data_name = (char *)data;
if (! (data_name && data_name[0])) {
message_info = (http_message_info_t *)data;
if (message_info == NULL) {
/*
* No information from dissector data
*/
data_name = NULL;
} else {
data_name = message_info->media_str;
if (! (data_name && data_name[0])) {
/*
* No information from dissector data
*/
data_name = NULL;
}
}
}

View File

@ -49,14 +49,6 @@
#include "packet-tcp.h"
#include "packet-ssl.h"
typedef enum _http_type {
HTTP_REQUEST,
HTTP_RESPONSE,
HTTP_NOTIFICATION,
HTTP_OTHERS
} http_type_t;
void proto_register_http(void);
void proto_reg_handoff_http(void);
void proto_register_message_http(void);
@ -764,6 +756,7 @@ dissect_http_message(tvbuff_t *tvb, int offset, packet_info *pinfo,
int reported_length;
guint16 word;
gboolean leading_crlf = FALSE;
http_message_info_t message_info;
reported_length = tvb_reported_length_remaining(tvb, offset);
if (reported_length < 1) {
@ -1428,13 +1421,13 @@ dissect_http_message(tvbuff_t *tvb, int offset, packet_info *pinfo,
if (headers.content_encoding != NULL &&
g_ascii_strcasecmp(headers.content_encoding, "identity") != 0) {
/*
* We currently can't handle, for example, "compress";
* We currently don't handle, for example, "compress";
* just handle them as data for now.
*
* After July 7, 2004 the LZW patent expires, so support
* might be added then. However, I don't think that
* anybody ever really implemented "compress", due to
* the aforementioned patent.
* After July 7, 2004 the LZW patent expired, so
* support could be added. However, I don't think
* that anybody ever really implemented "compress",
* due to the aforementioned patent.
*/
tvbuff_t *uncomp_tvb = NULL;
proto_item *e_ti = NULL;
@ -1559,11 +1552,13 @@ dissect_http_message(tvbuff_t *tvb, int offset, packet_info *pinfo,
pinfo->match_uint);
}
message_info.type = http_type;
message_info.media_str = media_str;
if (handle != NULL) {
/*
* We have a subdissector - call it.
*/
dissected = call_dissector_only(handle, next_tvb, pinfo, tree, media_str);
dissected = call_dissector_only(handle, next_tvb, pinfo, tree, &message_info);
if (!dissected)
expert_add_info(pinfo, http_tree, &ei_http_subdissector_failed);
}
@ -1591,7 +1586,7 @@ dissect_http_message(tvbuff_t *tvb, int offset, packet_info *pinfo,
* Calling the default media handle if there is a content-type that
* wasn't handled above.
*/
call_dissector_with_data(media_handle, next_tvb, pinfo, tree, media_str);
call_dissector_with_data(media_handle, next_tvb, pinfo, tree, &message_info);
} else {
/* Call the default data dissector */
call_data_dissector(next_tvb, pinfo, http_tree);

View File

@ -85,4 +85,17 @@ typedef struct _http_conv_t {
http_req_res_t *req_res_tail;
} http_conv_t;
typedef enum _http_type {
HTTP_REQUEST,
HTTP_RESPONSE,
HTTP_NOTIFICATION,
HTTP_OTHERS
} http_type_t;
/** Passed to dissectors called by the HTTP dissector. */
typedef struct _http_message_info_t {
http_type_t type; /* Message type; may be HTTP_OTHERS if not called by HTTP */
const char *media_str; /* Content-Type parameters */
} http_message_info_t;
#endif /* __PACKET_HTTP_H__ */

View File

@ -31,6 +31,7 @@
#include <wsutil/str_util.h>
#include "packet-ber.h"
#include "packet-http.h"
#include "packet-imf.h"
#include "packet-ess.h"
#include "packet-p1.h"
@ -813,6 +814,8 @@ dissect_imf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
/* now dissect the MIME based upon the content type */
if(content_type_str && media_type_dissector_table) {
http_message_info_t message_info;
col_set_fence(pinfo->cinfo, COL_INFO);
if(content_encoding_str && !g_ascii_strncasecmp(content_encoding_str, "base64", 6)) {
@ -823,7 +826,9 @@ dissect_imf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
next_tvb = tvb_new_subset_remaining(tvb, end_offset);
}
dissector_try_string(media_type_dissector_table, content_type_str, next_tvb, pinfo, tree, (void*)parameters);
message_info.type = HTTP_OTHERS;
message_info.media_str = parameters;
dissector_try_string(media_type_dissector_table, content_type_str, next_tvb, pinfo, tree, (void*)&message_info);
} else {
/* just show the lines or highlight the rest of the buffer as message text */

View File

@ -189,16 +189,34 @@ static int add_value_head(const gchar *tag_desc, proto_tree *tree,
tvbuff_t *tvb, int offset, int name_length, int value_length, char **name_val);
static int
dissect_ipp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
dissect_ipp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
proto_tree *ipp_tree;
proto_item *ti;
int offset = 0;
gboolean is_request = (pinfo->destport == pinfo->match_uint);
/* XXX - should this be based on the HTTP header? */
http_message_info_t *message_info = (http_message_info_t *)data;
gboolean is_request;
guint16 status_code;
const gchar *status_type;
if (message_info != NULL) {
switch (message_info->type) {
case HTTP_REQUEST:
is_request = TRUE;
break;
case HTTP_RESPONSE:
is_request = FALSE;
break;
default:
is_request = (pinfo->destport == pinfo->match_uint);
break;
}
} else
is_request = (pinfo->destport == pinfo->match_uint);
col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPP");
if (is_request)
col_set_str(pinfo->cinfo, COL_INFO, "IPP request");

View File

@ -38,6 +38,7 @@
*
* National variants
* French ISUP Specification: SPIROU 1998 - 002-005 edition 1 ( Info found here http://www.icg-corp.com/docs/ISUP.pdf ).
* See also http://www.fftelecoms.org/sites/default/files/contenus_lies/fft_interco_ip_-_sip-i_interface_specification_v1_0.pdf
* Israeli ISUP Specification: excertp (for BCM message) found in https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=4231 .
* Russian national ISUP-R 2000: RD 45.217-2001 book 4
* Japan ISUP http://www.ttc.or.jp/jp/document_list/sum/sum_JT-Q763v21.1.pdf
@ -54,12 +55,14 @@
#include <epan/sctpppids.h>
#include <epan/reassemble.h>
#include <epan/to_str.h>
#include <epan/media_params.h>
#include <wsutil/str_util.h>
#include "packet-q931.h"
#include "packet-isup.h"
#include "packet-e164.h"
#include "packet-charging_ase.h"
#include "packet-mtp3.h"
#include "packet-http.h"
void proto_register_isup(void);
void proto_reg_handoff_isup(void);
@ -10419,31 +10422,47 @@ dissect_application_isup(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, vo
proto_tree *isup_tree = NULL;
tvbuff_t *message_tvb;
guint8 message_type;
gchar *content_type_parameter_str;
const char *version, *base;
int len_version, len_base;
guint8 itu_isup_variant = ISUP_ITU_STANDARD_VARIANT; /* Default */
if (data) {
content_type_parameter_str = ascii_strdown_inplace((gchar *)data);
if (strstr(content_type_parameter_str, "ansi")) {
isup_standard = ANSI_STANDARD;
col_append_str(pinfo->cinfo, COL_PROTOCOL, "/ISUP(ANSI)");
message_type = tvb_get_guint8(tvb, 0);
/* application/ISUP has no CIC */
col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ",
"ISUP:%s",
val_to_str_ext_const(message_type, &ansi_isup_message_type_value_acro_ext, "reserved"));
if (tree) {
ti = proto_tree_add_item(tree, proto_isup, tvb, 0, -1, ENC_NA);
isup_tree = proto_item_add_subtree(ti, ett_isup);
}
http_message_info_t *message_info = (http_message_info_t *)data;
if (message_info->media_str) {
version = find_parameter(message_info->media_str, "version=", &len_version);
base = find_parameter(message_info->media_str, "base=", &len_base);
if ((version && len_version >= 4 && g_ascii_strncasecmp(version, "ansi", 4) == 0) ||
(base && len_base >= 4 && g_ascii_strncasecmp(base, "ansi", 4) == 0)) {
/*
* "version" or "base" parameter begins with "ansi", so it's ANSI.
*/
isup_standard = ANSI_STANDARD;
col_append_str(pinfo->cinfo, COL_PROTOCOL, "/ISUP(ANSI)");
message_type = tvb_get_guint8(tvb, 0);
/* application/ISUP has no CIC */
col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ",
"ISUP:%s",
val_to_str_ext_const(message_type, &ansi_isup_message_type_value_acro_ext, "reserved"));
if (tree) {
ti = proto_tree_add_item(tree, proto_isup, tvb, 0, -1, ENC_NA);
isup_tree = proto_item_add_subtree(ti, ett_isup);
}
message_tvb = tvb_new_subset_remaining(tvb, 0);
dissect_ansi_isup_message(message_tvb, pinfo, isup_tree, ISUP_ITU_STANDARD_VARIANT, 0);
return tvb_reported_length(tvb);
} else if (strstr(content_type_parameter_str, "spirou")) {
isup_standard = ITU_STANDARD;
itu_isup_variant = ISUP_FRENCH_VARIANT;
message_tvb = tvb_new_subset_remaining(tvb, 0);
dissect_ansi_isup_message(message_tvb, pinfo, isup_tree, ISUP_ITU_STANDARD_VARIANT, 0);
return tvb_reported_length(tvb);
} else if ((version && g_ascii_strncasecmp(version, "spirou", len_version) == 0) ||
(base && g_ascii_strncasecmp(base, "spirou", len_base) == 0)) {
/*
* "version" or "base" version is "spirou", so it's SPIROU.
*/
isup_standard = ITU_STANDARD;
itu_isup_variant = ISUP_FRENCH_VARIANT;
} else {
isup_standard = ITU_STANDARD;
}
} else {
/* default to ITU */
isup_standard = ITU_STANDARD;
}
} else {

View File

@ -38,6 +38,8 @@
#include <wiretap/wtap.h>
#include "packet-http.h"
void proto_register_json(void);
void proto_reg_handoff_json(void);
static char *json_string_unescape(tvbparse_elem_t *tok);
@ -116,6 +118,7 @@ dissect_json(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
json_parser_data_t parser_data;
tvbparse_t *tt;
http_message_info_t *message_info;
const char *data_name;
int offset;
@ -138,12 +141,20 @@ dissect_json(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
/*
* No information from "match_string"
*/
data_name = (char *)data;
if (! (data_name && data_name[0])) {
message_info = (http_message_info_t *)data;
if (message_info == NULL) {
/*
* No information from dissector data
*/
data_name = NULL;
} else {
data_name = message_info->media_str;
if (! (data_name && data_name[0])) {
/*
* No information from dissector data
*/
data_name = NULL;
}
}
}

View File

@ -42,6 +42,7 @@
#include <wsutil/str_util.h>
#include "packet-jxta.h"
#include "packet-http.h"
void proto_register_jxta(void);
void proto_reg_handoff_jxta(void);
@ -2052,11 +2053,11 @@ static int dissect_media( const gchar* fullmediatype, tvbuff_t * tvb, packet_inf
gchar *mediatype = wmem_strdup(wmem_packet_scope(), fullmediatype);
gchar *parms_at = strchr(mediatype, ';');
const char *save_match_string = pinfo->match_string;
char *media_str = NULL;
http_message_info_t message_info = { HTTP_OTHERS, NULL };
/* Based upon what is done in packet-media.c we set up type and params */
if (NULL != parms_at) {
media_str = wmem_strdup( wmem_packet_scope(), parms_at + 1 );
message_info.media_str = wmem_strdup( wmem_packet_scope(), parms_at + 1 );
*parms_at = '\0';
}
@ -2086,7 +2087,7 @@ static int dissect_media( const gchar* fullmediatype, tvbuff_t * tvb, packet_inf
}
}
} else {
dissected = dissector_try_string(media_type_dissector_table, mediatype, tvb, pinfo, tree, media_str) ? tvb_captured_length(tvb) : 0;
dissected = dissector_try_string(media_type_dissector_table, mediatype, tvb, pinfo, tree, &message_info) ? tvb_captured_length(tvb) : 0;
if( dissected != (int) tvb_captured_length(tvb) ) {
/* g_message( "%s : %d expected, %d dissected", mediatype, tvb_captured_length(tvb), dissected ); */
@ -2094,7 +2095,7 @@ static int dissect_media( const gchar* fullmediatype, tvbuff_t * tvb, packet_inf
}
if (0 == dissected) {
dissected = call_dissector_with_data(media_handle, tvb, pinfo, tree, media_str);
dissected = call_dissector_with_data(media_handle, tvb, pinfo, tree, &message_info);
}
pinfo->match_string = save_match_string;

View File

@ -32,6 +32,8 @@
#include <wsutil/str_util.h>
#include "packet-http.h"
void proto_register_media(void);
/* proto_media cannot be static because it's referenced in the
@ -48,6 +50,7 @@ dissect_media(tvbuff_t *tvb, packet_info *pinfo , proto_tree *tree, void* data)
int bytes;
proto_item *ti;
proto_tree *media_tree = 0;
http_message_info_t *message_info = (http_message_info_t *)data;
heur_dtbl_entry_t *hdtbl_entry;
if (dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, tree, &hdtbl_entry, data)) {
@ -63,11 +66,12 @@ dissect_media(tvbuff_t *tvb, packet_info *pinfo , proto_tree *tree, void* data)
ti = proto_tree_add_item(tree, proto_media, tvb, 0, -1, ENC_NA);
media_tree = proto_item_add_subtree(ti, ett_media);
if (data) {
if (message_info != NULL && message_info->media_str != NULL) {
/* The media type has parameters */
proto_tree_add_bytes_format_value(media_tree, hf_media_type, tvb, 0, bytes,
NULL, "%s; %s (%d byte%s)",
pinfo->match_string, (char *)data,
pinfo->match_string, message_info->media_str,
bytes, plurality(bytes, "", "s"));
} else {
/* The media type has no parameters */

View File

@ -36,6 +36,7 @@
#include <wsutil/str_util.h>
#include "packet-msrp.h"
#include "packet-http.h"
void proto_register_msrp(void);
void proto_reg_handoff_msrp(void);
@ -471,7 +472,7 @@ dissect_msrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
int found_match = 0;
gint content_type_len, content_type_parameter_str_len;
gchar *media_type_str_lower_case = NULL;
char *content_type_parameter_str = NULL;
http_message_info_t message_info = { HTTP_OTHERS, NULL };
tvbuff_t *next_tvb;
gint parameter_offset;
gint semi_colon_offset;
@ -655,7 +656,7 @@ dissect_msrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
parameter_offset++;
content_type_len = semi_colon_offset - value_offset;
content_type_parameter_str_len = line_end_offset - parameter_offset;
content_type_parameter_str = tvb_get_string_enc(wmem_packet_scope(), tvb,
message_info.media_str = tvb_get_string_enc(wmem_packet_scope(), tvb,
parameter_offset, content_type_parameter_str_len, ENC_UTF_8|ENC_NA);
}
media_type_str_lower_case = ascii_strdown_inplace(
@ -689,7 +690,7 @@ dissect_msrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
found_match = dissector_try_string(media_type_dissector_table,
media_type_str_lower_case,
next_tvb, pinfo,
msrp_data_tree, content_type_parameter_str);
msrp_data_tree, &message_info);
/* If no match dump as text */
}
if ( found_match == 0 )

View File

@ -59,12 +59,14 @@
#include <epan/packet.h>
#include <epan/expert.h>
#include <epan/media_params.h>
#include <epan/prefs.h>
#include <wsutil/str_util.h>
#include "packet-imf.h"
#include "packet-dcerpc.h"
#include "packet-gssapi.h"
#include "packet-http.h"
void proto_register_multipart(void);
void proto_reg_handoff_multipart(void);
@ -179,13 +181,12 @@ static gint
process_preamble(proto_tree *tree, tvbuff_t *tvb, multipart_info_t *m_info,
gboolean *last_boundary);
static gint
process_body_part(proto_tree *tree, tvbuff_t *tvb, multipart_info_t *m_info,
process_body_part(proto_tree *tree, tvbuff_t *tvb,
http_message_info_t *input_message_info, multipart_info_t *m_info,
packet_info *pinfo, gint start, gint idx,
gboolean *last_boundary);
static gint
is_known_multipart_header(const char *header_str, guint len);
static gint
index_of_char(const char *str, const char c);
/* Return a tvb that contains the binary representation of a base64
@ -310,96 +311,6 @@ unfold_and_compact_mime_header(const char *lines, gint *first_colon_offset)
return (ret);
}
/* Return the index of a given char in the given string,
* or -1 if not found.
*/
static gint
index_of_char(const char *str, const char c)
{
gint len = 0;
const char *p = str;
while (*p && *p != c) {
p++;
len++;
}
if (*p)
return len;
return -1;
}
static char *find_parameter(char *parameters, const char *key, int *retlen)
{
char *start, *p;
int keylen = 0;
int len = 0;
if(!parameters || !*parameters || !key || strlen(key) == 0)
/* we won't be able to find anything */
return NULL;
keylen = (int) strlen(key);
p = parameters;
while (*p) {
while ((*p) && g_ascii_isspace(*p))
p++; /* Skip white space */
if (g_ascii_strncasecmp(p, key, keylen) == 0)
break;
/* Skip to next parameter */
p = strchr(p, ';');
if (p == NULL)
{
return NULL;
}
p++; /* Skip semicolon */
}
if (*p == 0x0)
return NULL; /* key wasn't found */
start = p + keylen;
if (start[0] == 0) {
return NULL;
}
/*
* Process the parameter value
*/
if (start[0] == '"') {
/*
* Parameter value is a quoted-string
*/
start++; /* Skip the quote */
len = index_of_char(start, '"');
if (len < 0) {
/*
* No closing quote
*/
return NULL;
}
} else {
/*
* Look for end of boundary
*/
p = start;
while (*p) {
if (*p == ';' || g_ascii_isspace(*p))
break;
p++;
len++;
}
}
if(retlen)
(*retlen) = len;
return start;
}
/* Retrieve the media information from pinfo->private_data,
* and compute the boundary string and its length.
* Return a pointer to a filled-in multipart_info_t, or NULL on failure.
@ -409,7 +320,7 @@ static char *find_parameter(char *parameters, const char *key, int *retlen)
* leading hyphens. (quote from rfc2046)
*/
static multipart_info_t *
get_multipart_info(packet_info *pinfo, const char *str)
get_multipart_info(packet_info *pinfo, http_message_info_t *message_info)
{
const char *start_boundary, *start_protocol = NULL;
int len_boundary = 0, len_protocol = 0;
@ -418,16 +329,22 @@ get_multipart_info(packet_info *pinfo, const char *str)
char *parameters;
gint dummy;
if ((type == NULL) || (str == NULL)) {
/*
* We need both a content type AND parameters
* for multipart dissection.
*/
/*
* We need both a content type AND parameters
* for multipart dissection.
*/
if (type == NULL) {
return NULL;
}
if (message_info == NULL) {
return NULL;
}
if (message_info->media_str == NULL) {
return NULL;
}
/* Clean up the parameters */
parameters = unfold_and_compact_mime_header(str, &dummy);
parameters = unfold_and_compact_mime_header(message_info->media_str, &dummy);
start_boundary = find_parameter(parameters, "boundary=", &len_boundary);
@ -626,14 +543,15 @@ dissect_kerberos_encrypted_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree
* Return the offset to the start of the next body-part.
*/
static gint
process_body_part(proto_tree *tree, tvbuff_t *tvb, multipart_info_t *m_info,
process_body_part(proto_tree *tree, tvbuff_t *tvb,
http_message_info_t *input_message_info, multipart_info_t *m_info,
packet_info *pinfo, gint start, gint idx,
gboolean *last_boundary)
{
proto_tree *subtree;
proto_item *ti;
gint offset = start, next_offset = 0;
char *parameters = NULL;
http_message_info_t message_info = { input_message_info->type, NULL };
gint body_start, boundary_start, boundary_line_len;
gchar *content_type_str = NULL;
@ -753,9 +671,9 @@ process_body_part(proto_tree *tree, tvbuff_t *tvb, multipart_info_t *m_info,
if (semicolon_offset > 0) {
value_str[semicolon_offset] = '\0';
parameters = wmem_strdup(wmem_packet_scope(), value_str + semicolon_offset + 1);
message_info.media_str = wmem_strdup(wmem_packet_scope(), value_str + semicolon_offset + 1);
} else {
parameters = NULL;
message_info.media_str = NULL;
}
content_type_str = wmem_ascii_strdown(wmem_packet_scope(), value_str, -1);
@ -764,7 +682,7 @@ process_body_part(proto_tree *tree, tvbuff_t *tvb, multipart_info_t *m_info,
proto_item_append_text(ti, " (%s)", content_type_str);
/* find the "name" parameter in case we don't find a content disposition "filename" */
if((mimetypename = find_parameter(parameters, "name=", &len)) != NULL) {
if((mimetypename = find_parameter(message_info.media_str, "name=", &len)) != NULL) {
mimetypename = g_strndup(mimetypename, len);
}
@ -835,7 +753,7 @@ process_body_part(proto_tree *tree, tvbuff_t *tvb, multipart_info_t *m_info,
tmp_tvb = encrypt.gssapi_decrypted_tvb;
is_raw_data = FALSE;
content_type_str = m_info->orig_content_type;
parameters = m_info->orig_parameters;
message_info.media_str = m_info->orig_parameters;
} else if(encrypt.gssapi_encrypted_tvb) {
tmp_tvb = encrypt.gssapi_encrypted_tvb;
proto_tree_add_expert(tree, pinfo, &ei_multipart_decryption_not_possible, tmp_tvb, 0, -1);
@ -867,21 +785,21 @@ process_body_part(proto_tree *tree, tvbuff_t *tvb, multipart_info_t *m_info,
* First try the dedicated multipart dissector table
*/
dissected = dissector_try_string(multipart_media_subdissector_table,
content_type_str, tmp_tvb, pinfo, subtree, parameters);
content_type_str, tmp_tvb, pinfo, subtree, &message_info);
if (! dissected) {
/*
* Fall back to the default media dissector table
*/
dissected = dissector_try_string(media_type_dissector_table,
content_type_str, tmp_tvb, pinfo, subtree, parameters);
content_type_str, tmp_tvb, pinfo, subtree, &message_info);
}
if (! dissected) {
const char *save_match_string = pinfo->match_string;
pinfo->match_string = content_type_str;
call_dissector_with_data(media_handle, tmp_tvb, pinfo, subtree, parameters);
call_dissector_with_data(media_handle, tmp_tvb, pinfo, subtree, &message_info);
pinfo->match_string = save_match_string;
}
parameters = NULL; /* Shares same memory as content_type_str */
message_info.media_str = NULL; /* Shares same memory as content_type_str */
} else {
call_data_dissector(tmp_tvb, pinfo, subtree);
}
@ -908,7 +826,8 @@ static int dissect_multipart(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
proto_tree *subtree;
proto_item *ti;
proto_item *type_ti;
multipart_info_t *m_info = get_multipart_info(pinfo, (const char*)data);
http_message_info_t *message_info = (http_message_info_t *)data;
multipart_info_t *m_info = get_multipart_info(pinfo, message_info);
gint header_start = 0;
gint body_index = 0;
gboolean last_boundary = FALSE;
@ -952,7 +871,7 @@ static int dissect_multipart(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
* Process the encapsulated bodies
*/
while (last_boundary == FALSE) {
header_start = process_body_part(subtree, tvb, m_info,
header_start = process_body_part(subtree, tvb, message_info, m_info,
pinfo, header_start, body_index++, &last_boundary);
if (header_start == -1) {
return tvb_reported_length(tvb);

View File

@ -53,6 +53,8 @@
#include "packet-e164.h"
#include "packet-sip.h"
#include "packet-http.h"
#include "packet-sdp.h" /* SDP needs a transport layer to determine request/response */
/* un-comment the following as well as this line in conversation.c, to enable debug printing */
@ -2863,7 +2865,7 @@ dissect_sip_common(tvbuff_t *tvb, int offset, int remaining_length, packet_info
char cseq_method[MAX_CSEQ_METHOD_SIZE] = "";
char call_id[MAX_CALL_ID_SIZE] = "";
gchar *media_type_str_lower_case = NULL;
char *content_type_parameter_str = NULL;
http_message_info_t message_info = { HTTP_OTHERS, NULL };
char *content_encoding_parameter_str = NULL;
guint resend_for_packet = 0;
guint request_for_response = 0;
@ -3614,7 +3616,7 @@ dissect_sip_common(tvbuff_t *tvb, int offset, int remaining_length, packet_info
content_type_end = tvb_skip_wsp_return(tvb, semi_colon_offset-1);
content_type_len = content_type_end - value_offset;
content_type_parameter_str_len = value_offset + value_len - parameter_offset;
content_type_parameter_str = tvb_get_string_enc(wmem_packet_scope(), tvb, parameter_offset,
message_info.media_str = tvb_get_string_enc(wmem_packet_scope(), tvb, parameter_offset,
content_type_parameter_str_len, ENC_UTF_8|ENC_NA);
}
media_type_str_lower_case = ascii_strdown_inplace(
@ -4168,7 +4170,7 @@ dissect_sip_common(tvbuff_t *tvb, int offset, int remaining_length, packet_info
found_match = dissector_try_string(media_type_dissector_table,
media_type_str_lower_case,
next_tvb, pinfo,
message_body_tree, content_type_parameter_str);
message_body_tree, &message_info);
DENDENT();
DPRINT(("done calling dissector_try_string() with found_match=%u", found_match));
@ -4180,7 +4182,7 @@ dissect_sip_common(tvbuff_t *tvb, int offset, int remaining_length, packet_info
found_match = dissector_try_string(media_type_dissector_table,
"multipart/",
next_tvb, pinfo,
message_body_tree, content_type_parameter_str);
message_body_tree, &message_info);
DENDENT();
DPRINT(("done calling dissector_try_string() with found_match=%u", found_match));
}

View File

@ -40,6 +40,7 @@
#include <epan/tap.h>
#include "packet-tcp.h"
#include "packet-ssl.h"
#include "packet-http.h"
#ifdef HAVE_ZLIB
#define ZLIB_CONST
@ -177,6 +178,7 @@ typedef struct _spdy_data_frame_t {
} spdy_data_frame_t;
typedef struct _spdy_stream_info_t {
http_type_t message_type;
gchar *content_type;
gchar *content_type_parameters;
gchar *content_encoding;
@ -514,6 +516,7 @@ static spdy_conv_t * get_or_create_spdy_conversation_data(packet_info *pinfo) {
*/
static void spdy_save_stream_info(spdy_conv_t *conv_data,
guint32 stream_id,
http_type_t message_type,
gchar *content_type,
gchar *content_type_params,
gchar *content_encoding) {
@ -524,6 +527,7 @@ static void spdy_save_stream_info(spdy_conv_t *conv_data,
}
si = (spdy_stream_info_t *)wmem_alloc(wmem_file_scope(), sizeof(spdy_stream_info_t));
si->message_type = message_type;
si->content_type = content_type;
si->content_type_parameters = content_type_params;
si->content_encoding = content_encoding;
@ -725,6 +729,7 @@ static int dissect_spdy_data_payload(tvbuff_t *tvb,
dissector_handle_t handle;
guint num_data_frames;
gboolean dissected;
http_message_info_t message_info;
/* Add frame description. */
proto_item_append_text(spdy_proto, ", Stream: %d, Length: %d",
@ -911,11 +916,13 @@ static int dissect_spdy_data_payload(tvbuff_t *tvb,
handle = dissector_get_string_handle(media_type_subdissector_table,
si->content_type);
}
message_info.type = si->message_type;
message_info.media_str = media_str;
if (handle != NULL) {
/*
* We have a subdissector - call it.
*/
dissected = call_dissector_with_data(handle, data_tvb, pinfo, spdy_tree, media_str);
dissected = call_dissector_with_data(handle, data_tvb, pinfo, spdy_tree, &message_info);
} else {
dissected = FALSE;
}
@ -925,7 +932,7 @@ static int dissect_spdy_data_payload(tvbuff_t *tvb,
* Calling the default media handle if there is a content-type that
* wasn't handled above.
*/
call_dissector_with_data(media_handle, next_tvb, pinfo, spdy_tree, media_str);
call_dissector_with_data(media_handle, next_tvb, pinfo, spdy_tree, &message_info);
} else {
/* Call the default data dissector */
call_data_dissector(next_tvb, pinfo, spdy_tree);
@ -1328,8 +1335,9 @@ static int dissect_spdy_header_payload(
*/
if (content_type != NULL && !pinfo->fd->flags.visited) {
gchar *content_type_params = spdy_parse_content_type(content_type);
spdy_save_stream_info(conv_data, stream_id, content_type,
content_type_params, content_encoding);
spdy_save_stream_info(conv_data, stream_id,
(hdr_status == NULL) ? HTTP_REQUEST : HTTP_RESPONSE,
content_type, content_type_params, content_encoding);
}
return frame->length;

View File

@ -34,6 +34,7 @@
#include <epan/packet.h>
#include "packet-http.h"
/*
* Media dissector for line-based text media like text/plain, message/http.
@ -59,6 +60,7 @@ dissect_text_lines(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* da
proto_item *ti;
gint offset = 0, next_offset;
gint len;
http_message_info_t *message_info;
const char *data_name;
int length = tvb_captured_length(tvb);
@ -78,12 +80,20 @@ dissect_text_lines(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* da
/*
* No information from "match_string"
*/
data_name = (char *)data;
if (! (data_name && data_name[0])) {
message_info = (http_message_info_t *)data;
if (message_info == NULL) {
/*
* No information from dissector data
*/
data_name = NULL;
} else {
data_name = message_info->media_str;
if (! (data_name && data_name[0])) {
/*
* No information from dissector data
*/
data_name = NULL;
}
}
}

133
epan/media_params.c Normal file
View File

@ -0,0 +1,133 @@
/* media_params.c
* Routines for parsing media type parameters
* Copyright 2004, Anders Broman.
* Copyright 2004, Olivier Biot.
*
* Refer to the AUTHORS file or the AUTHORS section in the man page
* for contacting the author(s) of this file.
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <string.h>
#include <glib.h>
#include <epan/media_params.h>
/* Return the index of a given char in the given string,
* or -1 if not found.
*/
gint
index_of_char(const char *str, const char c)
{
gint len = 0;
const char *p = str;
while (*p && *p != c) {
p++;
len++;
}
if (*p)
return len;
return -1;
}
char *
find_parameter(const char *parameters, const char *key, int *retlen)
{
const char *start, *p;
int keylen = 0;
int len = 0;
if(!parameters || !*parameters || !key || strlen(key) == 0)
/* we won't be able to find anything */
return NULL;
keylen = (int) strlen(key);
p = parameters;
while (*p) {
while ((*p) && g_ascii_isspace(*p))
p++; /* Skip white space */
if (g_ascii_strncasecmp(p, key, keylen) == 0)
break;
/* Skip to next parameter */
p = strchr(p, ';');
if (p == NULL)
{
return NULL;
}
p++; /* Skip semicolon */
}
if (*p == 0x0)
return NULL; /* key wasn't found */
start = p + keylen;
if (start[0] == 0) {
return NULL;
}
/*
* Process the parameter value
*/
if (start[0] == '"') {
/*
* Parameter value is a quoted-string
*/
start++; /* Skip the quote */
len = index_of_char(start, '"');
if (len < 0) {
/*
* No closing quote
*/
return NULL;
}
} else {
/*
* Look for end of boundary
*/
p = start;
while (*p) {
if (*p == ';' || g_ascii_isspace(*p))
break;
p++;
len++;
}
}
if(retlen)
(*retlen) = len;
/*
* This is one of those ugly routines like strchr() where you can
* pass in a constant or non-constant string, and the result
* points into that string and inherits the constness of the
* input argument, but C doesn't support that, so the input
* parameter is const char * and the result is char *.
*/
return (char *)start;
}

52
epan/media_params.h Normal file
View File

@ -0,0 +1,52 @@
/* media_params.h
* Routines for parsing media type parameters
* Copyright 2004, Anders Broman.
* Copyright 2004, Olivier Biot.
*
* Refer to the AUTHORS file or the AUTHORS section in the man page
* for contacting the author(s) of this file.
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __MEDIA_PARAMS_H__
#define __MEDIA_PARAMS_H__
#include <glib.h>
#include "ws_symbol_export.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Return the index of a given char in the given string,
* or -1 if not found.
*/
WS_DLL_PUBLIC gint
index_of_char(const char *str, const char c);
WS_DLL_PUBLIC char *
find_parameter(const char *parameters, const char *key, int *retlen);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* media_params.h */