aboutsummaryrefslogtreecommitdiffstats
path: root/packet-mmse.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2001-09-25 21:32:41 +0000
committerGuy Harris <guy@alum.mit.edu>2001-09-25 21:32:41 +0000
commit4325d41fbd225074201140234c7c4b2484f4a0b2 (patch)
treec28f84a341d0cc3189e512a0bf78fb24ba178be7 /packet-mmse.c
parenta86490d2a7651930059c4750d735cf76efd969af (diff)
MMSE support, from Tom Uijldert.
svn path=/trunk/; revision=3954
Diffstat (limited to 'packet-mmse.c')
-rw-r--r--packet-mmse.c869
1 files changed, 869 insertions, 0 deletions
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.
+ */
+}