diff options
author | Guy Harris <guy@alum.mit.edu> | 2001-09-25 21:32:41 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2001-09-25 21:32:41 +0000 |
commit | 4325d41fbd225074201140234c7c4b2484f4a0b2 (patch) | |
tree | c28f84a341d0cc3189e512a0bf78fb24ba178be7 | |
parent | a86490d2a7651930059c4750d735cf76efd969af (diff) | |
download | wireshark-4325d41fbd225074201140234c7c4b2484f4a0b2.tar.gz wireshark-4325d41fbd225074201140234c7c4b2484f4a0b2.tar.bz2 wireshark-4325d41fbd225074201140234c7c4b2484f4a0b2.zip |
MMSE support, from Tom Uijldert.
svn path=/trunk/; revision=3954
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | Makefile.nmake | 3 | ||||
-rw-r--r-- | packet-mmse.c | 869 | ||||
-rw-r--r-- | packet-wsp.c | 35 |
5 files changed, 897 insertions, 14 deletions
@@ -793,6 +793,7 @@ Nicolas Balkota <balkota[AT]mac.com> { Tom Uijldert <Tom.Uijldert[AT]cmg.nl> { WTP fixes + MMSE support } Endoh Akira <endoh[AT]netmarks.co.jp> { diff --git a/Makefile.am b/Makefile.am index f0c3f280b7..adac70cec3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ # Makefile.am # Automake file for Ethereal # -# $Id: Makefile.am,v 1.367 2001/09/18 21:29:56 gram Exp $ +# $Id: Makefile.am,v 1.368 2001/09/25 21:32:41 guy Exp $ # # Ethereal - Network traffic analyzer # By Gerald Combs <gerald@ethereal.com> @@ -167,6 +167,7 @@ DISSECTOR_SRC = \ packet-mapi.c \ packet-mbtcp.c \ packet-mip.c \ + packet-mmse.c \ packet-mount.c \ packet-mpeg1.c \ packet-mpls.c \ diff --git a/Makefile.nmake b/Makefile.nmake index ddaa2db962..ccd7cafafd 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.130 2001/08/18 04:27:08 guy Exp $ +# $Id: Makefile.nmake,v 1.131 2001/09/25 21:32:41 guy Exp $ include config.nmake include <win32.mak> @@ -119,6 +119,7 @@ DISSECTOR_SRC = \ packet-mapi.c \ packet-mbtcp.c \ packet-mip.c \ + packet-mmse.c \ packet-mount.c \ packet-mpeg1.c \ packet-mpls.c \ diff --git a/packet-mmse.c b/packet-mmse.c new file mode 100644 index 0000000000..6f6748bc9f --- /dev/null +++ b/packet-mmse.c @@ -0,0 +1,869 @@ +/* packet-mmse.c + * Routines for MMS Message Encapsulation dissection + * Copyright 2001, Tom Uijldert <tom.uijldert@cmg.nl> + * + * $Id: packet-mmse.c,v 1.1 2001/09/25 21:32:41 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. + * ---------- + * + * Dissector of an encoded Multimedia message PDU, as defined by the WAPForum + * (http://www.wapforum.org) in "WAP-209.102-MMSEncapsulation" according + * the draft version of 8-February-2001. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif + +#ifdef HAVE_NETINET_IN_H +# include <netinet/in.h> +#endif + +#include <glib.h> + +#ifdef NEED_SNPRINTF_H +# include "snprintf.h" +#endif + +#include "packet.h" +#include "packet-wap.h" +/* #include "packet-mmse.h" */ /* We autoregister */ + +#define MM_QUOTE 0x7F /* Quoted string */ + +/* + * Header field values + */ +#define MM_BCC_HDR 0x81 /* Bcc */ +#define MM_CC_HDR 0x82 /* Cc */ +#define MM_CLOCATION_HDR 0x83 /* Content-Location */ +#define MM_CTYPE_HDR 0x84 /* Content-Type */ +#define MM_DATE_HDR 0x85 /* Date */ +#define MM_DREPORT_HDR 0x86 /* Delivery-Report */ +#define MM_DTIME_HDR 0x87 /* Delivery-Time */ +#define MM_EXPIRY_HDR 0x88 /* Expiry */ +#define MM_FROM_HDR 0x89 /* From */ +#define MM_MCLASS_HDR 0x8A /* Message-Class */ +#define MM_MID_HDR 0x8B /* Message-ID */ +#define MM_MTYPE_HDR 0x8C /* Message-Type */ +#define MM_VERSION_HDR 0x8D /* MMS-Version */ +#define MM_MSIZE_HDR 0x8E /* Message-Size */ +#define MM_PRIORITY_HDR 0x8F /* Priority */ +#define MM_RREPLY_HDR 0x90 /* Read-Reply */ +#define MM_RALLOWED_HDR 0x91 /* Report-Allowed */ +#define MM_RSTATUS_HDR 0x92 /* Response-Status */ +#define MM_RTEXT_HDR 0x93 /* Response-Text */ +#define MM_SVISIBILITY_HDR 0x94 /* Sender-Visibility */ +#define MM_STATUS_HDR 0x95 /* Status */ +#define MM_SUBJECT_HDR 0x96 /* Subject */ +#define MM_TO_HDR 0x97 /* To */ +#define MM_TID_HDR 0x98 /* Transaction-Id */ + +/* + * Initialize the protocol and registered fields + */ +static int proto_mmse = -1; + +static int hf_mmse_message_type = -1; +static int hf_mmse_transaction_id = -1; +static int hf_mmse_mms_version = -1; +static int hf_mmse_bcc = -1; +static int hf_mmse_cc = -1; +static int hf_mmse_content_location = -1; +static int hf_mmse_date = -1; +static int hf_mmse_delivery_report = -1; +static int hf_mmse_delivery_time_abs = -1; +static int hf_mmse_delivery_time_rel = -1; +static int hf_mmse_expiry_abs = -1; +static int hf_mmse_expiry_rel = -1; +static int hf_mmse_from = -1; +static int hf_mmse_message_class_id = -1; +static int hf_mmse_message_class_str = -1; +static int hf_mmse_message_id = -1; +static int hf_mmse_message_size = -1; +static int hf_mmse_priority = -1; +static int hf_mmse_read_reply = -1; +static int hf_mmse_report_allowed = -1; +static int hf_mmse_response_status = -1; +static int hf_mmse_response_text = -1; +static int hf_mmse_sender_visibility = -1; +static int hf_mmse_status = -1; +static int hf_mmse_subject = -1; +static int hf_mmse_to = -1; +static int hf_mmse_content_type = -1; +static int hf_mmse_ffheader = -1; + +/* + * Initialize the subtree pointers + */ +static gint ett_mmse = -1; + +/* + * Valuestrings for header contents + */ +static const value_string vals_message_type[] = { + { 0x80, "m-send-req" }, + { 0x81, "m-send-conf" }, + { 0x82, "m-notification-ind" }, + { 0x83, "m-notifyresp-ind" }, + { 0x84, "m-retrieve-conf" }, + { 0x85, "m-acknowledge-ind" }, + { 0x86, "m-delivery-ind" }, + { 0x00, NULL }, +}; + +static const value_string vals_yes_no[] = { + { 0x80, "Yes" }, + { 0x81, "No" }, + { 0x00, NULL }, +}; + +static const value_string vals_message_class[] = { + { 0x80, "Personal" }, + { 0x81, "Advertisement" }, + { 0x82, "Informational" }, + { 0x82, "Auto" }, + { 0x00, NULL }, +}; + +static const value_string vals_priority[] = { + { 0x80, "Low" }, + { 0x81, "Normal" }, + { 0x81, "High" }, + { 0x00, NULL }, +}; + +static const value_string vals_response_status[] = { + { 0x80, "Ok" }, + { 0x81, "Unspecified" }, + { 0x82, "Service denied" }, + { 0x83, "Message format corrupt" }, + { 0x84, "sending address unresolved" }, + { 0x85, "message not found" }, + { 0x86, "Network problem" }, + { 0x87, "Content not accepted" }, + { 0x88, "Unsupported message" }, + { 0x00, NULL }, +}; + +static const value_string vals_sender_visibility[] = { + { 0x80, "Hide" }, + { 0x81, "Show" }, + { 0x00, NULL }, +}; + +static const value_string vals_status[] = { + { 0x80, "Expired" }, + { 0x81, "Retrieved" }, + { 0x82, "Rejected" }, + { 0x82, "Deferred" }, + { 0x82, "Unrecognized" }, + { 0x00, NULL }, +}; + +/*! + * Decodes a Text-string from the protocol data + * Text-string = [Quote] *TEXT End-of-string + * Quote = <Octet 127> + * End-of-string = <Octet 0> + * + * \todo Shouldn't we be sharing this with WSP (packet-wap.c)? + * + * \param tvb The buffer with PDU-data + * \param offset Offset within that buffer + * \param strval String buffer to receive the text, reserve memory! + * + * \return The length in bytes of the entire field + */ +static guint +get_text_string(tvbuff_t *tvb, guint offset, char *strval) +{ + guint len; + + len = tvb_strsize(tvb, offset); + if (tvb_get_guint8(tvb, offset) == MM_QUOTE) + tvb_memcpy(tvb, strval, offset + 1, len - 1); + else + tvb_memcpy(tvb, strval, offset, len); + return len; +} + +/*! + * Decodes a Value-length from the protocol data. + * Value-length = Short-length | (Length-quote Length) + * Short-length = <Any octet 0-30> + * Length-quote = <Octet 31> + * Length = Uintvar-integer + * + * \todo Shouldn't we be sharing this with WSP (packet-wap.c)? + * + * \param tvb The buffer with PDU-data + * \param offset Offset within that buffer + * \param byte_count Returns the length in bytes of + * the "Value-length" field. + * + * \return The actual value of "Value-length" + */ +static guint +get_value_length(tvbuff_t *tvb, guint offset, guint *byte_count) +{ + guint field; + + field = tvb_get_guint8(tvb, offset++); + if (field < 31) + *byte_count = 1; + else { /* Must be 31 so, Uintvar follows */ + field = tvb_get_guintvar(tvb, offset, byte_count); + (*byte_count)++; + } + return field; +} + +/*! + * Decodes an Encoded-string-value from the protocol data + * Encoded-string-value = Text-string | Value-length Char-set Text-string + * + * \param tvb The buffer with PDU-data + * \param offset Offset within that buffer + * \param strval String buffer to receive the text, reserve memory! + * + * \return The length in bytes of the entire field + */ +static guint +get_encoded_strval(tvbuff_t *tvb, guint offset, char *strval) +{ + guint field; + guint length; + guint count; + + field = tvb_get_guint8(tvb, offset); + + if (field < 32) { + length = get_value_length(tvb, offset, &count); + /* \todo Something with "Char-set", skip for now */ + tvb_memcpy(tvb, strval, offset + count + 1, length - 1); + strval[length - 1] = '\0'; /* Just to make sure */ + return offset + count + length; + } else + return get_text_string(tvb, offset, strval); +} + +/*! + * Decodes a Long-integer from the protocol data + * Long-integer = Short-length Multi-octet-integer + * Short-length = <Any octet 0-30> + * Multi-octet-integer = 1*30OCTET + * + * \todo Shouldn't we be sharing this with WSP (packet-wap.c)? + * + * \param tvb The buffer with PDU-data + * \param offset Offset within that buffer + * \param byte_count Returns the length in bytes of the field + * + * \return The value of the Long-integer + * + * \note A maximum of 4-byte integers will be handled. + */ +static guint +get_long_integer(tvbuff_t *tvb, guint offset, guint *byte_count) +{ + guint val; + + *byte_count = tvb_get_guint8(tvb, offset++); + switch (*byte_count) { + case 1: + val = tvb_get_guint8(tvb, offset); + break; + case 2: + val = tvb_get_ntohs(tvb, offset); + break; + case 3: + val = tvb_get_ntoh24(tvb, offset); + break; + case 4: + val = tvb_get_ntohl(tvb, offset); + break; + default: + val = 0; + break; + } + (*byte_count)++; + return val; +} + +/* Code to actually dissect the packets */ +static gboolean +dissect_mmse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + guint8 pdut; + guint offset; + guint8 field = 0; + char strval[BUFSIZ]; + guint length; + guint count; + + /* 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; + + /* 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"); + + if (check_col(pinfo->fd, COL_INFO)) { + col_clear(pinfo->fd, COL_INFO); + col_add_fstr(pinfo->fd, COL_INFO, "MMS %s", + match_strval(pdut, vals_message_type)); + } + + /* In the interest of speed, if "tree" is NULL, don't do any work not + * necessary to generate protocol tree items. + */ + if (tree) { + offset = 2; /* Skip Message-Type */ + + /* create display subtree for the protocol */ + ti = proto_tree_add_item(tree, proto_mmse, tvb, 0, + tvb_length(tvb), FALSE); + mmse_tree = proto_item_add_subtree(ti, ett_mmse); + + /* Report PDU-type */ + proto_tree_add_uint(mmse_tree, hf_mmse_message_type, tvb, 0, 2, pdut); + /* + * Cycle through MMS-headers + */ + while ((offset < tvb_length(tvb)) && + (field = tvb_get_guint8(tvb, offset++)) != MM_CTYPE_HDR) + { + switch (field) + { + case MM_TID_HDR: /* Text-string */ + length = get_text_string(tvb, offset, strval); + proto_tree_add_string(mmse_tree, hf_mmse_transaction_id, + tvb, offset - 1, length + 1,strval); + offset += length; + break; + case MM_VERSION_HDR: /* nibble-Major/nibble-minor*/ + field = tvb_get_guint8(tvb, offset++); + { + guint8 major, minor; + + major = (field & 0x70) >> 4; + minor = field & 0x0F; + if (minor == 0x0F) + sprintf(strval, "%d", major); + else + sprintf(strval, "%d.%d", major, minor); + } + proto_tree_add_string(mmse_tree, hf_mmse_mms_version, tvb, + offset - 2, 2, strval); + break; + case MM_BCC_HDR: /* Encoded-string-value */ + length = get_encoded_strval(tvb, offset, strval); + proto_tree_add_string(mmse_tree, hf_mmse_bcc, tvb, + offset - 1, length + 1, strval); + offset += length; + break; + case MM_CC_HDR: /* Encoded-string-value */ + length = get_encoded_strval(tvb, offset, strval); + proto_tree_add_string(mmse_tree, hf_mmse_cc, tvb, + offset - 1, length + 1, strval); + offset += length; + break; + case MM_CLOCATION_HDR: /* Uri-value */ + length = get_text_string(tvb, offset, strval); + proto_tree_add_string(mmse_tree, hf_mmse_content_location, + tvb, offset - 1, length + 1,strval); + offset += length; + break; + case MM_DATE_HDR: /* Long-integer */ + { + guint tval; + nstime_t tmptime; + + tval = get_long_integer(tvb, offset, &count); + tmptime.secs = tval; + tmptime.nsecs = 0; + proto_tree_add_time(mmse_tree, hf_mmse_date, tvb, + offset - 1, count + 1, &tmptime); + } + offset += count; + break; + case MM_DREPORT_HDR: /* Yes|No */ + field = tvb_get_guint8(tvb, offset++); + proto_tree_add_uint(mmse_tree, hf_mmse_delivery_report, tvb, + offset - 2, 2, field); + break; + case MM_DTIME_HDR: + /* + * Value-length(Absolute-token Date-value| + * Relative-token Delta-seconds-value) + */ + length = get_value_length(tvb, offset, &count); + field = tvb_get_guint8(tvb, offset + count); + { + guint tval; + nstime_t tmptime; + guint cnt; + + tval = get_long_integer(tvb, offset + count, &cnt); + tmptime.secs = tval; + tmptime.nsecs = 0; + if (field == 0x80) + proto_tree_add_time(mmse_tree, + hf_mmse_delivery_time_abs, + tvb, offset - 1, + length + count + 1, &tmptime); + else + proto_tree_add_time(mmse_tree, + hf_mmse_delivery_time_rel, + tvb, offset - 1, + length + count + 1, &tmptime); + } + offset += length + count; + break; + case MM_EXPIRY_HDR: + /* + * Value-length(Absolute-token Date-value| + * Relative-token Delta-seconds-value) + */ + length = get_value_length(tvb, offset, &count); + field = tvb_get_guint8(tvb, offset + count); + { + guint tval; + nstime_t tmptime; + guint cnt; + + tval = get_long_integer(tvb, offset + count, &cnt); + tmptime.secs = tval; + tmptime.nsecs = 0; + if (field == 0x80) + proto_tree_add_time(mmse_tree, hf_mmse_expiry_abs, + tvb, offset - 1, + length + count + 1, &tmptime); + else + proto_tree_add_time(mmse_tree, hf_mmse_expiry_rel, + tvb, offset - 1, + length + count + 1, &tmptime); + } + offset += length + count; + break; + case MM_FROM_HDR: + /* + * Value-length(Address-present-token Encoded-string-value + * |Insert-address-token) + */ + length = get_value_length(tvb, offset, &count); + field = tvb_get_guint8(tvb, offset + count); + if (field == 0x81) { + strcpy(strval, "<insert address>"); + } else { + (void) get_encoded_strval(tvb, offset + count + 1, + strval); + } + proto_tree_add_string(mmse_tree, hf_mmse_from, tvb, + offset-1, length + 2, strval); + offset += length + 1; + break; + case MM_MCLASS_HDR: + /* + * Class-identifier|Text-string + */ + field = tvb_get_guint8(tvb, offset); + if (field & 0x80) { + offset++; + proto_tree_add_uint(mmse_tree, + hf_mmse_message_class_id, + tvb, offset - 2, 2, field); + } else { + length = get_text_string(tvb, offset, strval); + proto_tree_add_string(mmse_tree, + hf_mmse_message_class_str, + tvb, offset - 1, length + 1, + strval); + offset += length; + } + break; + case MM_MID_HDR: /* Text-string */ + length = get_text_string(tvb, offset, strval); + proto_tree_add_string(mmse_tree, hf_mmse_message_id, tvb, + offset - 1, length + 1, strval); + offset += length; + break; + case MM_MSIZE_HDR: /* Long-integer */ + length = get_long_integer(tvb, offset, &count); + proto_tree_add_uint(mmse_tree, hf_mmse_message_size, tvb, + offset - 1, count + 1, length); + offset += count; + break; + case MM_PRIORITY_HDR: /* Low|Normal|High */ + field = tvb_get_guint8(tvb, offset++); + proto_tree_add_uint(mmse_tree, hf_mmse_priority, tvb, + offset - 2, 2, field); + break; + case MM_RREPLY_HDR: /* Yes|No */ + field = tvb_get_guint8(tvb, offset++); + proto_tree_add_uint(mmse_tree, hf_mmse_read_reply, tvb, + offset - 2, 2, field); + break; + case MM_RALLOWED_HDR: /* Yes|No */ + field = tvb_get_guint8(tvb, offset++); + proto_tree_add_uint(mmse_tree, hf_mmse_report_allowed, tvb, + offset - 2, 2, field); + break; + case MM_RSTATUS_HDR: + field = tvb_get_guint8(tvb, offset++); + proto_tree_add_uint(mmse_tree, hf_mmse_response_status, tvb, + offset - 2, 2, field); + break; + case MM_RTEXT_HDR: /* Encoded-string-value */ + length = get_encoded_strval(tvb, offset, strval); + proto_tree_add_string(mmse_tree, hf_mmse_response_text, tvb, + offset - 1, length + 1, strval); + offset += length; + break; + case MM_SVISIBILITY_HDR: /* Hide|Show */ + field = tvb_get_guint8(tvb, offset++); + proto_tree_add_uint(mmse_tree,hf_mmse_sender_visibility, + tvb, offset - 2, 2, field); + break; + case MM_STATUS_HDR: + field = tvb_get_guint8(tvb, offset++); + proto_tree_add_uint(mmse_tree, hf_mmse_status, tvb, + offset - 2, 2, field); + break; + case MM_SUBJECT_HDR: /* Encoded-string-value */ + length = get_encoded_strval(tvb, offset, strval); + proto_tree_add_string(mmse_tree, hf_mmse_subject, tvb, + offset - 1, length + 1, strval); + offset += length; + break; + case MM_TO_HDR: /* Encoded-string-value */ + length = get_encoded_strval(tvb, offset, strval); + proto_tree_add_string(mmse_tree, hf_mmse_to, tvb, + offset - 1, length + 1, strval); + offset += length; + break; + default: + if (field & 0x80) { + fprintf(stderr, + "MMSE - Unknown field encountered (0x%02x)\n", + field); + } else { + guint length2; + char strval2[BUFSIZ]; + + --offset; + length = get_text_string(tvb, offset, strval); + length2= get_text_string(tvb, offset+length, strval2); + + proto_tree_add_string_format(mmse_tree, + hf_mmse_ffheader, + tvb, offset, + length + length2, NULL, + "%s : %s",strval,strval2); + offset += length + length2; + } + break; + } + } + 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... + */ + proto_tree_add_item(mmse_tree, hf_mmse_content_type, tvb, + offset - 1, + tvb_length_remaining(tvb, offset - 1), FALSE); + return TRUE; + } + } + return TRUE; + + /* If this protocol has a sub-dissector call it here, see section 1.8 */ +} + + +/* Register the protocol with Ethereal */ + +/* this format is required because a script is used to build the C function + * that calls all the protocol registration. + */ +void +proto_register_mmse(void) +{ + /* Setup list of header fields See Section 1.6.1 for details */ + static hf_register_info hf[] = { + { &hf_mmse_message_type, + { "Message-Type", "mmse.message_length", + FT_UINT8, BASE_HEX, VALS(vals_message_type), 0x00, + "Specifies the transaction type. Effectively defines PDU.", + HFILL + } + }, + { &hf_mmse_transaction_id, + { "Transaction-ID", "mmse.transaction_id", + FT_STRING, BASE_NONE, NULL, 0x00, + "A unique identifier for this transaction. " + "Identifies request and corresponding response only.", + HFILL + } + }, + { &hf_mmse_mms_version, + { "MMS-Version", "mmse.mms_version", + FT_STRING, BASE_NONE, NULL, 0x00, + "Version of the protocol used.", + HFILL + } + }, + { &hf_mmse_bcc, + { "Bcc", "mmse.bcc", + FT_STRING, BASE_NONE, NULL, 0x00, + "Blind carbon copy.", + HFILL + } + }, + { &hf_mmse_cc, + { "Bcc", "mmse.bcc", + FT_STRING, BASE_NONE, NULL, 0x00, + "Carbon copy.", + HFILL + } + }, + { &hf_mmse_content_location, + { "Content-Location", "mmse.content_location", + FT_STRING, BASE_NONE, NULL, 0x00, + "Defines the location of the message.", + HFILL + } + }, + { &hf_mmse_date, + { "Date", "mmse.date", + FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00, + "Arrival timestamp of the message or sending timestamp.", + HFILL + } + }, + { &hf_mmse_delivery_report, + { "Delivery-Report", "mmse.delivery_report", + FT_UINT8, BASE_HEX, VALS(vals_yes_no), 0x00, + "Whether a report of message delivery is wanted or not.", + HFILL + } + }, + { &hf_mmse_delivery_time_abs, + { "Delivery-Time", "mmse.delivery_time.abs", + FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00, + "The time at which message delivery is desired.", + HFILL + } + }, + { &hf_mmse_delivery_time_rel, + { "Delivery-Time", "mmse.delivery_time.rel", + FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00, + "The desired message delivery delay.", + HFILL + } + }, + { &hf_mmse_expiry_abs, + { "Expiry", "mmse.expiry.abs", + FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00, + "Time when message expires and need not be delivered anymore.", + HFILL + } + }, + { &hf_mmse_expiry_rel, + { "Expiry", "mmse.expiry.rel", + FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00, + "Delay before message expires and need not be delivered anymore.", + HFILL + } + }, + { &hf_mmse_from, + { "From", "mmse.from", + FT_STRING, BASE_NONE, NULL, 0x00, + "Address of the message sender.", + HFILL + } + }, + { &hf_mmse_message_class_id, + { "Message-Class", "mmse.message_class.id", + FT_UINT8, BASE_HEX, VALS(vals_message_class), 0x00, + "Of what category is the message.", + HFILL + } + }, + { &hf_mmse_message_class_str, + { "Message-Class", "mmse.message_class.str", + FT_STRING, BASE_NONE, NULL, 0x00, + "Of what category is the message.", + HFILL + } + }, + { &hf_mmse_message_id, + { "Message-Id", "mmse.message_id", + FT_STRING, BASE_NONE, NULL, 0x00, + "Unique identification of the message.", + HFILL + } + }, + { &hf_mmse_message_size, + { "Message-Size", "mmse.message_size", + FT_UINT32, BASE_DEC, NULL, 0x00, + "The size of the message in octets.", + HFILL + } + }, + { &hf_mmse_priority, + { "Priority", "mmse.priority", + FT_UINT8, BASE_HEX, VALS(vals_priority), 0x00, + "Priority of the message.", + HFILL + } + }, + { &hf_mmse_read_reply, + { "Read-Reply", "mmse.read_reply", + FT_UINT8, BASE_HEX, VALS(vals_yes_no), 0x00, + "Whether a read report from every recipient is wanted.", + HFILL + } + }, + { &hf_mmse_report_allowed, + { "Report-Allowed", "mmse.report_allowed", + FT_UINT8, BASE_HEX, VALS(vals_yes_no), 0x00, + "Sending of delivery report allowed or not.", + HFILL + } + }, + { &hf_mmse_response_status, + { "Response-Status", "mmse.response_status", + FT_UINT8, BASE_HEX, VALS(vals_response_status), 0x00, + "MMS-specific result of a message submission or retrieval.", + HFILL + } + }, + { &hf_mmse_response_text, + { "Response-Text", "mmse.response_text", + FT_STRING, BASE_NONE, NULL, 0x00, + "Additional information on MMS-specific result.", + HFILL + } + }, + { &hf_mmse_sender_visibility, + { "Sender-Visibility", "mmse.sender_visibility", + FT_UINT8, BASE_HEX, VALS(vals_yes_no), 0x00, + "Disclose sender identity to receiver or not.", + HFILL + } + }, + { &hf_mmse_status, + { "Status", "mmse.status", + FT_UINT8, BASE_HEX, VALS(vals_status), 0x00, + "Current status of the message.", + HFILL + } + }, + { &hf_mmse_subject, + { "Subject", "mmse.subject", + FT_STRING, BASE_NONE, NULL, 0x00, + "Subject of the message.", + HFILL + } + }, + { &hf_mmse_to, + { "To", "mmse.to", + FT_STRING, BASE_NONE, NULL, 0x00, + "Recipient(s) of the message.", + HFILL + } + }, + { &hf_mmse_content_type, + { "Data", "mmse.content_type", + FT_NONE, BASE_NONE, NULL, 0x00, + "Media content of the message.", + HFILL + } + }, + { &hf_mmse_ffheader, + { "Free format (not encoded) header", "mmse.ffheader", + FT_STRING, BASE_NONE, NULL, 0x00, + "Application header without corresponding encoding.", + HFILL + } + }, + }; + /* Setup protocol subtree array */ + static gint *ett[] = { + &ett_mmse, + }; + + /* Register the protocol name and description */ + proto_mmse = proto_register_protocol("MMS Message Encapsulation", + "WAP-MMSE", "mmse"); + + /* Required function calls to register header fields and subtrees used */ + proto_register_field_array(proto_mmse, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + +/* If this dissector uses sub-dissector registration add registration routine. + * This format is required because a script is used to find these routines and + * create the code that calls these routines. + */ +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... + */ + /* + * \todo + * The bearer could also be http (through the same content-type field). + * Same modifications would apply there. + */ +} diff --git a/packet-wsp.c b/packet-wsp.c index 2b8b3dfe74..e5adb3821e 100644 --- a/packet-wsp.c +++ b/packet-wsp.c @@ -2,7 +2,7 @@ * * Routines to dissect WSP component of WAP traffic. * - * $Id: packet-wsp.c,v 1.36 2001/09/25 18:27:35 guy Exp $ + * $Id: packet-wsp.c,v 1.37 2001/09/25 21:32:41 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -709,6 +709,8 @@ typedef enum { VALUE_IN_LEN, } value_type_t; +static heur_dissector_list_t heur_subdissector_list; + static void add_uri (proto_tree *, tvbuff_t *, guint, guint); static void add_headers (proto_tree *, tvbuff_t *); static int add_well_known_header (proto_tree *, tvbuff_t *, int, guint8); @@ -1125,15 +1127,15 @@ dissect_wsp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, break; case POST: - if (tree) { - uriStart = offset; - count = 0; /* Initialise count */ - uriLength = tvb_get_guintvar (tvb, offset, &count); - headerStart = uriStart+count; - count = 0; /* Initialise count */ - headersLength = tvb_get_guintvar (tvb, headerStart, &count); - offset = headerStart + count; + uriStart = offset; + count = 0; /* Initialise count */ + uriLength = tvb_get_guintvar (tvb, offset, &count); + headerStart = uriStart+count; + count = 0; /* Initialise count */ + headersLength = tvb_get_guintvar (tvb, headerStart, &count); + offset = headerStart + count; + if (tree) { add_uri (wsp_tree, tvb, uriStart, offset); offset += uriLength; @@ -1163,13 +1165,16 @@ dissect_wsp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, add_post_data (wsp_tree, tmp_tvb, contentType, contentTypeStr); } + tmp_tvb = tvb_new_subset (tvb, headerStart + count + uriLength + headersLength, -1, -1); + dissector_try_heuristic(heur_subdissector_list, tmp_tvb, pinfo, tree); break; case REPLY: + count = 0; /* Initialise count */ + headersLength = tvb_get_guintvar (tvb, offset+1, &count); + headerStart = offset + count + 1; if (tree) { ti = proto_tree_add_item (wsp_tree, hf_wsp_header_status,tvb,offset,1,bo_little_endian); - count = 0; /* Initialise count */ - headersLength = tvb_get_guintvar (tvb, offset+1, &count); nextOffset = offset + 1 + count; ti = proto_tree_add_uint (wsp_tree, hf_wsp_header_length,tvb,offset+1,count,headersLength); @@ -1189,7 +1194,7 @@ dissect_wsp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, tmp_tvb = tvb_new_subset (tvb, nextOffset, headerLength, headerLength); add_headers (wsp_tree, tmp_tvb); } - offset += count+headerLength+1; + offset += count+headersLength+1; /* TODO: Data - decode WMLC */ /* Runs from offset+1+count+headerLength+1 to end of frame */ @@ -1198,6 +1203,11 @@ dissect_wsp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ti = proto_tree_add_item (wsp_tree, hf_wsp_reply_data,tvb,offset,tvb_length_remaining(tvb, offset),bo_little_endian); } } + 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); + } break; } } @@ -3856,6 +3866,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); + register_heur_dissector_list("wsp", &heur_subdissector_list); }; void |