2 * Routines for MMS Message Encapsulation dissection
3 * Copyright 2001, Tom Uijldert <tom.uijldert@cmg.nl>
5 * $Id: packet-mmse.c,v 1.1 2001/09/25 21:32:41 guy 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.102-MMSEncapsulation" according
28 * the draft version of 8-February-2001.
39 #ifdef HAVE_SYS_TYPES_H
40 # include <sys/types.h>
43 #ifdef HAVE_NETINET_IN_H
44 # include <netinet/in.h>
49 #ifdef NEED_SNPRINTF_H
50 # include "snprintf.h"
54 #include "packet-wap.h"
55 /* #include "packet-mmse.h" */ /* We autoregister */
57 #define MM_QUOTE 0x7F /* Quoted string */
62 #define MM_BCC_HDR 0x81 /* Bcc */
63 #define MM_CC_HDR 0x82 /* Cc */
64 #define MM_CLOCATION_HDR 0x83 /* Content-Location */
65 #define MM_CTYPE_HDR 0x84 /* Content-Type */
66 #define MM_DATE_HDR 0x85 /* Date */
67 #define MM_DREPORT_HDR 0x86 /* Delivery-Report */
68 #define MM_DTIME_HDR 0x87 /* Delivery-Time */
69 #define MM_EXPIRY_HDR 0x88 /* Expiry */
70 #define MM_FROM_HDR 0x89 /* From */
71 #define MM_MCLASS_HDR 0x8A /* Message-Class */
72 #define MM_MID_HDR 0x8B /* Message-ID */
73 #define MM_MTYPE_HDR 0x8C /* Message-Type */
74 #define MM_VERSION_HDR 0x8D /* MMS-Version */
75 #define MM_MSIZE_HDR 0x8E /* Message-Size */
76 #define MM_PRIORITY_HDR 0x8F /* Priority */
77 #define MM_RREPLY_HDR 0x90 /* Read-Reply */
78 #define MM_RALLOWED_HDR 0x91 /* Report-Allowed */
79 #define MM_RSTATUS_HDR 0x92 /* Response-Status */
80 #define MM_RTEXT_HDR 0x93 /* Response-Text */
81 #define MM_SVISIBILITY_HDR 0x94 /* Sender-Visibility */
82 #define MM_STATUS_HDR 0x95 /* Status */
83 #define MM_SUBJECT_HDR 0x96 /* Subject */
84 #define MM_TO_HDR 0x97 /* To */
85 #define MM_TID_HDR 0x98 /* Transaction-Id */
88 * Initialize the protocol and registered fields
90 static int proto_mmse = -1;
92 static int hf_mmse_message_type = -1;
93 static int hf_mmse_transaction_id = -1;
94 static int hf_mmse_mms_version = -1;
95 static int hf_mmse_bcc = -1;
96 static int hf_mmse_cc = -1;
97 static int hf_mmse_content_location = -1;
98 static int hf_mmse_date = -1;
99 static int hf_mmse_delivery_report = -1;
100 static int hf_mmse_delivery_time_abs = -1;
101 static int hf_mmse_delivery_time_rel = -1;
102 static int hf_mmse_expiry_abs = -1;
103 static int hf_mmse_expiry_rel = -1;
104 static int hf_mmse_from = -1;
105 static int hf_mmse_message_class_id = -1;
106 static int hf_mmse_message_class_str = -1;
107 static int hf_mmse_message_id = -1;
108 static int hf_mmse_message_size = -1;
109 static int hf_mmse_priority = -1;
110 static int hf_mmse_read_reply = -1;
111 static int hf_mmse_report_allowed = -1;
112 static int hf_mmse_response_status = -1;
113 static int hf_mmse_response_text = -1;
114 static int hf_mmse_sender_visibility = -1;
115 static int hf_mmse_status = -1;
116 static int hf_mmse_subject = -1;
117 static int hf_mmse_to = -1;
118 static int hf_mmse_content_type = -1;
119 static int hf_mmse_ffheader = -1;
122 * Initialize the subtree pointers
124 static gint ett_mmse = -1;
127 * Valuestrings for header contents
129 static const value_string vals_message_type[] = {
130 { 0x80, "m-send-req" },
131 { 0x81, "m-send-conf" },
132 { 0x82, "m-notification-ind" },
133 { 0x83, "m-notifyresp-ind" },
134 { 0x84, "m-retrieve-conf" },
135 { 0x85, "m-acknowledge-ind" },
136 { 0x86, "m-delivery-ind" },
140 static const value_string vals_yes_no[] = {
146 static const value_string vals_message_class[] = {
147 { 0x80, "Personal" },
148 { 0x81, "Advertisement" },
149 { 0x82, "Informational" },
154 static const value_string vals_priority[] = {
161 static const value_string vals_response_status[] = {
163 { 0x81, "Unspecified" },
164 { 0x82, "Service denied" },
165 { 0x83, "Message format corrupt" },
166 { 0x84, "sending address unresolved" },
167 { 0x85, "message not found" },
168 { 0x86, "Network problem" },
169 { 0x87, "Content not accepted" },
170 { 0x88, "Unsupported message" },
174 static const value_string vals_sender_visibility[] = {
180 static const value_string vals_status[] = {
182 { 0x81, "Retrieved" },
183 { 0x82, "Rejected" },
184 { 0x82, "Deferred" },
185 { 0x82, "Unrecognized" },
190 * Decodes a Text-string from the protocol data
191 * Text-string = [Quote] *TEXT End-of-string
192 * Quote = <Octet 127>
193 * End-of-string = <Octet 0>
195 * \todo Shouldn't we be sharing this with WSP (packet-wap.c)?
197 * \param tvb The buffer with PDU-data
198 * \param offset Offset within that buffer
199 * \param strval String buffer to receive the text, reserve memory!
201 * \return The length in bytes of the entire field
204 get_text_string(tvbuff_t *tvb, guint offset, char *strval)
208 len = tvb_strsize(tvb, offset);
209 if (tvb_get_guint8(tvb, offset) == MM_QUOTE)
210 tvb_memcpy(tvb, strval, offset + 1, len - 1);
212 tvb_memcpy(tvb, strval, offset, len);
217 * Decodes a Value-length from the protocol data.
218 * Value-length = Short-length | (Length-quote Length)
219 * Short-length = <Any octet 0-30>
220 * Length-quote = <Octet 31>
221 * Length = Uintvar-integer
223 * \todo Shouldn't we be sharing this with WSP (packet-wap.c)?
225 * \param tvb The buffer with PDU-data
226 * \param offset Offset within that buffer
227 * \param byte_count Returns the length in bytes of
228 * the "Value-length" field.
230 * \return The actual value of "Value-length"
233 get_value_length(tvbuff_t *tvb, guint offset, guint *byte_count)
237 field = tvb_get_guint8(tvb, offset++);
240 else { /* Must be 31 so, Uintvar follows */
241 field = tvb_get_guintvar(tvb, offset, byte_count);
248 * Decodes an Encoded-string-value from the protocol data
249 * Encoded-string-value = Text-string | Value-length Char-set Text-string
251 * \param tvb The buffer with PDU-data
252 * \param offset Offset within that buffer
253 * \param strval String buffer to receive the text, reserve memory!
255 * \return The length in bytes of the entire field
258 get_encoded_strval(tvbuff_t *tvb, guint offset, char *strval)
264 field = tvb_get_guint8(tvb, offset);
267 length = get_value_length(tvb, offset, &count);
268 /* \todo Something with "Char-set", skip for now */
269 tvb_memcpy(tvb, strval, offset + count + 1, length - 1);
270 strval[length - 1] = '\0'; /* Just to make sure */
271 return offset + count + length;
273 return get_text_string(tvb, offset, strval);
277 * Decodes a Long-integer from the protocol data
278 * Long-integer = Short-length Multi-octet-integer
279 * Short-length = <Any octet 0-30>
280 * Multi-octet-integer = 1*30OCTET
282 * \todo Shouldn't we be sharing this with WSP (packet-wap.c)?
284 * \param tvb The buffer with PDU-data
285 * \param offset Offset within that buffer
286 * \param byte_count Returns the length in bytes of the field
288 * \return The value of the Long-integer
290 * \note A maximum of 4-byte integers will be handled.
293 get_long_integer(tvbuff_t *tvb, guint offset, guint *byte_count)
297 *byte_count = tvb_get_guint8(tvb, offset++);
298 switch (*byte_count) {
300 val = tvb_get_guint8(tvb, offset);
303 val = tvb_get_ntohs(tvb, offset);
306 val = tvb_get_ntoh24(tvb, offset);
309 val = tvb_get_ntohl(tvb, offset);
319 /* Code to actually dissect the packets */
321 dissect_mmse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
330 /* Set up structures needed to add the protocol subtree and manage it */
332 proto_tree *mmse_tree;
334 * Check if data makes sense for it to be dissected as MMSE: Message-type
335 * field must make sense and followed by Transaction-Id header
337 if (tvb_get_guint8(tvb, 0) != MM_MTYPE_HDR)
339 pdut = tvb_get_guint8(tvb, 1);
340 if (match_strval(pdut, vals_message_type) == NULL)
342 if (tvb_get_guint8(tvb, 2) != MM_TID_HDR)
345 /* Make entries in Protocol column and Info column on summary display */
346 if (check_col(pinfo->fd, COL_PROTOCOL))
347 col_set_str(pinfo->fd, COL_PROTOCOL, "mmse");
349 if (check_col(pinfo->fd, COL_INFO)) {
350 col_clear(pinfo->fd, COL_INFO);
351 col_add_fstr(pinfo->fd, COL_INFO, "MMS %s",
352 match_strval(pdut, vals_message_type));
355 /* In the interest of speed, if "tree" is NULL, don't do any work not
356 * necessary to generate protocol tree items.
359 offset = 2; /* Skip Message-Type */
361 /* create display subtree for the protocol */
362 ti = proto_tree_add_item(tree, proto_mmse, tvb, 0,
363 tvb_length(tvb), FALSE);
364 mmse_tree = proto_item_add_subtree(ti, ett_mmse);
366 /* Report PDU-type */
367 proto_tree_add_uint(mmse_tree, hf_mmse_message_type, tvb, 0, 2, pdut);
369 * Cycle through MMS-headers
371 while ((offset < tvb_length(tvb)) &&
372 (field = tvb_get_guint8(tvb, offset++)) != MM_CTYPE_HDR)
376 case MM_TID_HDR: /* Text-string */
377 length = get_text_string(tvb, offset, strval);
378 proto_tree_add_string(mmse_tree, hf_mmse_transaction_id,
379 tvb, offset - 1, length + 1,strval);
382 case MM_VERSION_HDR: /* nibble-Major/nibble-minor*/
383 field = tvb_get_guint8(tvb, offset++);
387 major = (field & 0x70) >> 4;
388 minor = field & 0x0F;
390 sprintf(strval, "%d", major);
392 sprintf(strval, "%d.%d", major, minor);
394 proto_tree_add_string(mmse_tree, hf_mmse_mms_version, tvb,
395 offset - 2, 2, strval);
397 case MM_BCC_HDR: /* Encoded-string-value */
398 length = get_encoded_strval(tvb, offset, strval);
399 proto_tree_add_string(mmse_tree, hf_mmse_bcc, tvb,
400 offset - 1, length + 1, strval);
403 case MM_CC_HDR: /* Encoded-string-value */
404 length = get_encoded_strval(tvb, offset, strval);
405 proto_tree_add_string(mmse_tree, hf_mmse_cc, tvb,
406 offset - 1, length + 1, strval);
409 case MM_CLOCATION_HDR: /* Uri-value */
410 length = get_text_string(tvb, offset, strval);
411 proto_tree_add_string(mmse_tree, hf_mmse_content_location,
412 tvb, offset - 1, length + 1,strval);
415 case MM_DATE_HDR: /* Long-integer */
420 tval = get_long_integer(tvb, offset, &count);
423 proto_tree_add_time(mmse_tree, hf_mmse_date, tvb,
424 offset - 1, count + 1, &tmptime);
428 case MM_DREPORT_HDR: /* Yes|No */
429 field = tvb_get_guint8(tvb, offset++);
430 proto_tree_add_uint(mmse_tree, hf_mmse_delivery_report, tvb,
431 offset - 2, 2, field);
435 * Value-length(Absolute-token Date-value|
436 * Relative-token Delta-seconds-value)
438 length = get_value_length(tvb, offset, &count);
439 field = tvb_get_guint8(tvb, offset + count);
445 tval = get_long_integer(tvb, offset + count, &cnt);
449 proto_tree_add_time(mmse_tree,
450 hf_mmse_delivery_time_abs,
452 length + count + 1, &tmptime);
454 proto_tree_add_time(mmse_tree,
455 hf_mmse_delivery_time_rel,
457 length + count + 1, &tmptime);
459 offset += length + count;
463 * Value-length(Absolute-token Date-value|
464 * Relative-token Delta-seconds-value)
466 length = get_value_length(tvb, offset, &count);
467 field = tvb_get_guint8(tvb, offset + count);
473 tval = get_long_integer(tvb, offset + count, &cnt);
477 proto_tree_add_time(mmse_tree, hf_mmse_expiry_abs,
479 length + count + 1, &tmptime);
481 proto_tree_add_time(mmse_tree, hf_mmse_expiry_rel,
483 length + count + 1, &tmptime);
485 offset += length + count;
489 * Value-length(Address-present-token Encoded-string-value
490 * |Insert-address-token)
492 length = get_value_length(tvb, offset, &count);
493 field = tvb_get_guint8(tvb, offset + count);
495 strcpy(strval, "<insert address>");
497 (void) get_encoded_strval(tvb, offset + count + 1,
500 proto_tree_add_string(mmse_tree, hf_mmse_from, tvb,
501 offset-1, length + 2, strval);
502 offset += length + 1;
506 * Class-identifier|Text-string
508 field = tvb_get_guint8(tvb, offset);
511 proto_tree_add_uint(mmse_tree,
512 hf_mmse_message_class_id,
513 tvb, offset - 2, 2, field);
515 length = get_text_string(tvb, offset, strval);
516 proto_tree_add_string(mmse_tree,
517 hf_mmse_message_class_str,
518 tvb, offset - 1, length + 1,
523 case MM_MID_HDR: /* Text-string */
524 length = get_text_string(tvb, offset, strval);
525 proto_tree_add_string(mmse_tree, hf_mmse_message_id, tvb,
526 offset - 1, length + 1, strval);
529 case MM_MSIZE_HDR: /* Long-integer */
530 length = get_long_integer(tvb, offset, &count);
531 proto_tree_add_uint(mmse_tree, hf_mmse_message_size, tvb,
532 offset - 1, count + 1, length);
535 case MM_PRIORITY_HDR: /* Low|Normal|High */
536 field = tvb_get_guint8(tvb, offset++);
537 proto_tree_add_uint(mmse_tree, hf_mmse_priority, tvb,
538 offset - 2, 2, field);
540 case MM_RREPLY_HDR: /* Yes|No */
541 field = tvb_get_guint8(tvb, offset++);
542 proto_tree_add_uint(mmse_tree, hf_mmse_read_reply, tvb,
543 offset - 2, 2, field);
545 case MM_RALLOWED_HDR: /* Yes|No */
546 field = tvb_get_guint8(tvb, offset++);
547 proto_tree_add_uint(mmse_tree, hf_mmse_report_allowed, tvb,
548 offset - 2, 2, field);
551 field = tvb_get_guint8(tvb, offset++);
552 proto_tree_add_uint(mmse_tree, hf_mmse_response_status, tvb,
553 offset - 2, 2, field);
555 case MM_RTEXT_HDR: /* Encoded-string-value */
556 length = get_encoded_strval(tvb, offset, strval);
557 proto_tree_add_string(mmse_tree, hf_mmse_response_text, tvb,
558 offset - 1, length + 1, strval);
561 case MM_SVISIBILITY_HDR: /* Hide|Show */
562 field = tvb_get_guint8(tvb, offset++);
563 proto_tree_add_uint(mmse_tree,hf_mmse_sender_visibility,
564 tvb, offset - 2, 2, field);
567 field = tvb_get_guint8(tvb, offset++);
568 proto_tree_add_uint(mmse_tree, hf_mmse_status, tvb,
569 offset - 2, 2, field);
571 case MM_SUBJECT_HDR: /* Encoded-string-value */
572 length = get_encoded_strval(tvb, offset, strval);
573 proto_tree_add_string(mmse_tree, hf_mmse_subject, tvb,
574 offset - 1, length + 1, strval);
577 case MM_TO_HDR: /* Encoded-string-value */
578 length = get_encoded_strval(tvb, offset, strval);
579 proto_tree_add_string(mmse_tree, hf_mmse_to, tvb,
580 offset - 1, length + 1, strval);
586 "MMSE - Unknown field encountered (0x%02x)\n",
590 char strval2[BUFSIZ];
593 length = get_text_string(tvb, offset, strval);
594 length2= get_text_string(tvb, offset+length, strval2);
596 proto_tree_add_string_format(mmse_tree,
599 length + length2, NULL,
600 "%s : %s",strval,strval2);
601 offset += length + length2;
606 if (field == MM_CTYPE_HDR) {
609 * Eeehh, we're now actually back to good old WSP content-type
610 * encoding for multipart/related and multipart/mixed MIME-types.
611 * I'm not gonna do that work here again so maybe it's wise to
612 * share some more code with packet-wsp.c in the near future?
613 * Leave it as "Data" for now as it is the end of the PDU...
615 proto_tree_add_item(mmse_tree, hf_mmse_content_type, tvb,
617 tvb_length_remaining(tvb, offset - 1), FALSE);
623 /* If this protocol has a sub-dissector call it here, see section 1.8 */
627 /* Register the protocol with Ethereal */
629 /* this format is required because a script is used to build the C function
630 * that calls all the protocol registration.
633 proto_register_mmse(void)
635 /* Setup list of header fields See Section 1.6.1 for details */
636 static hf_register_info hf[] = {
637 { &hf_mmse_message_type,
638 { "Message-Type", "mmse.message_length",
639 FT_UINT8, BASE_HEX, VALS(vals_message_type), 0x00,
640 "Specifies the transaction type. Effectively defines PDU.",
644 { &hf_mmse_transaction_id,
645 { "Transaction-ID", "mmse.transaction_id",
646 FT_STRING, BASE_NONE, NULL, 0x00,
647 "A unique identifier for this transaction. "
648 "Identifies request and corresponding response only.",
652 { &hf_mmse_mms_version,
653 { "MMS-Version", "mmse.mms_version",
654 FT_STRING, BASE_NONE, NULL, 0x00,
655 "Version of the protocol used.",
661 FT_STRING, BASE_NONE, NULL, 0x00,
662 "Blind carbon copy.",
668 FT_STRING, BASE_NONE, NULL, 0x00,
673 { &hf_mmse_content_location,
674 { "Content-Location", "mmse.content_location",
675 FT_STRING, BASE_NONE, NULL, 0x00,
676 "Defines the location of the message.",
681 { "Date", "mmse.date",
682 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
683 "Arrival timestamp of the message or sending timestamp.",
687 { &hf_mmse_delivery_report,
688 { "Delivery-Report", "mmse.delivery_report",
689 FT_UINT8, BASE_HEX, VALS(vals_yes_no), 0x00,
690 "Whether a report of message delivery is wanted or not.",
694 { &hf_mmse_delivery_time_abs,
695 { "Delivery-Time", "mmse.delivery_time.abs",
696 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
697 "The time at which message delivery is desired.",
701 { &hf_mmse_delivery_time_rel,
702 { "Delivery-Time", "mmse.delivery_time.rel",
703 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
704 "The desired message delivery delay.",
708 { &hf_mmse_expiry_abs,
709 { "Expiry", "mmse.expiry.abs",
710 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x00,
711 "Time when message expires and need not be delivered anymore.",
715 { &hf_mmse_expiry_rel,
716 { "Expiry", "mmse.expiry.rel",
717 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
718 "Delay before message expires and need not be delivered anymore.",
723 { "From", "mmse.from",
724 FT_STRING, BASE_NONE, NULL, 0x00,
725 "Address of the message sender.",
729 { &hf_mmse_message_class_id,
730 { "Message-Class", "mmse.message_class.id",
731 FT_UINT8, BASE_HEX, VALS(vals_message_class), 0x00,
732 "Of what category is the message.",
736 { &hf_mmse_message_class_str,
737 { "Message-Class", "mmse.message_class.str",
738 FT_STRING, BASE_NONE, NULL, 0x00,
739 "Of what category is the message.",
743 { &hf_mmse_message_id,
744 { "Message-Id", "mmse.message_id",
745 FT_STRING, BASE_NONE, NULL, 0x00,
746 "Unique identification of the message.",
750 { &hf_mmse_message_size,
751 { "Message-Size", "mmse.message_size",
752 FT_UINT32, BASE_DEC, NULL, 0x00,
753 "The size of the message in octets.",
758 { "Priority", "mmse.priority",
759 FT_UINT8, BASE_HEX, VALS(vals_priority), 0x00,
760 "Priority of the message.",
764 { &hf_mmse_read_reply,
765 { "Read-Reply", "mmse.read_reply",
766 FT_UINT8, BASE_HEX, VALS(vals_yes_no), 0x00,
767 "Whether a read report from every recipient is wanted.",
771 { &hf_mmse_report_allowed,
772 { "Report-Allowed", "mmse.report_allowed",
773 FT_UINT8, BASE_HEX, VALS(vals_yes_no), 0x00,
774 "Sending of delivery report allowed or not.",
778 { &hf_mmse_response_status,
779 { "Response-Status", "mmse.response_status",
780 FT_UINT8, BASE_HEX, VALS(vals_response_status), 0x00,
781 "MMS-specific result of a message submission or retrieval.",
785 { &hf_mmse_response_text,
786 { "Response-Text", "mmse.response_text",
787 FT_STRING, BASE_NONE, NULL, 0x00,
788 "Additional information on MMS-specific result.",
792 { &hf_mmse_sender_visibility,
793 { "Sender-Visibility", "mmse.sender_visibility",
794 FT_UINT8, BASE_HEX, VALS(vals_yes_no), 0x00,
795 "Disclose sender identity to receiver or not.",
800 { "Status", "mmse.status",
801 FT_UINT8, BASE_HEX, VALS(vals_status), 0x00,
802 "Current status of the message.",
807 { "Subject", "mmse.subject",
808 FT_STRING, BASE_NONE, NULL, 0x00,
809 "Subject of the message.",
815 FT_STRING, BASE_NONE, NULL, 0x00,
816 "Recipient(s) of the message.",
820 { &hf_mmse_content_type,
821 { "Data", "mmse.content_type",
822 FT_NONE, BASE_NONE, NULL, 0x00,
823 "Media content of the message.",
828 { "Free format (not encoded) header", "mmse.ffheader",
829 FT_STRING, BASE_NONE, NULL, 0x00,
830 "Application header without corresponding encoding.",
835 /* Setup protocol subtree array */
836 static gint *ett[] = {
840 /* Register the protocol name and description */
841 proto_mmse = proto_register_protocol("MMS Message Encapsulation",
844 /* Required function calls to register header fields and subtrees used */
845 proto_register_field_array(proto_mmse, hf, array_length(hf));
846 proto_register_subtree_array(ett, array_length(ett));
849 /* If this dissector uses sub-dissector registration add registration routine.
850 * This format is required because a script is used to find these routines and
851 * create the code that calls these routines.
854 proto_reg_handoff_mmse(void)
856 heur_dissector_add("wsp", dissect_mmse, proto_mmse);
859 * Mmmmm, actually, it should register itself on the "wsp.content_type"
860 * protocol field. Especially when IANA finally registers the type
861 * 'application/wap.vnd.mms-message'. The wsp-dissector should then
862 * ofcourse be modified to cater for such subdissectors...
866 * The bearer could also be http (through the same content-type field).
867 * Same modifications would apply there.