2 * Routines for MMS Message Encapsulation dissection
3 * Copyright 2001, Tom Uijldert <tom.uijldert@cmg.nl>
5 * $Id: packet-mmse.c,v 1.32 2004/02/06 01:07:51 obiot Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 * Dissector of an encoded Multimedia message PDU, as defined by the WAPForum
27 * (http://www.wapforum.org) in "WAP-209-MMSEncapsulation-20020105-a".
30 /* This file has been edited with 8-space tabs and 4-space indentation */
42 #include <epan/packet.h>
43 #include "packet-wap.h"
44 #include "packet-wsp.h"
45 /* #include "packet-mmse.h" */ /* We autoregister */
47 #define MM_QUOTE 0x7F /* Quoted string */
49 #define MMS_CONTENT_TYPE 0x3E /* WINA-value for mms-message */
51 /* General-purpose debug logger.
52 * Requires double parentheses because of variable arguments of printf().
54 * Enable debug logging for MMSE by defining AM_CFLAGS
55 * so that it contains "-DDEBUG_mmse"
59 printf("%s:%u: ", __FILE__, __LINE__); \
68 * Forward declarations
70 static void dissect_mmse_standalone(tvbuff_t *, packet_info *, proto_tree *);
71 static void dissect_mmse_encapsulated(tvbuff_t *, packet_info *, proto_tree *);
72 static void dissect_mmse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
73 guint8 pdut, char *message_type);
78 #define MM_BCC_HDR 0x81 /* Bcc */
79 #define MM_CC_HDR 0x82 /* Cc */
80 #define MM_CLOCATION_HDR 0x83 /* Content-Location */
81 #define MM_CTYPE_HDR 0x84 /* Content-Type */
82 #define MM_DATE_HDR 0x85 /* Date */
83 #define MM_DREPORT_HDR 0x86 /* Delivery-Report */
84 #define MM_DTIME_HDR 0x87 /* Delivery-Time */
85 #define MM_EXPIRY_HDR 0x88 /* Expiry */
86 #define MM_FROM_HDR 0x89 /* From */
87 #define MM_MCLASS_HDR 0x8A /* Message-Class */
88 #define MM_MID_HDR 0x8B /* Message-ID */
89 #define MM_MTYPE_HDR 0x8C /* Message-Type */
90 #define MM_VERSION_HDR 0x8D /* MMS-Version */
91 #define MM_MSIZE_HDR 0x8E /* Message-Size */
92 #define MM_PRIORITY_HDR 0x8F /* Priority */
93 #define MM_RREPLY_HDR 0x90 /* Read-Reply */
94 #define MM_RALLOWED_HDR 0x91 /* Report-Allowed */
95 #define MM_RSTATUS_HDR 0x92 /* Response-Status */
96 #define MM_RTEXT_HDR 0x93 /* Response-Text */
97 #define MM_SVISIBILITY_HDR 0x94 /* Sender-Visibility */
98 #define MM_STATUS_HDR 0x95 /* Status */
99 #define MM_SUBJECT_HDR 0x96 /* Subject */
100 #define MM_TO_HDR 0x97 /* To */
101 #define MM_TID_HDR 0x98 /* Transaction-Id */
103 static const value_string vals_mm_header_names[] = {
104 { MM_BCC_HDR, "Bcc" },
106 { MM_CLOCATION_HDR, "Content-Location" },
107 { MM_CTYPE_HDR, "Content-Type" },
108 { MM_DATE_HDR, "Date" },
109 { MM_DREPORT_HDR, "Delivery-Report" },
110 { MM_DTIME_HDR, "Delivery-Time" },
111 { MM_EXPIRY_HDR, "Expiry" },
112 { MM_FROM_HDR, "From" },
113 { MM_MCLASS_HDR, "Message-Class" },
114 { MM_MID_HDR, "Message-ID" },
115 { MM_MTYPE_HDR, "Message-Type" },
116 { MM_VERSION_HDR, "MMS-Version" },
117 { MM_MSIZE_HDR, "Message-Size" },
118 { MM_PRIORITY_HDR, "Priority" },
119 { MM_RREPLY_HDR, "Read-Reply" },
120 { MM_RALLOWED_HDR, "Report-Allowed" },
121 { MM_RSTATUS_HDR, "Response-Status" },
122 { MM_RTEXT_HDR, "Response-Text" },
123 { MM_SVISIBILITY_HDR, "Sender-Visibility" },
124 { MM_STATUS_HDR, "Status" },
125 { MM_SUBJECT_HDR, "Subject" },
127 { MM_TID_HDR, "Transaction-Id" },
132 * Initialize the protocol and registered fields
134 static int proto_mmse = -1;
136 static int hf_mmse_message_type = -1;
137 static int hf_mmse_transaction_id = -1;
138 static int hf_mmse_mms_version = -1;
139 static int hf_mmse_bcc = -1;
140 static int hf_mmse_cc = -1;
141 static int hf_mmse_content_location = -1;
142 static int hf_mmse_date = -1;
143 static int hf_mmse_delivery_report = -1;
144 static int hf_mmse_delivery_time_abs = -1;
145 static int hf_mmse_delivery_time_rel = -1;
146 static int hf_mmse_expiry_abs = -1;
147 static int hf_mmse_expiry_rel = -1;
148 static int hf_mmse_from = -1;
149 static int hf_mmse_message_class_id = -1;
150 static int hf_mmse_message_class_str = -1;
151 static int hf_mmse_message_id = -1;
152 static int hf_mmse_message_size = -1;
153 static int hf_mmse_priority = -1;
154 static int hf_mmse_read_reply = -1;
155 static int hf_mmse_report_allowed = -1;
156 static int hf_mmse_response_status = -1;
157 static int hf_mmse_response_text = -1;
158 static int hf_mmse_sender_visibility = -1;
159 static int hf_mmse_status = -1;
160 static int hf_mmse_subject = -1;
161 static int hf_mmse_to = -1;
162 static int hf_mmse_content_type = -1;
163 static int hf_mmse_ffheader = -1;
166 * Initialize the subtree pointers
168 static gint ett_mmse = -1;
171 * Valuestrings for header contents
174 #define PDU_M_SEND_REQ 0x80
175 #define PDU_M_SEND_CONF 0x81
176 #define PDU_M_NOTIFICATION_IND 0x82
177 #define PDU_M_NOTIFYRESP_IND 0x83
178 #define PDU_M_RETRIEVE_CONF 0x84
179 #define PDU_M_ACKNOWLEDGE_IND 0x85
180 #define PDU_M_DELIVERY_IND 0x86
182 #define pdu_has_content(pdut) \
183 ( ((pdut) == PDU_M_SEND_REQ) \
184 || ((pdut) == PDU_M_DELIVERY_IND) )
186 static const value_string vals_message_type[] = {
187 { PDU_M_SEND_REQ, "m-send-req" },
188 { PDU_M_SEND_CONF, "m-send-conf" },
189 { PDU_M_NOTIFICATION_IND, "m-notification-ind" },
190 { PDU_M_NOTIFYRESP_IND, "m-notifyresp-ind" },
191 { PDU_M_RETRIEVE_CONF, "m-retrieve-conf" },
192 { PDU_M_ACKNOWLEDGE_IND, "m-acknowledge-ind" },
193 { PDU_M_DELIVERY_IND, "m-delivery-ind" },
197 static const value_string vals_yes_no[] = {
203 static const value_string vals_message_class[] = {
204 { 0x80, "Personal" },
205 { 0x81, "Advertisement" },
206 { 0x82, "Informational" },
211 static const value_string vals_priority[] = {
218 static const value_string vals_response_status[] = {
220 { 0x81, "Unspecified" },
221 { 0x82, "Service denied" },
222 { 0x83, "Message format corrupt" },
223 { 0x84, "Sending address unresolved" },
224 { 0x85, "Message not found" },
225 { 0x86, "Network problem" },
226 { 0x87, "Content not accepted" },
227 { 0x88, "Unsupported message" },
231 static const value_string vals_sender_visibility[] = {
237 static const value_string vals_message_status[] = {
239 { 0x81, "Retrieved" },
240 { 0x82, "Rejected" },
241 { 0x83, "Deferred" },
242 { 0x84, "Unrecognized" },
247 * Decodes a Text-string from the protocol data
248 * Text-string = [Quote] *TEXT End-of-string
249 * Quote = <Octet 127>
250 * End-of-string = <Octet 0>
252 * \todo Shouldn't we be sharing this with WSP (packet-wap.c)?
254 * \param tvb The buffer with PDU-data
255 * \param offset Offset within that buffer
256 * \param strval Pointer to variable into which to put pointer to
257 * buffer allocated to hold the text; must be freed
258 * when no longer used
260 * \return The length in bytes of the entire field
263 get_text_string(tvbuff_t *tvb, guint offset, char **strval)
267 DebugLog(("get_text_string(tvb = %p, offset = %u, **strval) - start\n",
269 len = tvb_strsize(tvb, offset);
270 DebugLog((" [1] tvb_strsize(tvb, offset) == %u\n", len));
271 if (tvb_get_guint8(tvb, offset) == MM_QUOTE)
272 *strval = (char *)tvb_memdup(tvb, offset + 1, len - 1);
274 *strval = (char *)tvb_memdup(tvb, offset, len);
275 DebugLog((" [3] Return(len) == %u\n", len));
280 * Decodes a Value-length from the protocol data.
281 * Value-length = Short-length | (Length-quote Length)
282 * Short-length = <Any octet 0-30>
283 * Length-quote = <Octet 31>
284 * Length = Uintvar-integer
286 * \todo Shouldn't we be sharing this with WSP (packet-wap.c)?
288 * \param tvb The buffer with PDU-data
289 * \param offset Offset within that buffer
290 * \param byte_count Returns the length in bytes of
291 * the "Value-length" field.
293 * \return The actual value of "Value-length"
296 get_value_length(tvbuff_t *tvb, guint offset, guint *byte_count)
300 field = tvb_get_guint8(tvb, offset++);
303 else { /* Must be 31 so, Uintvar follows */
304 field = tvb_get_guintvar(tvb, offset, byte_count);
311 * Decodes an Encoded-string-value from the protocol data
312 * Encoded-string-value = Text-string | Value-length Char-set Text-string
314 * \param tvb The buffer with PDU-data
315 * \param offset Offset within that buffer
316 * \param strval Pointer to variable into which to put pointer to
317 * buffer allocated to hold the text; must be freed
318 * when no longer used
320 * \return The length in bytes of the entire field
323 get_encoded_strval(tvbuff_t *tvb, guint offset, char **strval)
329 field = tvb_get_guint8(tvb, offset);
332 length = get_value_length(tvb, offset, &count);
333 /* \todo Something with "Char-set", skip for now */
334 *strval = (char *)tvb_get_string(tvb, offset + count + 1, length - 1);
335 return count + length;
337 return get_text_string(tvb, offset, strval);
341 * Decodes a Long-integer from the protocol data
342 * Long-integer = Short-length Multi-octet-integer
343 * Short-length = <Any octet 0-30>
344 * Multi-octet-integer = 1*30OCTET
346 * \todo Shouldn't we be sharing this with WSP (packet-wap.c)?
348 * \param tvb The buffer with PDU-data
349 * \param offset Offset within that buffer
350 * \param byte_count Returns the length in bytes of the field
352 * \return The value of the Long-integer
354 * \note A maximum of 4-byte integers will be handled.
357 get_long_integer(tvbuff_t *tvb, guint offset, guint *byte_count)
361 *byte_count = tvb_get_guint8(tvb, offset++);
362 switch (*byte_count) {
364 val = tvb_get_guint8(tvb, offset);
367 val = tvb_get_ntohs(tvb, offset);
370 val = tvb_get_ntoh24(tvb, offset);
373 val = tvb_get_ntohl(tvb, offset);
383 /* Code to actually dissect the packets */
385 dissect_mmse_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
389 DebugLog(("dissect_mmse_heur()\n"));
391 * Check if data makes sense for it to be dissected as MMSE: Message-type
392 * field must make sense and followed by either Transaction-Id
393 * or MMS-Version header
395 if (tvb_get_guint8(tvb, 0) != MM_MTYPE_HDR)
397 pdut = tvb_get_guint8(tvb, 1);
398 if (match_strval(pdut, vals_message_type) == NULL)
400 if ((tvb_get_guint8(tvb, 2) != MM_TID_HDR) &&
401 (tvb_get_guint8(tvb, 2) != MM_VERSION_HDR))
403 dissect_mmse_standalone(tvb, pinfo, tree);
408 dissect_mmse_standalone(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
413 DebugLog(("dissect_mmse_standalone() - START (Packet %u)\n",
416 pdut = tvb_get_guint8(tvb, 1);
417 message_type = match_strval(pdut, vals_message_type);
419 /* Make entries in Protocol column and Info column on summary display */
420 if (check_col(pinfo->cinfo, COL_PROTOCOL))
421 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MMSE");
423 if (check_col(pinfo->cinfo, COL_INFO)) {
424 col_clear(pinfo->cinfo, COL_INFO);
425 col_add_fstr(pinfo->cinfo, COL_INFO, "MMS %s", message_type);
428 dissect_mmse(tvb, pinfo, tree, pdut, message_type);
432 dissect_mmse_encapsulated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
437 DebugLog(("dissect_mmse_encapsulated() - START (Packet %u)\n",
440 pdut = tvb_get_guint8(tvb, 1);
441 message_type = match_strval(pdut, vals_message_type);
443 /* Make entries in Info column on summary display */
444 if (check_col(pinfo->cinfo, COL_INFO)) {
445 col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "(MMS %s)",
449 dissect_mmse(tvb, pinfo, tree, pdut, message_type);
453 dissect_mmse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 pdut,
462 /* Set up structures needed to add the protocol subtree and manage it */
463 proto_item *ti = NULL;
464 proto_tree *mmse_tree = NULL;
466 DebugLog(("dissect_mmse() - START (Packet %u)\n", pinfo->fd->num));
468 /* If tree == NULL then we are only interested in protocol dissection
469 * up to reassembly and handoff to subdissectors if applicable; the
470 * columns must be set appropriately too.
471 * If tree != NULL then we also want to display the protocol tree
474 * In the interest of speed, skip protocol tree item generation
478 DebugLog(("tree != NULL\n"));
480 ti = proto_tree_add_item(tree, proto_mmse, tvb, 0, -1, FALSE);
481 proto_item_append_text(ti, ", Type: %s", message_type);
482 /* create display subtree for the protocol */
483 mmse_tree = proto_item_add_subtree(ti, ett_mmse);
485 /* Report PDU-type */
486 proto_tree_add_uint(mmse_tree, hf_mmse_message_type, tvb, 0, 2, pdut);
489 offset = 2; /* Skip Message-Type */
492 * Cycle through MMS-headers
494 * NOTE - some PDUs may convey content which can be handed off
497 if (tree || pdu_has_content(pdut)) {
498 while ((offset < tvb_reported_length(tvb)) &&
499 (field = tvb_get_guint8(tvb, offset++)) != MM_CTYPE_HDR)
501 DebugLog(("\tField = 0x%02X (offset = %u): %s\n",
503 val_to_str(field, vals_mm_header_names,
504 "Unknown MMS header 0x%02X")));
507 case MM_TID_HDR: /* Text-string */
508 length = get_text_string(tvb, offset, &strval);
510 proto_tree_add_string(mmse_tree, hf_mmse_transaction_id,
511 tvb, offset - 1, length + 1,strval);
516 case MM_VERSION_HDR: /* nibble-Major/nibble-minor*/
517 field = tvb_get_guint8(tvb, offset++);
521 major = (field & 0x70) >> 4;
522 minor = field & 0x0F;
524 strval = g_strdup_printf("%u", major);
526 strval = g_strdup_printf("%u.%u", major, minor);
527 proto_tree_add_string(mmse_tree, hf_mmse_mms_version,
528 tvb, offset - 2, 2, strval);
532 case MM_BCC_HDR: /* Encoded-string-value */
533 length = get_encoded_strval(tvb, offset, &strval);
535 proto_tree_add_string(mmse_tree, hf_mmse_bcc, tvb,
536 offset - 1, length + 1, strval);
541 case MM_CC_HDR: /* Encoded-string-value */
542 length = get_encoded_strval(tvb, offset, &strval);
544 proto_tree_add_string(mmse_tree, hf_mmse_cc, tvb,
545 offset - 1, length + 1, strval);
550 case MM_CLOCATION_HDR: /* Uri-value */
551 length = get_text_string(tvb, offset, &strval);
553 proto_tree_add_string(mmse_tree,
554 hf_mmse_content_location,
555 tvb, offset - 1, length + 1,strval);
560 case MM_DATE_HDR: /* Long-integer */
565 tval = get_long_integer(tvb, offset, &count);
569 proto_tree_add_time(mmse_tree, hf_mmse_date, tvb,
570 offset - 1, count + 1, &tmptime);
575 case MM_DREPORT_HDR: /* Yes|No */
576 field = tvb_get_guint8(tvb, offset++);
578 proto_tree_add_uint(mmse_tree,
579 hf_mmse_delivery_report,
580 tvb, offset - 2, 2, field);
585 * Value-length(Absolute-token Date-value|
586 * Relative-token Delta-seconds-value)
588 length = get_value_length(tvb, offset, &count);
589 field = tvb_get_guint8(tvb, offset + count);
595 tval = get_long_integer(tvb, offset + count + 1, &cnt);
600 proto_tree_add_time(mmse_tree,
601 hf_mmse_delivery_time_abs,
603 length + count + 1, &tmptime);
605 proto_tree_add_time(mmse_tree,
606 hf_mmse_delivery_time_rel,
608 length + count + 1, &tmptime);
610 offset += length + count;
614 * Value-length(Absolute-token Date-value|
615 * Relative-token Delta-seconds-value)
617 length = get_value_length(tvb, offset, &count);
618 field = tvb_get_guint8(tvb, offset + count);
624 tval = get_long_integer(tvb, offset + count + 1, &cnt);
629 proto_tree_add_time(mmse_tree, hf_mmse_expiry_abs,
631 length + count + 1, &tmptime);
633 proto_tree_add_time(mmse_tree, hf_mmse_expiry_rel,
635 length + count + 1, &tmptime);
637 offset += length + count;
641 * Value-length(Address-present-token Encoded-string-value
642 * |Insert-address-token)
644 length = get_value_length(tvb, offset, &count);
646 field = tvb_get_guint8(tvb, offset + count);
648 proto_tree_add_string(mmse_tree, hf_mmse_from, tvb,
649 offset-1, length + count + 1,
652 (void) get_encoded_strval(tvb, offset + count + 1,
654 proto_tree_add_string(mmse_tree, hf_mmse_from, tvb,
655 offset-1, length + count + 1, strval);
659 offset += length + count;
663 * Class-identifier|Text-string
665 field = tvb_get_guint8(tvb, offset);
669 proto_tree_add_uint(mmse_tree,
670 hf_mmse_message_class_id,
671 tvb, offset - 2, 2, field);
674 length = get_text_string(tvb, offset, &strval);
676 proto_tree_add_string(mmse_tree,
677 hf_mmse_message_class_str,
678 tvb, offset - 1, length + 1,
685 case MM_MID_HDR: /* Text-string */
686 length = get_text_string(tvb, offset, &strval);
688 proto_tree_add_string(mmse_tree, hf_mmse_message_id,
689 tvb, offset - 1, length + 1, strval);
694 case MM_MSIZE_HDR: /* Long-integer */
695 length = get_long_integer(tvb, offset, &count);
697 proto_tree_add_uint(mmse_tree, hf_mmse_message_size,
698 tvb, offset - 1, count + 1, length);
702 case MM_PRIORITY_HDR: /* Low|Normal|High */
703 field = tvb_get_guint8(tvb, offset++);
705 proto_tree_add_uint(mmse_tree, hf_mmse_priority, tvb,
706 offset - 2, 2, field);
709 case MM_RREPLY_HDR: /* Yes|No */
710 field = tvb_get_guint8(tvb, offset++);
712 proto_tree_add_uint(mmse_tree, hf_mmse_read_reply, tvb,
713 offset - 2, 2, field);
716 case MM_RALLOWED_HDR: /* Yes|No */
717 field = tvb_get_guint8(tvb, offset++);
719 proto_tree_add_uint(mmse_tree, hf_mmse_report_allowed,
720 tvb, offset - 2, 2, field);
724 field = tvb_get_guint8(tvb, offset++);
726 proto_tree_add_uint(mmse_tree, hf_mmse_response_status,
727 tvb, offset - 2, 2, field);
730 case MM_RTEXT_HDR: /* Encoded-string-value */
731 length = get_encoded_strval(tvb, offset, &strval);
733 proto_tree_add_string(mmse_tree, hf_mmse_response_text,
734 tvb, offset - 1, length + 1, strval);
739 case MM_SVISIBILITY_HDR: /* Hide|Show */
740 field = tvb_get_guint8(tvb, offset++);
742 proto_tree_add_uint(mmse_tree,hf_mmse_sender_visibility,
743 tvb, offset - 2, 2, field);
747 field = tvb_get_guint8(tvb, offset++);
749 proto_tree_add_uint(mmse_tree, hf_mmse_status, tvb,
750 offset - 2, 2, field);
753 case MM_SUBJECT_HDR: /* Encoded-string-value */
754 length = get_encoded_strval(tvb, offset, &strval);
756 proto_tree_add_string(mmse_tree, hf_mmse_subject, tvb,
757 offset - 1, length + 1, strval);
762 case MM_TO_HDR: /* Encoded-string-value */
763 length = get_encoded_strval(tvb, offset, &strval);
765 proto_tree_add_string(mmse_tree, hf_mmse_to, tvb,
766 offset - 1, length + 1, strval);
774 proto_tree_add_text(mmse_tree, tvb, offset - 1, 1,
775 "Unknown field (0x%02x)", field);
782 length = get_text_string(tvb, offset, &strval);
783 CLEANUP_PUSH(g_free, strval);
784 length2= get_text_string(tvb, offset+length, &strval2);
787 proto_tree_add_string_format(mmse_tree,
788 hf_mmse_ffheader, tvb, offset,
790 (const char *) tvb_get_ptr(
791 tvb, offset, length + length2),
792 "%s: %s",strval,strval2);
795 offset += length + length2;
796 CLEANUP_CALL_AND_POP;
800 DebugLog(("\tEnd(case)\n"));
802 DebugLog(("\tEnd(switch)\n"));
803 if (field == MM_CTYPE_HDR) {
805 * Eeehh, we're now actually back to good old WSP content-type
806 * encoding. Let's steal that from the WSP-dissector.
810 const char *type_str;
812 DebugLog(("Content-Type: [from WSP dissector]\n"));
813 DebugLog(("Calling add_content_type() in WSP dissector\n"));
814 offset = add_content_type(mmse_tree, tvb, offset, &type, &type_str);
815 DebugLog(("Generating new TVB subset (offset = %u)\n", offset));
816 tmp_tvb = tvb_new_subset(tvb, offset, -1, -1);
817 DebugLog(("Add POST data\n"));
818 add_post_data(mmse_tree, tmp_tvb, type, type_str, pinfo);
819 DebugLog(("Done!\n"));
822 DebugLog(("tree == NULL and PDU has no potential content\n"));
825 /* If this protocol has a sub-dissector call it here, see section 1.8 */
826 DebugLog(("dissect_mmse() - END\n"));
830 /* Register the protocol with Ethereal */
832 /* this format is required because a script is used to build the C function
833 * that calls all the protocol registration.
836 proto_register_mmse(void)
838 /* Setup list of header fields See Section 1.6.1 for details */
839 static hf_register_info hf[] = {
840 { &hf_mmse_message_type,
841 { "Message-Type", "mmse.message_type",
842 FT_UINT8, BASE_HEX, VALS(vals_message_type), 0x00,
843 "Specifies the transaction type. Effectively defines PDU.",
847 { &hf_mmse_transaction_id,
848 { "Transaction-ID", "mmse.transaction_id",
849 FT_STRING, BASE_NONE, NULL, 0x00,
850 "A unique identifier for this transaction. "
851 "Identifies request and corresponding response only.",
855 { &hf_mmse_mms_version,
856 { "MMS-Version", "mmse.mms_version",
857 FT_STRING, BASE_NONE, NULL, 0x00,
858 "Version of the protocol used.",
864 FT_STRING, BASE_NONE, NULL, 0x00,
865 "Blind carbon copy.",
871 FT_STRING, BASE_NONE, NULL, 0x00,
876 { &hf_mmse_content_location,
877 { "Content-Location", "mmse.content_location",
878 FT_STRING, BASE_NONE, NULL, 0x00,
879 "Defines the location of the message.",
884 { "Date", "mmse.date",
885 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
886 "Arrival timestamp of the message or sending timestamp.",
890 { &hf_mmse_delivery_report,
891 { "Delivery-Report", "mmse.delivery_report",
892 FT_UINT8, BASE_HEX, VALS(vals_yes_no), 0x00,
893 "Whether a report of message delivery is wanted or not.",
897 { &hf_mmse_delivery_time_abs,
898 { "Delivery-Time", "mmse.delivery_time.abs",
899 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
900 "The time at which message delivery is desired.",
904 { &hf_mmse_delivery_time_rel,
905 { "Delivery-Time", "mmse.delivery_time.rel",
906 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
907 "The desired message delivery delay.",
911 { &hf_mmse_expiry_abs,
912 { "Expiry", "mmse.expiry.abs",
913 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
914 "Time when message expires and need not be delivered anymore.",
918 { &hf_mmse_expiry_rel,
919 { "Expiry", "mmse.expiry.rel",
920 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
921 "Delay before message expires and need not be delivered anymore.",
926 { "From", "mmse.from",
927 FT_STRING, BASE_NONE, NULL, 0x00,
928 "Address of the message sender.",
932 { &hf_mmse_message_class_id,
933 { "Message-Class", "mmse.message_class.id",
934 FT_UINT8, BASE_HEX, VALS(vals_message_class), 0x00,
935 "Of what category is the message.",
939 { &hf_mmse_message_class_str,
940 { "Message-Class", "mmse.message_class.str",
941 FT_STRING, BASE_NONE, NULL, 0x00,
942 "Of what category is the message.",
946 { &hf_mmse_message_id,
947 { "Message-Id", "mmse.message_id",
948 FT_STRING, BASE_NONE, NULL, 0x00,
949 "Unique identification of the message.",
953 { &hf_mmse_message_size,
954 { "Message-Size", "mmse.message_size",
955 FT_UINT32, BASE_DEC, NULL, 0x00,
956 "The size of the message in octets.",
961 { "Priority", "mmse.priority",
962 FT_UINT8, BASE_HEX, VALS(vals_priority), 0x00,
963 "Priority of the message.",
967 { &hf_mmse_read_reply,
968 { "Read-Reply", "mmse.read_reply",
969 FT_UINT8, BASE_HEX, VALS(vals_yes_no), 0x00,
970 "Whether a read report from every recipient is wanted.",
974 { &hf_mmse_report_allowed,
975 { "Report-Allowed", "mmse.report_allowed",
976 FT_UINT8, BASE_HEX, VALS(vals_yes_no), 0x00,
977 "Sending of delivery report allowed or not.",
981 { &hf_mmse_response_status,
982 { "Response-Status", "mmse.response_status",
983 FT_UINT8, BASE_HEX, VALS(vals_response_status), 0x00,
984 "MMS-specific result of a message submission or retrieval.",
988 { &hf_mmse_response_text,
989 { "Response-Text", "mmse.response_text",
990 FT_STRING, BASE_NONE, NULL, 0x00,
991 "Additional information on MMS-specific result.",
995 { &hf_mmse_sender_visibility,
996 { "Sender-Visibility", "mmse.sender_visibility",
997 FT_UINT8, BASE_HEX, VALS(vals_sender_visibility), 0x00,
998 "Disclose sender identity to receiver or not.",
1003 { "Status", "mmse.status",
1004 FT_UINT8, BASE_HEX, VALS(vals_message_status), 0x00,
1005 "Current status of the message.",
1010 { "Subject", "mmse.subject",
1011 FT_STRING, BASE_NONE, NULL, 0x00,
1012 "Subject of the message.",
1018 FT_STRING, BASE_NONE, NULL, 0x00,
1019 "Recipient(s) of the message.",
1023 { &hf_mmse_content_type,
1024 { "Data", "mmse.content_type",
1025 FT_NONE, BASE_NONE, NULL, 0x00,
1026 "Media content of the message.",
1030 { &hf_mmse_ffheader,
1031 { "Free format (not encoded) header", "mmse.ffheader",
1032 FT_STRING, BASE_NONE, NULL, 0x00,
1033 "Application header without corresponding encoding.",
1038 /* Setup protocol subtree array */
1039 static gint *ett[] = {
1043 /* Register the protocol name and description */
1044 proto_mmse = proto_register_protocol("MMS Message Encapsulation",
1047 /* Required function calls to register header fields and subtrees used */
1048 proto_register_field_array(proto_mmse, hf, array_length(hf));
1049 proto_register_subtree_array(ett, array_length(ett));
1052 /* If this dissector uses sub-dissector registration add registration routine.
1053 * This format is required because a script is used to find these routines and
1054 * create the code that calls these routines.
1057 proto_reg_handoff_mmse(void)
1059 dissector_handle_t mmse_standalone_handle;
1060 dissector_handle_t mmse_encapsulated_handle;
1062 heur_dissector_add("wsp", dissect_mmse_heur, proto_mmse);
1063 mmse_standalone_handle = create_dissector_handle(
1064 dissect_mmse_standalone, proto_mmse);
1065 mmse_encapsulated_handle = create_dissector_handle(
1066 dissect_mmse_encapsulated, proto_mmse);
1067 /* As the media types for WSP and HTTP are the same, the WSP dissector
1068 * uses the same string dissector table as the HTTP protocol. */
1069 dissector_add_string("media_type",
1070 "application/vnd.wap.mms-message", mmse_standalone_handle);
1071 dissector_add_string("multipart_media_type",
1072 "application/vnd.wap.mms-message", mmse_encapsulated_handle);