From Tom Uijldert: WSP/MMSE changes to handle multipart-content:

packet-wsp.[ch]:
	- Proper parameter-dissection
	- Now handles multipart content
	- Exports content-type & multipart-dissection
	- Attach a sub-dissector based on content-type

	packet-mmse.c:
	- Dissecting message-content added
	- Registers with WSP based on content-type.

svn path=/trunk/; revision=4353
This commit is contained in:
Guy Harris 2001-12-07 11:10:53 +00:00
parent 6b0b77c5f1
commit 6bb3e341d1
4 changed files with 280 additions and 94 deletions

View File

@ -832,6 +832,7 @@ Tom Uijldert <Tom.Uijldert[AT]cmg.nl> {
Push-traffic dissecting for WSP/WTLS
UCP support
SMPP support
multipart-content support in WSP/MMSE
}
Endoh Akira <endoh[AT]netmarks.co.jp> {

View File

@ -2,7 +2,7 @@
* Routines for MMS Message Encapsulation dissection
* Copyright 2001, Tom Uijldert <tom.uijldert@cmg.nl>
*
* $Id: packet-mmse.c,v 1.2 2001/10/19 21:40:48 guy Exp $
* $Id: packet-mmse.c,v 1.3 2001/12/07 11:10:52 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -52,10 +52,18 @@
#include "packet.h"
#include "packet-wap.h"
#include "packet-wsp.h"
/* #include "packet-mmse.h" */ /* We autoregister */
#define MM_QUOTE 0x7F /* Quoted string */
#define MMS_CONTENT_TYPE 0x3E /* WINA-value for mms-message */
/*
* Forward declarations
*/
static void dissect_mmse(tvbuff_t *, packet_info *, proto_tree *);
/*
* Header field values
*/
@ -318,6 +326,26 @@ get_long_integer(tvbuff_t *tvb, guint offset, guint *byte_count)
/* Code to actually dissect the packets */
static gboolean
dissect_mmse_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
guint8 pdut;
/*
* Check if data makes sense for it to be dissected as MMSE: Message-type
* field must make sense and followed by Transaction-Id header
*/
if (tvb_get_guint8(tvb, 0) != MM_MTYPE_HDR)
return FALSE;
pdut = tvb_get_guint8(tvb, 1);
if (match_strval(pdut, vals_message_type) == NULL)
return FALSE;
if (tvb_get_guint8(tvb, 2) != MM_TID_HDR)
return FALSE;
dissect_mmse(tvb, pinfo, tree);
return TRUE;
}
static void
dissect_mmse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
guint8 pdut;
@ -330,18 +358,8 @@ dissect_mmse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* Set up structures needed to add the protocol subtree and manage it */
proto_item *ti;
proto_tree *mmse_tree;
/*
* Check if data makes sense for it to be dissected as MMSE: Message-type
* field must make sense and followed by Transaction-Id header
*/
if (tvb_get_guint8(tvb, 0) != MM_MTYPE_HDR)
return FALSE;
pdut = tvb_get_guint8(tvb, 1);
if (match_strval(pdut, vals_message_type) == NULL)
return FALSE;
if (tvb_get_guint8(tvb, 2) != MM_TID_HDR)
return FALSE;
pdut = tvb_get_guint8(tvb, 1);
/* Make entries in Protocol column and Info column on summary display */
if (check_col(pinfo->fd, COL_PROTOCOL))
col_set_str(pinfo->fd, COL_PROTOCOL, "MMSE");
@ -605,20 +623,21 @@ dissect_mmse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
if (field == MM_CTYPE_HDR) {
/*
* \todo
* Eeehh, we're now actually back to good old WSP content-type
* encoding for multipart/related and multipart/mixed MIME-types.
* I'm not gonna do that work here again so maybe it's wise to
* share some more code with packet-wsp.c in the near future?
* Leave it as "Data" for now as it is the end of the PDU...
* Let's steal that from the WSP-dissector.
*/
proto_tree_add_item(mmse_tree, hf_mmse_content_type, tvb,
offset - 1,
tvb_length_remaining(tvb, offset - 1), FALSE);
return TRUE;
tvbuff_t *tmp_tvb;
guint type;
const char *type_str;
offset = add_content_type(mmse_tree, tvb, offset, &type, &type_str);
tmp_tvb = tvb_new_subset(tvb, offset,
tvb_length_remaining(tvb, offset),
tvb_length_remaining(tvb, offset));
add_multipart_data(mmse_tree, tmp_tvb);
}
}
return TRUE;
/* If this protocol has a sub-dissector call it here, see section 1.8 */
}
@ -853,17 +872,16 @@ proto_register_mmse(void)
void
proto_reg_handoff_mmse(void)
{
heur_dissector_add("wsp", dissect_mmse, proto_mmse);
/*!
* \todo
* Mmmmm, actually, it should register itself on the "wsp.content_type"
* protocol field. Especially when IANA finally registers the type
* 'application/wap.vnd.mms-message'. The wsp-dissector should then
* ofcourse be modified to cater for such subdissectors...
*/
dissector_handle_t mmse_handle;
heur_dissector_add("wsp", dissect_mmse_heur, proto_mmse);
mmse_handle = create_dissector_handle(dissect_mmse, proto_mmse);
dissector_add("wsp.content_type.type", MMS_CONTENT_TYPE,
mmse_handle);
/*
* \todo
* The bearer could also be http (through the same content-type field).
* Same modifications would apply there.
* The bearer could also be http (through the content-type field).
* The wsp-dissector should then ofcourse be modified to cater for
* such subdissectors...
*/
}

View File

@ -2,7 +2,7 @@
*
* Routines to dissect WSP component of WAP traffic.
*
* $Id: packet-wsp.c,v 1.47 2001/12/03 03:59:43 guy Exp $
* $Id: packet-wsp.c,v 1.48 2001/12/07 11:10:52 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -95,9 +95,13 @@ static int hf_wsp_parameter_start_info = HF_EMPTY;
static int hf_wsp_parameter_comment = HF_EMPTY;
static int hf_wsp_parameter_domain = HF_EMPTY;
static int hf_wsp_parameter_path = HF_EMPTY;
static int hf_wsp_parameter_upart_type = HF_EMPTY;
static int hf_wsp_parameter_upart_type_value = HF_EMPTY;
static int hf_wsp_reply_data = HF_EMPTY;
static int hf_wsp_post_data = HF_EMPTY;
static int hf_wsp_push_data = HF_EMPTY;
static int hf_wsp_multipart_data = HF_EMPTY;
static int hf_wsp_mpart = HF_EMPTY;
static int hf_wsp_header_shift_code = HF_EMPTY;
static int hf_wsp_header_accept = HF_EMPTY;
@ -136,6 +140,7 @@ static int hf_wsp_header_warning_text = HF_EMPTY;
static int hf_wsp_header_application_header = HF_EMPTY;
static int hf_wsp_header_application_value = HF_EMPTY;
static int hf_wsp_header_x_wap_tod = HF_EMPTY;
static int hf_wsp_header_content_ID = HF_EMPTY;
static int hf_wsp_header_transfer_encoding = HF_EMPTY;
static int hf_wsp_header_transfer_encoding_str = HF_EMPTY;
static int hf_wsp_header_via = HF_EMPTY;
@ -167,6 +172,8 @@ static gint ett_capabilities = ETT_EMPTY;
static gint ett_content_type = ETT_EMPTY;
static gint ett_redirect_flags = ETT_EMPTY;
static gint ett_redirect_afl = ETT_EMPTY;
static gint ett_multiparts = ETT_EMPTY;
static gint ett_mpartlist = ETT_EMPTY;
/* Handle for WSP-over-UDP dissector */
static dissector_handle_t wsp_fromudp_handle;
@ -722,23 +729,23 @@ static const true_false_string yes_no_truth = {
enum {
RESERVED = 0x00,
CONNECT = 0x01,
CONNECTREPLY = 0x02,
CONNECTREPLY = 0x02,
REDIRECT = 0x03, /* No sample data */
REPLY = 0x04,
DISCONNECT = 0x05,
PUSH = 0x06, /* No sample data */
CONFIRMEDPUSH = 0x07, /* No sample data */
CONFIRMEDPUSH = 0x07, /* No sample data */
SUSPEND = 0x08, /* No sample data */
RESUME = 0x09, /* No sample data */
GET = 0x40,
GET = 0x40,
OPTIONS = 0x41, /* No sample data */
HEAD = 0x42, /* No sample data */
DELETE = 0x43, /* No sample data */
TRACE = 0x44, /* No sample data */
POST = 0x60,
PUT = 0x61, /* No sample data */
PUT = 0x61, /* No sample data */
};
typedef enum {
@ -747,6 +754,7 @@ typedef enum {
VALUE_IN_LEN,
} value_type_t;
static dissector_table_t wsp_dissector_table;
static heur_dissector_list_t heur_subdissector_list;
static void add_uri (proto_tree *, frame_data *, tvbuff_t *, guint, guint);
@ -768,22 +776,22 @@ static void add_connection_header (proto_tree *, tvbuff_t *, int,
tvbuff_t *, value_type_t, int);
static void add_content_type_value (proto_tree *, tvbuff_t *, int, int,
tvbuff_t *, value_type_t, int, int, int, guint *, const char **);
static guint add_content_type (proto_tree *, tvbuff_t *, guint, guint *,
const char **);
static void add_wap_application_id_header (proto_tree *, tvbuff_t *, int,
tvbuff_t *, value_type_t, int);
static void add_integer_value_header (proto_tree *, tvbuff_t *, int,
tvbuff_t *, value_type_t, int, int, guint8);
static void add_string_value_header (proto_tree *, tvbuff_t *, int,
tvbuff_t *, value_type_t, int, int, guint8);
static void add_quoted_string_value_header (proto_tree *, tvbuff_t *, int,
tvbuff_t *, value_type_t, int, int, guint8);
static void add_date_value_header (proto_tree *, tvbuff_t *, int,
tvbuff_t *, value_type_t, int, int, guint8);
static int add_parameter (proto_tree *, tvbuff_t *, int);
static void add_untyped_parameter (proto_tree *, tvbuff_t *, int, int);
static void add_parameter_charset (proto_tree *, tvbuff_t *, int, int);
static void add_parameter_type (proto_tree *, tvbuff_t *, int, int);
static void add_parameter_text (proto_tree *, tvbuff_t *, int, int, int,
const char *paramName);
static int add_untyped_parameter (proto_tree *, tvbuff_t *, int, int);
static int add_parameter_charset (proto_tree *, tvbuff_t *, int, int);
static int add_constrained_encoding (proto_tree *, tvbuff_t *, int, int);
static int add_parameter_type (proto_tree *, tvbuff_t *, int, int);
static int add_parameter_text (proto_tree *, tvbuff_t *, int, int, int, const char *);
static void add_post_data (proto_tree *, tvbuff_t *, guint, const char *);
static void add_post_variable (proto_tree *, tvbuff_t *, guint, guint, guint, guint);
static void add_pragma_header (proto_tree *, tvbuff_t *, int, tvbuff_t *,
@ -795,9 +803,7 @@ static void add_warning_header (proto_tree *, tvbuff_t *, int, tvbuff_t *,
static void add_accept_application_header (proto_tree *, tvbuff_t *, int,
tvbuff_t *, value_type_t, int);
static void add_capabilities (proto_tree *tree, tvbuff_t *tvb, int type);
static void add_capability_vals(tvbuff_t *tvb, gboolean add_string,
int offsetStr, guint length, guint capabilitiesStart, char *valString,
size_t valStringSize);
static void add_capability_vals(tvbuff_t *, gboolean, int, guint, guint, char *, size_t);
static value_type_t get_value_type_len (tvbuff_t *, int, guint *, int *, int *);
static guint get_uintvar (tvbuff_t *, guint, guint);
static gint get_integer (tvbuff_t *, guint, guint, value_type_t, guint *);
@ -1185,7 +1191,8 @@ dissect_wsp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
if (tvb_reported_length_remaining(tvb, headerStart + count + uriLength + headersLength) > 0)
{
tmp_tvb = tvb_new_subset (tvb, headerStart + count + uriLength + headersLength, -1, -1);
dissector_try_heuristic(heur_subdissector_list, tmp_tvb, pinfo, tree);
if (!dissector_try_port(wsp_dissector_table, contentType, tmp_tvb, pinfo, tree))
dissector_try_heuristic(heur_subdissector_list, tmp_tvb, pinfo, tree);
}
break;
@ -1226,7 +1233,8 @@ dissect_wsp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
if (tvb_reported_length_remaining(tvb, headerStart + headersLength) > 0)
{
tmp_tvb = tvb_new_subset (tvb, headerStart + headersLength, -1, -1);
dissector_try_heuristic(heur_subdissector_list, tmp_tvb, pinfo, tree);
if (!dissector_try_port(wsp_dissector_table, contentType, tmp_tvb, pinfo, tree))
dissector_try_heuristic(heur_subdissector_list, tmp_tvb, pinfo, tree);
}
break;
@ -1267,7 +1275,8 @@ dissect_wsp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
if (tvb_reported_length_remaining(tvb, headerStart + headersLength) > 0)
{
tmp_tvb = tvb_new_subset (tvb, headerStart + headersLength, -1, -1);
dissector_try_heuristic(heur_subdissector_list, tmp_tvb, pinfo, tree);
if (!dissector_try_port(wsp_dissector_table, contentType, tmp_tvb, pinfo, tree))
dissector_try_heuristic(heur_subdissector_list, tmp_tvb, pinfo, tree);
}
break;
@ -1642,11 +1651,17 @@ add_well_known_header (proto_tree *tree, tvbuff_t *tvb, int offset,
hf_wsp_header_profile, headerType);
break;
case FN_X_WAP_APPLICATION_ID: /* X-Wap-Application-Id */
case FN_X_WAP_APPLICATION_ID: /* X-Wap-Application-Id */
add_wap_application_id_header (tree, header_buff, headerLen,
value_buff, valueType, valueLen);
break;
case FN_CONTENT_ID: /* Content-ID */
add_quoted_string_value_header (tree, header_buff, headerLen,
value_buff, valueType, valueLen,
hf_wsp_header_content_ID, headerType);
break;
default:
proto_tree_add_text (tree, header_buff, 0, headerLen,
"Unsupported Header: %s",
@ -2869,7 +2884,7 @@ add_content_type_value (proto_tree *tree, tvbuff_t *header_buff,
offset = add_parameter (parameter_tree, value_buff, offset);
}
static guint
guint
add_content_type (proto_tree *tree, tvbuff_t *tvb, guint offset,
guint *contentTypep, const char **contentTypeStrp)
{
@ -2959,6 +2974,24 @@ add_string_value_header (proto_tree *tree, tvbuff_t *header_buff,
}
}
static void
add_quoted_string_value_header (proto_tree *tree, tvbuff_t *header_buff,
int headerLen, tvbuff_t *value_buff, value_type_t valueType,
int valueLen, int hf_string, guint8 headerType)
{
if (valueType != VALUE_IS_TEXT_STRING)
{
proto_tree_add_text (tree, header_buff, 0, headerLen,
"Invalid %s quoted string value",
match_strval (headerType, vals_field_names));
}
else
{
proto_tree_add_string (tree, hf_string, header_buff,
0, headerLen, tvb_get_ptr (value_buff, 1, valueLen - 1));
}
}
/* Utility function to add a date value to the protocol tree */
static void
add_date_value_header (proto_tree *tree, tvbuff_t *header_buff,
@ -3010,7 +3043,7 @@ add_parameter (proto_tree *tree, tvbuff_t *value_buff, int offset)
/*
* Untyped-parameter.
*/
add_untyped_parameter (tree, value_buff, startOffset, offset);
offset = add_untyped_parameter (tree, value_buff, startOffset, offset);
return offset;
}
@ -3029,53 +3062,56 @@ add_parameter (proto_tree *tree, tvbuff_t *value_buff, int offset)
switch (value) {
case 0x01: /* Charset */
add_parameter_charset (tree, value_buff, startOffset, offset);
offset = add_parameter_charset (tree, value_buff, startOffset, offset);
break;
case 0x03: /* Type */
add_parameter_type (tree, value_buff, startOffset, offset);
offset = add_parameter_type (tree, value_buff, startOffset, offset);
break;
case 0x05: /* Name */
add_parameter_text (tree, value_buff, startOffset, offset,
hf_wsp_parameter_name, "Name");
offset = add_parameter_text (tree, value_buff, startOffset, offset,
hf_wsp_parameter_name, "Name");
break;
case 0x06: /* Filename */
add_parameter_text (tree, value_buff, startOffset, offset,
hf_wsp_parameter_filename, "Filename");
offset = add_parameter_text (tree, value_buff, startOffset, offset,
hf_wsp_parameter_filename, "Filename");
break;
case 0x09: /* Type (special) */
offset = add_constrained_encoding(tree, value_buff, startOffset, offset);
break;
case 0x0A: /* Start */
add_parameter_text (tree, value_buff, startOffset, offset,
hf_wsp_parameter_start, "Start");
offset = add_parameter_text (tree, value_buff, startOffset, offset,
hf_wsp_parameter_start, "Start");
break;
case 0x0B: /* Start-info */
add_parameter_text (tree, value_buff, startOffset, offset,
hf_wsp_parameter_start_info, "Start-info");
offset = add_parameter_text (tree, value_buff, startOffset, offset,
hf_wsp_parameter_start_info, "Start-info");
break;
case 0x0C: /* Comment */
add_parameter_text (tree, value_buff, startOffset, offset,
hf_wsp_parameter_comment, "Comment");
offset = add_parameter_text (tree, value_buff, startOffset, offset,
hf_wsp_parameter_comment, "Comment");
break;
case 0x0D: /* Domain */
add_parameter_text (tree, value_buff, startOffset, offset,
hf_wsp_parameter_domain, "Domain");
offset = add_parameter_text (tree, value_buff, startOffset, offset,
hf_wsp_parameter_domain, "Domain");
break;
case 0x0F: /* Path */
add_parameter_text (tree, value_buff, startOffset, offset,
hf_wsp_parameter_path, "Path");
offset = add_parameter_text (tree, value_buff, startOffset, offset,
hf_wsp_parameter_path, "Path");
break;
case 0x00: /* Q */
case 0x02: /* Level */
case 0x07: /* Differences */
case 0x08: /* Padding */
case 0x09: /* Type (special) */
case 0x0E: /* Max-Age */
case 0x10: /* Secure */
default:
@ -3085,25 +3121,18 @@ add_parameter (proto_tree *tree, tvbuff_t *value_buff, int offset)
return offset;
}
static void
static int
add_untyped_parameter (proto_tree *tree, tvbuff_t *value_buff, int startOffset,
int offset)
{
int tokenOffset;
guint tokenSize;
const guint8 *token;
value_type_t valueType;
int subvalueLen;
int subvalueOffset;
guint value;
int textvOffset;
guint stringSize;
tokenOffset = offset;
tokenSize = tvb_strsize (value_buff, tokenOffset);
token = tvb_get_ptr (value_buff, tokenOffset, tokenSize);
offset += tokenSize;
int vOffset = offset;
token = tvb_get_ptr (value_buff, startOffset, offset - startOffset);
/*
* Now an Untyped-value; either an Integer-value or a Text-value.
*/
@ -3114,9 +3143,7 @@ add_untyped_parameter (proto_tree *tree, tvbuff_t *value_buff, int startOffset,
/*
* Text-value.
*/
textvOffset = offset;
stringSize = tvb_strsize (value_buff, textvOffset);
if (stringSize == 1) {
if ((offset - vOffset) == 1) {
/*
* No-value. (stringSize includes the terminating
* null byte, so an empty string has a size of 1.)
@ -3124,13 +3151,12 @@ add_untyped_parameter (proto_tree *tree, tvbuff_t *value_buff, int startOffset,
proto_tree_add_text (tree, value_buff, startOffset,
offset - startOffset,
"%s", token);
return;
return offset;
}
offset += stringSize;
proto_tree_add_text (tree, value_buff, startOffset,
offset - startOffset,
"%s: %s", token,
tvb_get_ptr (value_buff, textvOffset, stringSize));
tvb_get_ptr (value_buff, vOffset, offset - vOffset));
}
else
{
@ -3151,9 +3177,10 @@ add_untyped_parameter (proto_tree *tree, tvbuff_t *value_buff, int startOffset,
"%s: Invalid Integer-value", token);
}
}
return offset;
}
static void
static int
add_parameter_charset (proto_tree *tree, tvbuff_t *value_buff, int startOffset,
int offset)
{
@ -3172,7 +3199,7 @@ add_parameter_charset (proto_tree *tree, tvbuff_t *value_buff, int startOffset,
proto_tree_add_uint (tree, hf_wsp_parameter_well_known_charset,
value_buff, startOffset, offset - startOffset,
subvalueLen); /* subvalueLen is the value */
return;
return offset;
}
if (valueType == VALUE_IS_TEXT_STRING)
{
@ -3181,7 +3208,7 @@ add_parameter_charset (proto_tree *tree, tvbuff_t *value_buff, int startOffset,
*/
proto_tree_add_text (tree, value_buff, startOffset,
offset - startOffset, "Invalid Well-known charset");
return;
return offset;
}
/*
@ -3194,7 +3221,7 @@ add_parameter_charset (proto_tree *tree, tvbuff_t *value_buff, int startOffset,
*/
proto_tree_add_text (tree, value_buff, startOffset,
offset- startOffset, "*");
return;
return offset;
}
if (get_integer(value_buff, subvalueOffset, subvalueLen,
@ -3206,9 +3233,49 @@ add_parameter_charset (proto_tree *tree, tvbuff_t *value_buff, int startOffset,
proto_tree_add_uint (tree, hf_wsp_parameter_well_known_charset,
value_buff, startOffset, offset - startOffset, value);
}
return offset;
}
static void
static int
add_constrained_encoding (proto_tree *tree, tvbuff_t *value_buff, int startOffset,
int offset)
{
value_type_t valueType;
int subvalueLen;
int subvalueOffset;
guint value;
valueType = get_value_type_len (value_buff, offset,
&subvalueLen, &subvalueOffset, &offset);
if (valueType == VALUE_IN_LEN)
{
/*
* Integer-value, invalid
*/
proto_tree_add_text (tree, value_buff, startOffset,
offset - startOffset, "Invalid multipart type parameter");
return offset;
}
if (valueType == VALUE_IS_TEXT_STRING)
{
/*
* type-label.
*/
proto_tree_add_string (tree, hf_wsp_parameter_upart_type,
value_buff, startOffset, offset - startOffset,
tvb_get_ptr (value_buff, subvalueOffset, subvalueLen));
return offset;
}
/*
* First byte had the 8th bit set.
*/
get_integer(value_buff, subvalueOffset, subvalueLen, valueType, &value);
proto_tree_add_uint (tree, hf_wsp_parameter_upart_type_value,
value_buff, startOffset, offset - startOffset, value);
return offset;
}
static int
add_parameter_type (proto_tree *tree, tvbuff_t *value_buff, int startOffset,
int offset)
{
@ -3227,9 +3294,10 @@ add_parameter_type (proto_tree *tree, tvbuff_t *value_buff, int startOffset,
proto_tree_add_uint (tree, hf_wsp_parameter_type, value_buff,
startOffset, offset - startOffset, value);
}
return offset;
}
static void
static int
add_parameter_text (proto_tree *tree, tvbuff_t *value_buff, int startOffset,
int offset, int hf_string, const char *paramName)
{
@ -3243,9 +3311,11 @@ add_parameter_text (proto_tree *tree, tvbuff_t *value_buff, int startOffset,
proto_tree_add_text (tree, value_buff, startOffset,
offset - startOffset, "Invalid %s", paramName);
} else {
proto_tree_add_item (tree, hf_string, value_buff,
startOffset, offset - startOffset, bo_little_endian);
proto_tree_add_string (tree, hf_string, value_buff,
startOffset, offset - startOffset,
tvb_get_ptr (value_buff, subvalueOffset, subvalueLen));
}
return offset;
}
static void
@ -3296,6 +3366,11 @@ add_post_data (proto_tree *tree, tvbuff_t *tvb, guint contentType,
add_post_variable (ti, tvb, variableStart, variableEnd, valueStart, offset);
}
}
else if ((contentType == 0x22) || (contentType == 0x23) || (contentType == 0x23) || (contentType == 0x24) ||
(contentType == 0x25) || (contentType == 0x26) || (contentType == 0x33))
{
add_multipart_data(ti, tvb);
}
}
static void
@ -3338,6 +3413,57 @@ add_post_variable (proto_tree *tree, tvbuff_t *tvb, guint variableStart, guint v
g_free (valueBuffer);
}
void
add_multipart_data (proto_tree *tree, tvbuff_t *tvb)
{
int offset = 0;
guint nextOffset;
guint nEntries = 0;
guint count;
guint HeadersLen;
guint DataLen;
guint contentType = 0;
const char *contentTypeStr;
tvbuff_t *tmp_tvb;
int partnr = 1;
int part_start;
proto_item *sub_tree = NULL,
*ti;
proto_tree *mpart_tree;
nEntries = tvb_get_guintvar (tvb, offset, &count);
offset += count;
if (nEntries)
{
sub_tree = proto_tree_add_text(tree, tvb, offset - count, 0,
"Multipart body");
proto_item_add_subtree(sub_tree, ett_mpartlist);
}
while (nEntries--)
{
part_start = offset;
HeadersLen = tvb_get_guintvar (tvb, offset, &count);
offset += count;
DataLen = tvb_get_guintvar (tvb, offset, &count);
offset += count;
ti = proto_tree_add_uint(sub_tree, hf_wsp_mpart, tvb, part_start,
HeadersLen + DataLen + (offset - part_start), partnr);
mpart_tree = proto_item_add_subtree(ti, ett_multiparts);
nextOffset = add_content_type (mpart_tree, tvb, offset, &contentType, &contentTypeStr);
HeadersLen -= (nextOffset - offset);
if (HeadersLen > 0)
{
tmp_tvb = tvb_new_subset (tvb, nextOffset, HeadersLen, HeadersLen);
add_headers (mpart_tree, tmp_tvb);
}
offset = nextOffset + HeadersLen;
proto_tree_add_item (mpart_tree, hf_wsp_multipart_data, tvb, offset, DataLen, bo_little_endian);
offset += DataLen;
partnr++;
}
}
static gint
get_integer (tvbuff_t *tvb, guint offset, guint valueLength,
value_type_t valueType, guint *value)
@ -3558,6 +3684,20 @@ proto_register_wsp(void)
"Path", HFILL
}
},
{ &hf_wsp_parameter_upart_type,
{ "Type",
"wsp.content_type.parameter.upart.type",
FT_STRING, BASE_NONE, NULL, 0x00,
"Multipart type", HFILL
}
},
{ &hf_wsp_parameter_upart_type_value,
{ "Type",
"wsp.content_type.parameter.upart.type.int",
FT_UINT8, BASE_DEC, NULL, 0x00,
"Multipart type (int value)", HFILL
}
},
{ &hf_wsp_reply_data,
{ "Data",
"wsp.reply.data",
@ -3864,6 +4004,13 @@ proto_register_wsp(void)
"Application Header Value", HFILL
}
},
{ &hf_wsp_header_content_ID,
{ "Content-ID",
"wsp.header.content-id",
FT_STRING, BASE_NONE, NULL, 0x00,
"Content-ID", HFILL
}
},
{ &hf_wsp_header_x_wap_tod,
{ "X-WAP.TOD",
"wsp.header.x_wap_tod",
@ -3941,6 +4088,20 @@ proto_register_wsp(void)
"Push Data", HFILL
}
},
{ &hf_wsp_multipart_data,
{ "Data in this part",
"wsp.multipart.data",
FT_NONE, BASE_NONE, NULL, 0x00,
"The data of 1 MIME-multipart part.", HFILL
}
},
{ &hf_wsp_mpart,
{ "Part",
"wsp.multipart",
FT_UINT32, BASE_DEC, NULL, 0x00,
"MIME part of multipart data.", HFILL
}
},
{ &hf_wsp_redirect_flags,
{ "Flags",
"wsp.redirect_flags",
@ -4040,6 +4201,8 @@ proto_register_wsp(void)
&ett_content_type,
&ett_redirect_flags,
&ett_redirect_afl,
&ett_multiparts,
&ett_mpartlist
};
/* Register the protocol name and description */
@ -4057,6 +4220,7 @@ proto_register_wsp(void)
register_dissector("wsp-co", dissect_wsp_fromwap_co, proto_wsp);
register_dissector("wsp-cl", dissect_wsp_fromwap_cl, proto_wsp);
wsp_dissector_table = register_dissector_table("wsp.content_type.type");
register_heur_dissector_list("wsp", &heur_subdissector_list);
wsp_fromudp_handle = create_dissector_handle(dissect_wsp_fromudp,

View File

@ -2,7 +2,7 @@
*
* Declarations for disassembly of WSP component of WAP traffic.
*
* $Id: packet-wsp.h,v 1.3 2001/02/13 00:17:54 guy Exp $
* $Id: packet-wsp.h,v 1.4 2001/12/07 11:10:53 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -61,4 +61,7 @@ static const value_string vals_wsp_reason_codes[] = {
{ 0xEE, "Content type cannot be processed" },
};
void add_multipart_data (proto_tree *, tvbuff_t *);
guint add_content_type (proto_tree *, tvbuff_t *, guint, guint *, const char **);
#endif /* packet-wsp.h */