2 * Routines for MMS Message Encapsulation dissection
3 * Copyright 2001, Tom Uijldert <tom.uijldert@cmg.nl>
4 * Copyright 2004, Olivier Biot
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * Dissector of an encoded Multimedia message PDU, as defined by the WAPForum
28 * (http://www.wapforum.org) in "WAP-209-MMSEncapsulation-20020105-a".
29 * Subsequent releases of MMS are in control of the Open Mobile Alliance (OMA):
30 * Dissection of MMS 1.1 as in OMA-MMS-ENC-v1.1.
31 * Dissection of MMS 1.2 as in OMA-MMS-ENC-v1.2 (not finished yet).
34 /* This file has been edited with 8-space tabs and 4-space indentation */
42 #include <epan/packet.h>
43 #include <epan/to_str.h>
44 #include <epan/strutil.h>
45 #include <epan/wmem/wmem.h>
46 #include "packet-wap.h"
47 #include "packet-wsp.h"
48 /* #include "packet-mmse.h" */ /* We autoregister */
50 #define MM_QUOTE 0x7F /* Quoted string */
52 #define MMS_CONTENT_TYPE 0x3E /* WINA-value for mms-message */
54 /* General-purpose debug logger.
55 * Requires double parentheses because of variable arguments of printf().
57 * Enable debug logging for MMSE by defining AM_CFLAGS
58 * so that it contains "-DDEBUG_mmse"
62 g_print("%s:%u: ", __FILE__, __LINE__); \
69 * Forward declarations
71 static void dissect_mmse_standalone(tvbuff_t
*, packet_info
*, proto_tree
*);
72 static void dissect_mmse(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
73 guint8 pdut
, const char *message_type
);
79 #define MM_BCC_HDR 0x81 /* Bcc */
80 #define MM_CC_HDR 0x82 /* Cc */
81 #define MM_CLOCATION_HDR 0x83 /* X-Mms-Content-Location */
82 #define MM_CTYPE_HDR 0x84 /* Content-Type */
83 #define MM_DATE_HDR 0x85 /* Date */
84 #define MM_DREPORT_HDR 0x86 /* X-Mms-Delivery-Report */
85 #define MM_DTIME_HDR 0x87 /* X-Mms-Delivery-Time */
86 #define MM_EXPIRY_HDR 0x88 /* X-Mms-Expiry */
87 #define MM_FROM_HDR 0x89 /* From */
88 #define MM_MCLASS_HDR 0x8A /* X-Mms-Message-Class */
89 #define MM_MID_HDR 0x8B /* Message-ID */
90 #define MM_MTYPE_HDR 0x8C /* X-Mms-Message-Type */
91 #define MM_VERSION_HDR 0x8D /* X-Mms-MMS-Version */
92 #define MM_MSIZE_HDR 0x8E /* X-Mms-Message-Size */
93 #define MM_PRIORITY_HDR 0x8F /* X-Mms-Priority */
94 #define MM_RREPLY_HDR 0x90 /* X-Mms-Read-Reply */
95 #define MM_RALLOWED_HDR 0x91 /* X-Mms-Report-Allowed */
96 #define MM_RSTATUS_HDR 0x92 /* X-Mms-Response-Status */
97 #define MM_RTEXT_HDR 0x93 /* X-Mms-Response-Text */
98 #define MM_SVISIBILITY_HDR 0x94 /* X-Mms-Sender-Visibility */
99 #define MM_STATUS_HDR 0x95 /* X-Mms-Status */
100 #define MM_SUBJECT_HDR 0x96 /* Subject */
101 #define MM_TO_HDR 0x97 /* To */
102 #define MM_TID_HDR 0x98 /* X-Mms-Transaction-Id */
104 #define MM_RETRIEVE_STATUS_HDR 0x99 /* X-Mms-Retrieve-Status */
105 #define MM_RETRIEVE_TEXT_HDR 0x9A /* X-Mms-Retrieve-Text */
106 #define MM_READ_STATUS_HDR 0x9B /* X-Mms-Read-Status */
107 #define MM_REPLY_CHARGING_HDR 0x9C /* X-Mms-Reply-Charging */
108 #define MM_REPLY_CHARGING_DEADLINE_HDR \
109 0x9D /* X-Mms-Reply-Charging-Deadline*/
110 #define MM_REPLY_CHARGING_ID_HDR \
111 0x9E /* X-Mms-Reply-Charging-ID */
112 #define MM_REPLY_CHARGING_SIZE_HDR \
113 0x9F /* X-Mms-Reply-Charging-Size */
114 #define MM_PREV_SENT_BY_HDR 0xA0 /* X-Mms-Previously-Sent-By */
115 #define MM_PREV_SENT_DATE_HDR 0xA1 /* X-Mms-Previously-Sent-Date */
117 #define MM_STORE_HDR 0xA2 /* X-Mms-Store */
118 #define MM_MM_STATE_HDR 0xA3 /* X-Mms-MM-State */
119 #define MM_MM_FLAGS_HDR 0xA4 /* X-Mms-MM-Flags */
120 #define MM_STORE_STATUS_HDR 0xA5 /* X-Mms-Store-Status */
121 #define MM_STORE_STATUS_TEXT_HDR \
122 0xA6 /* X-Mms-Store-Status-Text */
123 #define MM_STORED_HDR 0xA7 /* X-Mms-Stored */
124 #define MM_ATTRIBUTES_HDR 0xA8 /* X-Mms-Attributes */
125 #define MM_TOTALS_HDR 0xA9 /* X-Mms-Totals */
126 #define MM_MBOX_TOTALS_HDR 0xAA /* X-Mms-Mbox-Totals */
127 #define MM_QUOTAS_HDR 0xAB /* X-Mms-Quotas */
128 #define MM_MBOX_QUOTAS_HDR 0xAC /* X-Mms-Mbox-Quotas */
129 #define MM_MBOX_MSG_COUNT_HDR 0xAD /* X-Mms-Message-Count */
130 #define MM_CONTENT_HDR 0xAE /* Content */
131 #define MM_START_HDR 0xAF /* X-Mms-Start */
132 #define MM_ADDITIONAL_HDR 0xB0 /* Additional-headers */
133 #define MM_DISTRIBUION_IND_HDR 0xB1 /* X-Mms-Distribution-Indcator */
134 #define MM_ELEMENT_DESCR_HDR 0xB2 /* X-Mms-Element-Descriptor */
135 #define MM_LIMIT_HDR 0xB3 /* X-Mms-Limit */
137 static const value_string vals_mm_header_names
[] = {
139 { MM_BCC_HDR
, "Bcc" },
141 { MM_CLOCATION_HDR
, "X-Mms-Content-Location" },
142 { MM_CTYPE_HDR
, "X-Mms-Content-Type" },
143 { MM_DATE_HDR
, "Date" },
144 { MM_DREPORT_HDR
, "X-Mms-Delivery-Report" },
145 { MM_DTIME_HDR
, "X-Mms-Delivery-Time" },
146 { MM_EXPIRY_HDR
, "X-Mms-Expiry" },
147 { MM_FROM_HDR
, "From" },
148 { MM_MCLASS_HDR
, "X-Mms-Message-Class" },
149 { MM_MID_HDR
, "Message-ID" },
150 { MM_MTYPE_HDR
, "X-Mms-Message-Type" },
151 { MM_VERSION_HDR
, "X-Mms-MMS-Version" },
152 { MM_MSIZE_HDR
, "X-Mms-Message-Size" },
153 { MM_PRIORITY_HDR
, "X-Mms-Priority" },
154 { MM_RREPLY_HDR
, "X-Mms-Read-Reply" },
155 { MM_RALLOWED_HDR
, "X-Mms-Report-Allowed" },
156 { MM_RSTATUS_HDR
, "X-Mms-Response-Status" },
157 { MM_RTEXT_HDR
, "X-Mms-Response-Text" },
158 { MM_SVISIBILITY_HDR
, "X-Mms-Sender-Visibility" },
159 { MM_STATUS_HDR
, "X-Mms-Status" },
160 { MM_SUBJECT_HDR
, "Subject" },
162 { MM_TID_HDR
, "X-Mms-Transaction-Id" },
164 { MM_RETRIEVE_STATUS_HDR
, "X-Mms-Retrieve-Status" },
165 { MM_RETRIEVE_TEXT_HDR
, "X-Mms-Retrieve-Text" },
166 { MM_READ_STATUS_HDR
, "X-Mms-Read-Status" },
167 { MM_REPLY_CHARGING_HDR
, "X-Mms-Reply-Charging" },
168 { MM_REPLY_CHARGING_DEADLINE_HDR
,
169 "X-Mms-Reply-Charging-Deadline" },
170 { MM_REPLY_CHARGING_ID_HDR
, "X-Mms-Reply-Charging-ID" },
171 { MM_REPLY_CHARGING_SIZE_HDR
, "X-Mms-Reply-Charging-Size" },
172 { MM_PREV_SENT_BY_HDR
, "X-Mms-Previously-Sent-By" },
173 { MM_PREV_SENT_DATE_HDR
, "X-Mms-Previously-Sent-Date" },
175 { MM_STORE_HDR
, "X-Mms-Store" },
176 { MM_MM_STATE_HDR
, "X-Mms-MM-State" },
177 { MM_MM_FLAGS_HDR
, "X-Mms-MM-Flags" },
178 { MM_STORE_STATUS_HDR
, "X-Mms-Store-Status" },
179 { MM_STORE_STATUS_TEXT_HDR
, "X-Mms-Store-Status-Text" },
180 { MM_STORED_HDR
, "X-Mms-Stored" },
181 { MM_ATTRIBUTES_HDR
, "X-Mms-Attributes" },
182 { MM_TOTALS_HDR
, "X-Mms-Totals" },
183 { MM_MBOX_TOTALS_HDR
, "X-Mms-Mbox-Totals" },
184 { MM_QUOTAS_HDR
, "X-Mms-Quotas" },
185 { MM_MBOX_QUOTAS_HDR
, "X-Mms-Mbox-Quotas" },
186 { MM_MBOX_MSG_COUNT_HDR
, "X-Mms-Message-Count" },
187 { MM_CONTENT_HDR
, "Content" },
188 { MM_START_HDR
, "X-Mms-Start" },
189 { MM_ADDITIONAL_HDR
, "Additional-headers" },
190 { MM_DISTRIBUION_IND_HDR
, "X-Mms-Distribution-Indcator" },
191 { MM_ELEMENT_DESCR_HDR
, "X-Mms-Element-Descriptor" },
192 { MM_LIMIT_HDR
, "X-Mms-Limit" },
197 * Initialize the protocol and registered fields
199 static int proto_mmse
= -1;
201 static int hf_mmse_message_type
= -1;
202 static int hf_mmse_transaction_id
= -1;
203 static int hf_mmse_mms_version
= -1;
204 static int hf_mmse_bcc
= -1;
205 static int hf_mmse_cc
= -1;
206 static int hf_mmse_content_location
= -1;
207 static int hf_mmse_date
= -1;
208 static int hf_mmse_delivery_report
= -1;
209 static int hf_mmse_delivery_time_abs
= -1;
210 static int hf_mmse_delivery_time_rel
= -1;
211 static int hf_mmse_expiry_abs
= -1;
212 static int hf_mmse_expiry_rel
= -1;
213 static int hf_mmse_from
= -1;
214 static int hf_mmse_message_class_id
= -1;
215 static int hf_mmse_message_class_str
= -1;
216 static int hf_mmse_message_id
= -1;
217 static int hf_mmse_message_size
= -1;
218 static int hf_mmse_priority
= -1;
219 static int hf_mmse_read_reply
= -1;
220 static int hf_mmse_report_allowed
= -1;
221 static int hf_mmse_response_status
= -1;
222 static int hf_mmse_response_text
= -1;
223 static int hf_mmse_sender_visibility
= -1;
224 static int hf_mmse_status
= -1;
225 static int hf_mmse_subject
= -1;
226 static int hf_mmse_to
= -1;
227 /* static int hf_mmse_content_type = -1; */
228 static int hf_mmse_ffheader
= -1;
230 static int hf_mmse_read_report
= -1;
231 static int hf_mmse_retrieve_status
= -1;
232 static int hf_mmse_retrieve_text
= -1;
233 static int hf_mmse_read_status
= -1;
234 static int hf_mmse_reply_charging
= -1;
235 static int hf_mmse_reply_charging_deadline_abs
= -1;
236 static int hf_mmse_reply_charging_deadline_rel
= -1;
237 static int hf_mmse_reply_charging_id
= -1;
238 static int hf_mmse_reply_charging_size
= -1;
239 static int hf_mmse_prev_sent_by
= -1;
240 static int hf_mmse_prev_sent_by_fwd_count
= -1;
241 static int hf_mmse_prev_sent_by_address
= -1;
242 static int hf_mmse_prev_sent_date
= -1;
243 static int hf_mmse_prev_sent_date_fwd_count
= -1;
244 static int hf_mmse_prev_sent_date_date
= -1;
247 * Initialize the subtree pointers
249 static gint ett_mmse
= -1;
250 static gint ett_mmse_hdr_details
= -1;
253 * Valuestrings for PDU types
256 #define PDU_M_SEND_REQ 0x80
257 #define PDU_M_SEND_CONF 0x81
258 #define PDU_M_NOTIFICATION_IND 0x82
259 #define PDU_M_NOTIFYRESP_IND 0x83
260 #define PDU_M_RETRIEVE_CONF 0x84
261 #define PDU_M_ACKNOWLEDGE_IND 0x85
262 #define PDU_M_DELIVERY_IND 0x86
264 #define PDU_M_READ_REC_IND 0x87
265 #define PDU_M_READ_ORIG_IND 0x88
266 #define PDU_M_FORWARD_REQ 0x89
267 #define PDU_M_FORWARD_CONF 0x8A
269 #define PDU_M_MBOX_STORE_REQ 0x8B
270 #define PDU_M_MBOX_STORE_CONF 0x8C
271 #define PDU_M_MBOX_VIEW_REQ 0x8D
272 #define PDU_M_MBOX_VIEW_CONF 0x8E
273 #define PDU_M_MBOX_UPLOAD_REQ 0x8F
274 #define PDU_M_MBOX_UPLOAD_CONF 0x90
275 #define PDU_M_MBOX_DELETE_REQ 0x91
276 #define PDU_M_MBOX_DELETE_CONF 0x92
277 #define PDU_M_MBOX_DESCR 0x93
279 #define pdu_has_content(pdut) \
280 ( ((pdut) == PDU_M_SEND_REQ) \
281 || ((pdut) == PDU_M_DELIVERY_IND) \
282 || ((pdut) == PDU_M_RETRIEVE_CONF) \
283 || ((pdut) == PDU_M_MBOX_VIEW_CONF) \
284 || ((pdut) == PDU_M_MBOX_DESCR) \
285 || ((pdut) == PDU_M_MBOX_UPLOAD_REQ) \
288 static const value_string vals_message_type
[] = {
290 { PDU_M_SEND_REQ
, "m-send-req" },
291 { PDU_M_SEND_CONF
, "m-send-conf" },
292 { PDU_M_NOTIFICATION_IND
, "m-notification-ind" },
293 { PDU_M_NOTIFYRESP_IND
, "m-notifyresp-ind" },
294 { PDU_M_RETRIEVE_CONF
, "m-retrieve-conf" },
295 { PDU_M_ACKNOWLEDGE_IND
, "m-acknowledge-ind" },
296 { PDU_M_DELIVERY_IND
, "m-delivery-ind" },
298 { PDU_M_READ_REC_IND
, "m-read-rec-ind" },
299 { PDU_M_READ_ORIG_IND
, "m-read-orig-ind" },
300 { PDU_M_FORWARD_REQ
, "m-forward-req" },
301 { PDU_M_FORWARD_CONF
, "m-forward-conf" },
303 { PDU_M_MBOX_STORE_REQ
, "m-mbox-store-req" },
304 { PDU_M_MBOX_STORE_CONF
, "m-mbox-store-conf" },
305 { PDU_M_MBOX_VIEW_REQ
, "m-mbox-view-req" },
306 { PDU_M_MBOX_VIEW_CONF
, "m-mbox-view-conf" },
307 { PDU_M_MBOX_UPLOAD_REQ
, "m-mbox-upload-req" },
308 { PDU_M_MBOX_UPLOAD_CONF
, "m-mbox-upload-conf" },
309 { PDU_M_MBOX_DELETE_REQ
, "m-mbox-delete-req" },
310 { PDU_M_MBOX_DELETE_CONF
, "m-mbox-delete-conf" },
311 { PDU_M_MBOX_DESCR
, "m-mbox-descr" },
315 static const value_string vals_yes_no
[] = {
321 static const value_string vals_message_class
[] = {
322 { 0x80, "Personal" },
323 { 0x81, "Advertisement" },
324 { 0x82, "Informational" },
329 static const value_string vals_priority
[] = {
336 static const value_string vals_response_status
[] = {
337 /* MMS 1.0 - obsolete as from MMS 1.1 */
339 { 0x81, "Unspecified" },
340 { 0x82, "Service denied" },
341 { 0x83, "Message format corrupt" },
342 { 0x84, "Sending address unresolved" },
343 { 0x85, "Message not found" },
344 { 0x86, "Network problem" },
345 { 0x87, "Content not accepted" },
346 { 0x88, "Unsupported message" },
352 { 0xC0, "Transient failure" },
353 { 0xC1, "Transient: Sending address unresolved" },
354 { 0xC2, "Transient: Message not found" },
355 { 0xC3, "Transient: Network problem" },
357 { 0xC4, "Transient: Partial success" },
363 { 0xE0, "Permanent failure" },
364 { 0xE1, "Permanent: Service denied" },
365 { 0xE2, "Permanent: Message format corrupt" },
366 { 0xE3, "Permanent: Sending address unresolved" },
367 { 0xE4, "Permanent: Message not found" },
368 { 0xE5, "Permanent: Content not accepted" },
369 { 0xE6, "Permanent: Reply charging limitations not met" },
370 { 0xE7, "Permanent: Reply charging request not accepted" },
371 { 0xE8, "Permanent: Reply charging forwarding denied" },
372 { 0xE9, "Permanent: Reply charging not supported" },
374 { 0xEA, "Permanent: Address hiding not supported" },
379 static const value_string vals_sender_visibility
[] = {
385 static const value_string vals_message_status
[] = {
388 { 0x81, "Retrieved" },
389 { 0x82, "Rejected" },
390 { 0x83, "Deferred" },
391 { 0x84, "Unrecognized" },
393 { 0x85, "Indeterminate" },
394 { 0x86, "Forwarded" },
396 { 0x87, "Unreachable" },
401 static const value_string vals_retrieve_status
[] = {
406 { 0xC0, "Transient failure" },
407 { 0xC1, "Transient: Message not found" },
408 { 0xC2, "Transient: Network problem" },
414 { 0xE0, "Permanent failure" },
415 { 0xE1, "Permanent: Service denied" },
416 { 0xE2, "Permanent: Message not found" },
417 { 0xE3, "Permanent: Content unsupported" },
422 static const value_string vals_read_status
[] = {
424 { 0x81, "Deleted without being read" },
429 static const value_string vals_reply_charging
[] = {
430 { 0x80, "Requested" },
431 { 0x81, "Requested text only" },
432 { 0x82, "Accepted" },
433 { 0x83, "Accepted text only" },
439 * Decodes a Text-string from the protocol data
440 * Text-string = [Quote] *TEXT End-of-string
441 * Quote = <Octet 127>
442 * End-of-string = <Octet 0>
444 * \todo Shouldn't we be sharing this with WSP (packet-wap.c)?
446 * \param tvb The buffer with PDU-data
447 * \param offset Offset within that buffer
448 * \param strval Pointer to variable into which to put pointer to
449 * buffer allocated to hold the text; must be freed
450 * when no longer used
452 * \return The length in bytes of the entire field
455 get_text_string(tvbuff_t
*tvb
, guint offset
, const char **strval
)
459 DebugLog(("get_text_string(tvb = %p, offset = %u, **strval) - start\n",
461 len
= tvb_strsize(tvb
, offset
);
462 DebugLog((" [1] tvb_strsize(tvb, offset) == %u\n", len
));
463 if (tvb_get_guint8(tvb
, offset
) == MM_QUOTE
)
464 *strval
= (const char *)tvb_memdup(wmem_packet_scope(), tvb
, offset
+1, len
-1);
466 *strval
= (const char *)tvb_memdup(wmem_packet_scope(), tvb
, offset
, len
);
467 DebugLog((" [3] Return(len) == %u\n", len
));
472 * Decodes a Value-length from the protocol data.
473 * Value-length = Short-length | (Length-quote Length)
474 * Short-length = <Any octet 0-30>
475 * Length-quote = <Octet 31>
476 * Length = Uintvar-integer
478 * \todo Shouldn't we be sharing this with WSP (packet-wap.c)?
480 * \param tvb The buffer with PDU-data
481 * \param offset Offset within that buffer
482 * \param byte_count Returns the length in bytes of
483 * the "Value-length" field.
485 * \return The actual value of "Value-length"
488 get_value_length(tvbuff_t
*tvb
, guint offset
, guint
*byte_count
)
492 field
= tvb_get_guint8(tvb
, offset
++);
495 else { /* Must be 31 so, Uintvar follows */
496 field
= tvb_get_guintvar(tvb
, offset
, byte_count
);
503 * Decodes an Encoded-string-value from the protocol data
504 * Encoded-string-value = Text-string | Value-length Char-set Text-string
506 * \param tvb The buffer with PDU-data
507 * \param offset Offset within that buffer
508 * \param strval Pointer to variable into which to put pointer to
509 * buffer allocated to hold the text; must be freed
510 * when no longer used
512 * \return The length in bytes of the entire field
515 get_encoded_strval(tvbuff_t
*tvb
, guint offset
, const char **strval
)
521 field
= tvb_get_guint8(tvb
, offset
);
524 length
= get_value_length(tvb
, offset
, &count
);
528 /* \todo Something with "Char-set", skip for now */
529 *strval
= (char *)tvb_get_string(wmem_packet_scope(), tvb
, offset
+ count
+ 1, length
- 1);
531 return count
+ length
;
533 return get_text_string(tvb
, offset
, strval
);
537 * Decodes a Long-integer from the protocol data
538 * Long-integer = Short-length Multi-octet-integer
539 * Short-length = <Any octet 0-30>
540 * Multi-octet-integer = 1*30OCTET
542 * \todo Shouldn't we be sharing this with WSP (packet-wap.c)?
544 * \param tvb The buffer with PDU-data
545 * \param offset Offset within that buffer
546 * \param byte_count Returns the length in bytes of the field
548 * \return The value of the Long-integer
550 * \note A maximum of 4-byte integers will be handled.
553 get_long_integer(tvbuff_t
*tvb
, guint offset
, guint
*byte_count
)
557 *byte_count
= tvb_get_guint8(tvb
, offset
++);
558 switch (*byte_count
) {
560 val
= tvb_get_guint8(tvb
, offset
);
563 val
= tvb_get_ntohs(tvb
, offset
);
566 val
= tvb_get_ntoh24(tvb
, offset
);
569 val
= tvb_get_ntohl(tvb
, offset
);
580 * Decodes an Integer-value from the protocol data
581 * Integer-value = Short-integer | Long-integer
582 * Short-integer = OCTET
583 * Long-integer = Short-length Multi-octet-integer
584 * Short-length = <Any octet 0-30>
585 * Multi-octet-integer = 1*30OCTET
587 * \todo Shouldn't we be sharing this with WSP (packet-wap.c)?
589 * \param tvb The buffer with PDU-data
590 * \param offset Offset within that buffer
591 * \param byte_count Returns the length in bytes of the field
593 * \return The value of the Long-integer
595 * \note A maximum of 4-byte integers will be handled.
598 get_integer_value(tvbuff_t
*tvb
, guint offset
, guint
*byte_count
)
603 peek
= tvb_get_guint8(tvb
, offset
++);
612 val
= tvb_get_guint8(tvb
, offset
);
615 val
= tvb_get_ntohs(tvb
, offset
);
618 val
= tvb_get_ntoh24(tvb
, offset
);
621 val
= tvb_get_ntohl(tvb
, offset
);
632 /* Code to actually dissect the packets */
634 dissect_mmse_heur(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
638 DebugLog(("dissect_mmse_heur()\n"));
640 * Check if data makes sense for it to be dissected as MMSE: Message-type
641 * field must make sense and followed by either Transaction-Id
642 * or MMS-Version header
644 if (tvb_get_guint8(tvb
, 0) != MM_MTYPE_HDR
)
646 pdut
= tvb_get_guint8(tvb
, 1);
647 if (try_val_to_str(pdut
, vals_message_type
) == NULL
)
649 if ((tvb_get_guint8(tvb
, 2) != MM_TID_HDR
) &&
650 (tvb_get_guint8(tvb
, 2) != MM_VERSION_HDR
))
652 dissect_mmse_standalone(tvb
, pinfo
, tree
);
657 dissect_mmse_standalone(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
660 const char *message_type
;
662 DebugLog(("dissect_mmse_standalone() - START (Packet %u)\n",
665 pdut
= tvb_get_guint8(tvb
, 1);
666 message_type
= val_to_str(pdut
, vals_message_type
, "Unknown type %u");
668 /* Make entries in Protocol column and Info column on summary display */
669 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "MMSE");
671 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "MMS %s", message_type
);
673 dissect_mmse(tvb
, pinfo
, tree
, pdut
, message_type
);
677 dissect_mmse_encapsulated(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
680 const char *message_type
;
682 DebugLog(("dissect_mmse_encapsulated() - START (Packet %u)\n",
685 pdut
= tvb_get_guint8(tvb
, 1);
686 message_type
= val_to_str(pdut
, vals_message_type
, "Unknown type %u");
688 /* Make entries in Info column on summary display */
689 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, " ", "(MMS %s)",
692 dissect_mmse(tvb
, pinfo
, tree
, pdut
, message_type
);
696 dissect_mmse(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint8 pdut
,
697 const char *message_type
)
704 guint8 version
= 0x80; /* Default to MMSE 1.0 */
706 /* Set up structures needed to add the protocol subtree and manage it */
707 proto_item
*ti
= NULL
;
708 proto_tree
*mmse_tree
= NULL
;
710 DebugLog(("dissect_mmse() - START (Packet %u)\n", pinfo
->fd
->num
));
712 /* If tree == NULL then we are only interested in protocol dissection
713 * up to reassembly and handoff to subdissectors if applicable; the
714 * columns must be set appropriately too.
715 * If tree != NULL then we also want to display the protocol tree
718 * In the interest of speed, skip protocol tree item generation
722 DebugLog(("tree != NULL\n"));
724 ti
= proto_tree_add_item(tree
, proto_mmse
, tvb
, 0, -1, ENC_NA
);
725 proto_item_append_text(ti
, ", Type: %s", message_type
);
726 /* create display subtree for the protocol */
727 mmse_tree
= proto_item_add_subtree(ti
, ett_mmse
);
729 /* Report PDU-type */
730 proto_tree_add_uint(mmse_tree
, hf_mmse_message_type
, tvb
, 0, 2, pdut
);
733 offset
= 2; /* Skip Message-Type */
736 * Cycle through MMS-headers
738 * NOTE - some PDUs may convey content which can be handed off
741 if (tree
|| pdu_has_content(pdut
)) {
742 while ((offset
< tvb_reported_length(tvb
)) &&
743 (field
= tvb_get_guint8(tvb
, offset
++)) != MM_CTYPE_HDR
)
745 DebugLog(("\tField = 0x%02X (offset = %u): %s\n",
747 val_to_str(field
, vals_mm_header_names
,
748 "Unknown MMS header 0x%02X")));
751 case MM_TID_HDR
: /* Text-string */
752 length
= get_text_string(tvb
, offset
, &strval
);
754 proto_tree_add_string(mmse_tree
, hf_mmse_transaction_id
,
755 tvb
, offset
- 1, length
+ 1,strval
);
759 case MM_VERSION_HDR
: /* nibble-Major/nibble-minor*/
760 version
= tvb_get_guint8(tvb
, offset
++);
765 major
= (version
& 0x70) >> 4;
766 minor
= version
& 0x0F;
768 vers_string
= wmem_strdup_printf(wmem_packet_scope(), "%u", major
);
770 vers_string
= wmem_strdup_printf(wmem_packet_scope(), "%u.%u", major
, minor
);
771 proto_tree_add_string(mmse_tree
, hf_mmse_mms_version
,
772 tvb
, offset
- 2, 2, vers_string
);
775 case MM_BCC_HDR
: /* Encoded-string-value */
776 length
= get_encoded_strval(tvb
, offset
, &strval
);
778 proto_tree_add_string(mmse_tree
, hf_mmse_bcc
, tvb
,
779 offset
- 1, length
+ 1, strval
);
783 case MM_CC_HDR
: /* Encoded-string-value */
784 length
= get_encoded_strval(tvb
, offset
, &strval
);
786 proto_tree_add_string(mmse_tree
, hf_mmse_cc
, tvb
,
787 offset
- 1, length
+ 1, strval
);
791 case MM_CLOCATION_HDR
: /* Uri-value */
792 if (pdut
== PDU_M_MBOX_DELETE_CONF
) {
793 /* General form with length */
794 length
= tvb_get_guint8(tvb
, offset
);
795 if (length
== 0x1F) {
796 guint length_len
= 0;
797 length
= tvb_get_guintvar(tvb
, offset
+ 1,
799 length
+= 1 + length_len
;
804 tvb_ensure_bytes_exist(tvb
, offset
- 1, length
+ 1);
805 proto_tree_add_string(mmse_tree
,
806 hf_mmse_content_location
,
807 tvb
, offset
- 1, length
+ 1,
808 "<Undecoded value for m-mbox-delete-conf>");
811 length
= get_text_string(tvb
, offset
, &strval
);
813 proto_tree_add_string(mmse_tree
,
814 hf_mmse_content_location
,
815 tvb
, offset
- 1, length
+ 1, strval
);
820 case MM_DATE_HDR
: /* Long-integer */
825 tval
= get_long_integer(tvb
, offset
, &count
);
829 tvb_ensure_bytes_exist(tvb
, offset
- 1, count
+ 1);
830 proto_tree_add_time(mmse_tree
, hf_mmse_date
, tvb
,
831 offset
- 1, count
+ 1, &tmptime
);
836 case MM_DREPORT_HDR
: /* Yes|No */
837 field
= tvb_get_guint8(tvb
, offset
++);
839 proto_tree_add_uint(mmse_tree
,
840 hf_mmse_delivery_report
,
841 tvb
, offset
- 2, 2, field
);
846 * Value-length(Absolute-token Date-value|
847 * Relative-token Delta-seconds-value)
849 length
= get_value_length(tvb
, offset
, &count
);
850 field
= tvb_get_guint8(tvb
, offset
+ count
);
856 tval
= get_long_integer(tvb
, offset
+ count
+ 1, &cnt
);
860 tvb_ensure_bytes_exist(tvb
, offset
- 1, length
+ count
+ 1);
862 proto_tree_add_time(mmse_tree
,
863 hf_mmse_delivery_time_abs
,
865 length
+ count
+ 1, &tmptime
);
867 proto_tree_add_time(mmse_tree
,
868 hf_mmse_delivery_time_rel
,
870 length
+ count
+ 1, &tmptime
);
872 offset
+= length
+ count
;
876 * Value-length(Absolute-token Date-value|
877 * Relative-token Delta-seconds-value)
879 length
= get_value_length(tvb
, offset
, &count
);
880 field
= tvb_get_guint8(tvb
, offset
+ count
);
886 tval
= get_long_integer(tvb
, offset
+ count
+ 1, &cnt
);
890 tvb_ensure_bytes_exist(tvb
, offset
- 1, length
+ count
+ 1);
892 proto_tree_add_time(mmse_tree
, hf_mmse_expiry_abs
,
894 length
+ count
+ 1, &tmptime
);
896 proto_tree_add_time(mmse_tree
, hf_mmse_expiry_rel
,
898 length
+ count
+ 1, &tmptime
);
900 offset
+= length
+ count
;
904 * Value-length(Address-present-token Encoded-string-value
905 * |Insert-address-token)
907 length
= get_value_length(tvb
, offset
, &count
);
909 field
= tvb_get_guint8(tvb
, offset
+ count
);
910 tvb_ensure_bytes_exist(tvb
, offset
- 1, length
+ count
+ 1);
912 proto_tree_add_string(mmse_tree
, hf_mmse_from
, tvb
,
913 offset
-1, length
+ count
+ 1,
916 (void) get_encoded_strval(tvb
, offset
+ count
+ 1,
918 proto_tree_add_string(mmse_tree
, hf_mmse_from
, tvb
,
919 offset
-1, length
+ count
+ 1, strval
);
922 offset
+= length
+ count
;
926 * Class-identifier|Text-string
928 field
= tvb_get_guint8(tvb
, offset
);
932 proto_tree_add_uint(mmse_tree
,
933 hf_mmse_message_class_id
,
934 tvb
, offset
- 2, 2, field
);
937 length
= get_text_string(tvb
, offset
, &strval
);
939 proto_tree_add_string(mmse_tree
,
940 hf_mmse_message_class_str
,
941 tvb
, offset
- 1, length
+ 1,
947 case MM_MID_HDR
: /* Text-string */
948 length
= get_text_string(tvb
, offset
, &strval
);
950 proto_tree_add_string(mmse_tree
, hf_mmse_message_id
,
951 tvb
, offset
- 1, length
+ 1, strval
);
955 case MM_MSIZE_HDR
: /* Long-integer */
956 length
= get_long_integer(tvb
, offset
, &count
);
958 proto_tree_add_uint(mmse_tree
, hf_mmse_message_size
,
959 tvb
, offset
- 1, count
+ 1, length
);
963 case MM_PRIORITY_HDR
: /* Low|Normal|High */
964 field
= tvb_get_guint8(tvb
, offset
++);
966 proto_tree_add_uint(mmse_tree
, hf_mmse_priority
, tvb
,
967 offset
- 2, 2, field
);
970 case MM_RREPLY_HDR
: /* Yes|No */
971 field
= tvb_get_guint8(tvb
, offset
++);
973 if (version
== 0x80) { /* MMSE 1.0 */
974 proto_tree_add_uint(mmse_tree
, hf_mmse_read_reply
,
975 tvb
, offset
- 2, 2, field
);
977 proto_tree_add_uint(mmse_tree
, hf_mmse_read_report
,
978 tvb
, offset
- 2, 2, field
);
982 case MM_RALLOWED_HDR
: /* Yes|No */
983 field
= tvb_get_guint8(tvb
, offset
++);
985 proto_tree_add_uint(mmse_tree
, hf_mmse_report_allowed
,
986 tvb
, offset
- 2, 2, field
);
990 field
= tvb_get_guint8(tvb
, offset
++);
992 proto_tree_add_uint(mmse_tree
, hf_mmse_response_status
,
993 tvb
, offset
- 2, 2, field
);
996 case MM_RTEXT_HDR
: /* Encoded-string-value */
997 if (pdut
== PDU_M_MBOX_DELETE_CONF
) {
998 /* General form with length */
999 length
= tvb_get_guint8(tvb
, offset
);
1000 if (length
== 0x1F) {
1001 guint length_len
= 0;
1002 length
= tvb_get_guintvar(tvb
, offset
+ 1,
1004 length
+= 1 + length_len
;
1009 proto_tree_add_string(mmse_tree
,
1010 hf_mmse_content_location
,
1011 tvb
, offset
- 1, length
+ 1,
1012 "<Undecoded value for m-mbox-delete-conf>");
1015 length
= get_encoded_strval(tvb
, offset
, &strval
);
1017 proto_tree_add_string(mmse_tree
,
1018 hf_mmse_response_text
, tvb
, offset
- 1,
1019 length
+ 1, strval
);
1024 case MM_SVISIBILITY_HDR
: /* Hide|Show */
1025 field
= tvb_get_guint8(tvb
, offset
++);
1027 proto_tree_add_uint(mmse_tree
,hf_mmse_sender_visibility
,
1028 tvb
, offset
- 2, 2, field
);
1032 field
= tvb_get_guint8(tvb
, offset
++);
1034 proto_tree_add_uint(mmse_tree
, hf_mmse_status
, tvb
,
1035 offset
- 2, 2, field
);
1038 case MM_SUBJECT_HDR
: /* Encoded-string-value */
1039 length
= get_encoded_strval(tvb
, offset
, &strval
);
1041 proto_tree_add_string(mmse_tree
, hf_mmse_subject
, tvb
,
1042 offset
- 1, length
+ 1, strval
);
1046 case MM_TO_HDR
: /* Encoded-string-value */
1047 length
= get_encoded_strval(tvb
, offset
, &strval
);
1049 proto_tree_add_string(mmse_tree
, hf_mmse_to
, tvb
,
1050 offset
- 1, length
+ 1, strval
);
1056 * MMS Encapsulation 1.1
1058 case MM_RETRIEVE_STATUS_HDR
: /* Well-known-value */
1059 field
= tvb_get_guint8(tvb
, offset
++);
1061 proto_tree_add_uint(mmse_tree
, hf_mmse_retrieve_status
,
1062 tvb
, offset
- 2, 2, field
);
1065 case MM_RETRIEVE_TEXT_HDR
:
1066 if (pdut
== PDU_M_MBOX_DELETE_CONF
) {
1067 /* General form with length */
1068 length
= tvb_get_guint8(tvb
, offset
);
1069 if (length
== 0x1F) {
1070 guint length_len
= 0;
1071 length
= tvb_get_guintvar(tvb
, offset
+ 1,
1073 length
+= 1 + length_len
;
1078 proto_tree_add_string(mmse_tree
,
1079 hf_mmse_content_location
,
1080 tvb
, offset
- 1, length
+ 1,
1081 "<Undecoded value for m-mbox-delete-conf>");
1084 /* Encoded-string-value */
1085 length
= get_encoded_strval(tvb
, offset
, &strval
);
1087 proto_tree_add_string(mmse_tree
,
1088 hf_mmse_retrieve_text
, tvb
, offset
- 1,
1089 length
+ 1, strval
);
1094 case MM_READ_STATUS_HDR
: /* Well-known-value */
1095 field
= tvb_get_guint8(tvb
, offset
++);
1097 proto_tree_add_uint(mmse_tree
, hf_mmse_read_status
,
1098 tvb
, offset
- 2, 2, field
);
1101 case MM_REPLY_CHARGING_HDR
: /* Well-known-value */
1102 field
= tvb_get_guint8(tvb
, offset
++);
1104 proto_tree_add_uint(mmse_tree
, hf_mmse_reply_charging
,
1105 tvb
, offset
- 2, 2, field
);
1108 case MM_REPLY_CHARGING_DEADLINE_HDR
: /* Well-known-value */
1110 * Value-length(Absolute-token Date-value|
1111 * Relative-token Delta-seconds-value)
1113 length
= get_value_length(tvb
, offset
, &count
);
1114 field
= tvb_get_guint8(tvb
, offset
+ count
);
1120 tval
= get_long_integer(tvb
, offset
+ count
+ 1, &cnt
);
1121 tmptime
.secs
= tval
;
1124 tvb_ensure_bytes_exist(tvb
, offset
- 1, length
+ count
+ 1);
1126 proto_tree_add_time(mmse_tree
, hf_mmse_reply_charging_deadline_abs
,
1128 length
+ count
+ 1, &tmptime
);
1130 proto_tree_add_time(mmse_tree
, hf_mmse_reply_charging_deadline_rel
,
1132 length
+ count
+ 1, &tmptime
);
1134 offset
+= length
+ count
;
1136 case MM_REPLY_CHARGING_ID_HDR
: /* Text-string */
1137 length
= get_text_string(tvb
, offset
, &strval
);
1139 proto_tree_add_string(mmse_tree
,
1140 hf_mmse_reply_charging_id
,
1141 tvb
, offset
- 1, length
+ 1, strval
);
1145 case MM_REPLY_CHARGING_SIZE_HDR
: /* Long-integer */
1146 length
= get_long_integer(tvb
, offset
, &count
);
1148 proto_tree_add_uint(mmse_tree
,
1149 hf_mmse_reply_charging_size
,
1150 tvb
, offset
- 1, count
+ 1, length
);
1154 case MM_PREV_SENT_BY_HDR
:
1155 /* Value-length Integer-value Encoded-string-value */
1156 length
= get_value_length(tvb
, offset
, &count
);
1158 guint32 fwd_count
, count1
, count2
;
1159 proto_tree
*subtree
= NULL
;
1160 proto_item
*tii
= NULL
;
1161 /* 1. Forwarded-count-value := Integer-value */
1162 fwd_count
= get_integer_value(tvb
, offset
+ count
,
1164 /* 2. Encoded-string-value */
1165 count2
= get_encoded_strval(tvb
,
1166 offset
+ count
+ count1
, &strval
);
1167 /* Now render the fields */
1168 tii
= proto_tree_add_string_format(mmse_tree
,
1169 hf_mmse_prev_sent_by
,
1170 tvb
, offset
- 1, 1 + count
+ length
,
1171 strval
, "%s (Forwarded-count=%u)",
1172 format_text(strval
, strlen(strval
)),
1174 subtree
= proto_item_add_subtree(tii
,
1175 ett_mmse_hdr_details
);
1176 proto_tree_add_uint(subtree
,
1177 hf_mmse_prev_sent_by_fwd_count
,
1178 tvb
, offset
+ count
, count1
, fwd_count
);
1179 proto_tree_add_string(subtree
,
1180 hf_mmse_prev_sent_by_address
,
1181 tvb
, offset
+ count
+ count1
, count2
, strval
);
1183 offset
+= length
+ count
;
1185 case MM_PREV_SENT_DATE_HDR
:
1186 /* Value-Length Forwarded-count-value Date-value */
1187 length
= get_value_length(tvb
, offset
, &count
);
1189 guint32 fwd_count
, count1
, count2
;
1192 proto_tree
*subtree
= NULL
;
1193 proto_item
*tii
= NULL
;
1194 /* 1. Forwarded-count-value := Integer-value */
1195 fwd_count
= get_integer_value(tvb
, offset
+ count
,
1197 /* 2. Date-value := Long-integer */
1198 tval
= get_long_integer(tvb
, offset
+ count
+ count1
,
1200 tmptime
.secs
= tval
;
1202 strval
= abs_time_to_str(&tmptime
, ABSOLUTE_TIME_LOCAL
,
1204 /* Now render the fields */
1205 tvb_ensure_bytes_exist(tvb
, offset
- 1, length
+ count
+ 1);
1206 tii
= proto_tree_add_string_format(mmse_tree
,
1207 hf_mmse_prev_sent_date
,
1208 tvb
, offset
- 1, 1 + count
+ length
,
1209 strval
, "%s (Forwarded-count=%u)",
1210 format_text(strval
, strlen(strval
)),
1212 subtree
= proto_item_add_subtree(tii
,
1213 ett_mmse_hdr_details
);
1214 proto_tree_add_uint(subtree
,
1215 hf_mmse_prev_sent_date_fwd_count
,
1216 tvb
, offset
+ count
, count1
, fwd_count
);
1217 proto_tree_add_string(subtree
,
1218 hf_mmse_prev_sent_date_date
,
1219 tvb
, offset
+ count
+ count1
, count2
, strval
);
1221 offset
+= length
+ count
;
1224 /* MMS Encapsulation 1.2 */
1227 if (field
& 0x80) { /* Well-known WSP header encoding */
1228 guint8 peek
= tvb_get_guint8(tvb
, offset
);
1229 const char *hdr_name
= val_to_str(field
, vals_mm_header_names
,
1230 "Unknown field (0x%02x)");
1231 DebugLog(("\t\tUndecoded well-known header: %s\n",
1234 if (peek
& 0x80) { /* Well-known value */
1237 proto_tree_add_text(mmse_tree
, tvb
, offset
- 1,
1239 "%s: <Well-known value 0x%02x>"
1243 } else if ((peek
== 0) || (peek
>= 0x20)) { /* Text */
1244 length
= get_text_string(tvb
, offset
, &strval
);
1246 proto_tree_add_text(mmse_tree
, tvb
, offset
- 1,
1247 length
+ 1, "%s: %s (Not decoded)",
1249 format_text(strval
, strlen(strval
)));
1251 } else { /* General form with length */
1252 if (peek
== 0x1F) { /* Value length in guintvar */
1253 guint length_len
= 0;
1254 length
= 1 + tvb_get_guintvar(tvb
, offset
+ 1,
1256 length
+= length_len
;
1257 } else { /* Value length in octet */
1258 length
= 1 + tvb_get_guint8(tvb
, offset
);
1261 proto_tree_add_text(mmse_tree
, tvb
, offset
- 1,
1263 "<Value in general form> (not decoded)",
1268 } else { /* Literal WSP header encoding */
1270 const char *strval2
;
1273 length
= get_text_string(tvb
, offset
, &strval
);
1274 DebugLog(("\t\tUndecoded literal header: %s\n",
1276 length2
= get_text_string(tvb
, offset
+length
, &strval2
);
1279 proto_tree_add_string_format(mmse_tree
,
1280 hf_mmse_ffheader
, tvb
, offset
,
1282 tvb_get_string(wmem_packet_scope(), tvb
, offset
,
1285 format_text(strval
, strlen(strval
)),
1286 format_text(strval2
, strlen(strval2
)));
1288 offset
+= length
+ length2
;
1292 DebugLog(("\tEnd(case)\n"));
1294 DebugLog(("\tEnd(switch)\n"));
1295 if (field
== MM_CTYPE_HDR
) {
1297 * Eeehh, we're now actually back to good old WSP content-type
1298 * encoding. Let's steal that from the WSP-dissector.
1302 const char *type_str
;
1304 DebugLog(("Content-Type: [from WSP dissector]\n"));
1305 DebugLog(("Calling add_content_type() in WSP dissector\n"));
1306 offset
= add_content_type(mmse_tree
, tvb
, offset
, &type
, &type_str
);
1307 DebugLog(("Generating new TVB subset (offset = %u)\n", offset
));
1308 tmp_tvb
= tvb_new_subset_remaining(tvb
, offset
);
1309 DebugLog(("Add POST data\n"));
1310 add_post_data(mmse_tree
, tmp_tvb
, type
, type_str
, pinfo
);
1311 DebugLog(("Done!\n"));
1314 DebugLog(("tree == NULL and PDU has no potential content\n"));
1317 /* If this protocol has a sub-dissector call it here, see section 1.8 */
1318 DebugLog(("dissect_mmse() - END\n"));
1322 /* Register the protocol with Wireshark */
1324 /* this format is required because a script is used to build the C function
1325 * that calls all the protocol registration.
1328 proto_register_mmse(void)
1330 /* Setup list of header fields See Section 1.6.1 for details */
1331 static hf_register_info hf
[] = {
1332 { &hf_mmse_message_type
,
1333 { "X-Mms-Message-Type", "mmse.message_type",
1334 FT_UINT8
, BASE_HEX
, VALS(vals_message_type
), 0x00,
1335 "Specifies the transaction type. Effectively defines PDU.",
1339 { &hf_mmse_transaction_id
,
1340 { "X-Mms-Transaction-ID", "mmse.transaction_id",
1341 FT_STRING
, BASE_NONE
, NULL
, 0x00,
1342 "A unique identifier for this transaction. Identifies request and corresponding response only.",
1346 { &hf_mmse_mms_version
,
1347 { "X-Mms-MMS-Version", "mmse.mms_version",
1348 FT_STRING
, BASE_NONE
, NULL
, 0x00,
1349 "Version of the protocol used.",
1354 { "Bcc", "mmse.bcc",
1355 FT_STRING
, BASE_NONE
, NULL
, 0x00,
1356 "Blind carbon copy.",
1362 FT_STRING
, BASE_NONE
, NULL
, 0x00,
1367 { &hf_mmse_content_location
,
1368 { "X-Mms-Content-Location", "mmse.content_location",
1369 FT_STRING
, BASE_NONE
, NULL
, 0x00,
1370 "Defines the location of the message.",
1375 { "Date", "mmse.date",
1376 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x00,
1377 "Arrival timestamp of the message or sending timestamp.",
1381 { &hf_mmse_delivery_report
,
1382 { "X-Mms-Delivery-Report", "mmse.delivery_report",
1383 FT_UINT8
, BASE_HEX
, VALS(vals_yes_no
), 0x00,
1384 "Whether a report of message delivery is wanted or not.",
1388 { &hf_mmse_delivery_time_abs
,
1389 { "X-Mms-Delivery-Time", "mmse.delivery_time.abs",
1390 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x00,
1391 "The time at which message delivery is desired.",
1395 { &hf_mmse_delivery_time_rel
,
1396 { "X-Mms-Delivery-Time", "mmse.delivery_time.rel",
1397 FT_RELATIVE_TIME
, BASE_NONE
, NULL
, 0x00,
1398 "The desired message delivery delay.",
1402 { &hf_mmse_expiry_abs
,
1403 { "X-Mms-Expiry", "mmse.expiry.abs",
1404 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x00,
1405 "Time when message expires and need not be delivered anymore.",
1409 { &hf_mmse_expiry_rel
,
1410 { "X-Mms-Expiry", "mmse.expiry.rel",
1411 FT_RELATIVE_TIME
, BASE_NONE
, NULL
, 0x00,
1412 "Delay before message expires and need not be delivered anymore.",
1417 { "From", "mmse.from",
1418 FT_STRING
, BASE_NONE
, NULL
, 0x00,
1419 "Address of the message sender.",
1423 { &hf_mmse_message_class_id
,
1424 { "X-Mms-Message-Class", "mmse.message_class.id",
1425 FT_UINT8
, BASE_HEX
, VALS(vals_message_class
), 0x00,
1426 "Of what category is the message.",
1430 { &hf_mmse_message_class_str
,
1431 { "X-Mms-Message-Class", "mmse.message_class.str",
1432 FT_STRING
, BASE_NONE
, NULL
, 0x00,
1433 "Of what category is the message.",
1437 { &hf_mmse_message_id
,
1438 { "Message-Id", "mmse.message_id",
1439 FT_STRING
, BASE_NONE
, NULL
, 0x00,
1440 "Unique identification of the message.",
1444 { &hf_mmse_message_size
,
1445 { "X-Mms-Message-Size", "mmse.message_size",
1446 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
1447 "The size of the message in octets.",
1451 { &hf_mmse_priority
,
1452 { "X-Mms-Priority", "mmse.priority",
1453 FT_UINT8
, BASE_HEX
, VALS(vals_priority
), 0x00,
1454 "Priority of the message.",
1458 { &hf_mmse_read_reply
,
1459 { "X-Mms-Read-Reply", "mmse.read_reply",
1460 FT_UINT8
, BASE_HEX
, VALS(vals_yes_no
), 0x00,
1461 "Whether a read report from every recipient is wanted.",
1465 { &hf_mmse_read_report
,
1466 { "X-Mms-Read-Report", "mmse.read_report",
1467 FT_UINT8
, BASE_HEX
, VALS(vals_yes_no
), 0x00,
1468 "Whether a read report from every recipient is wanted.",
1472 { &hf_mmse_report_allowed
,
1473 { "X-Mms-Report-Allowed", "mmse.report_allowed",
1474 FT_UINT8
, BASE_HEX
, VALS(vals_yes_no
), 0x00,
1475 "Sending of delivery report allowed or not.",
1479 { &hf_mmse_response_status
,
1480 { "Response-Status", "mmse.response_status",
1481 FT_UINT8
, BASE_HEX
, VALS(vals_response_status
), 0x00,
1482 "MMS-specific result of a message submission or retrieval.",
1486 { &hf_mmse_response_text
,
1487 { "Response-Text", "mmse.response_text",
1488 FT_STRING
, BASE_NONE
, NULL
, 0x00,
1489 "Additional information on MMS-specific result.",
1493 { &hf_mmse_sender_visibility
,
1494 { "Sender-Visibility", "mmse.sender_visibility",
1495 FT_UINT8
, BASE_HEX
, VALS(vals_sender_visibility
), 0x00,
1496 "Disclose sender identity to receiver or not.",
1501 { "Status", "mmse.status",
1502 FT_UINT8
, BASE_HEX
, VALS(vals_message_status
), 0x00,
1503 "Current status of the message.",
1508 { "Subject", "mmse.subject",
1509 FT_STRING
, BASE_NONE
, NULL
, 0x00,
1510 "Subject of the message.",
1516 FT_STRING
, BASE_NONE
, NULL
, 0x00,
1517 "Recipient(s) of the message.",
1522 { &hf_mmse_content_type
,
1523 { "Data", "mmse.content_type",
1524 FT_NONE
, BASE_NONE
, NULL
, 0x00,
1525 "Media content of the message.",
1530 { &hf_mmse_ffheader
,
1531 { "Free format (not encoded) header", "mmse.ffheader",
1532 FT_STRING
, BASE_NONE
, NULL
, 0x00,
1533 "Application header without corresponding encoding.",
1538 { &hf_mmse_retrieve_status
,
1539 { "X-Mms-Retrieve-Status", "mmse.retrieve_status",
1540 FT_UINT8
, BASE_HEX
, VALS(vals_retrieve_status
), 0x00,
1541 "MMS-specific result of a message retrieval.",
1545 { &hf_mmse_retrieve_text
,
1546 { "X-Mms-Retrieve-Text", "mmse.retrieve_text",
1547 FT_STRING
, BASE_NONE
, NULL
, 0x00,
1548 "Status text of a MMS message retrieval.",
1552 { &hf_mmse_read_status
,
1553 { "X-Mms-Read-Status", "mmse.read_status",
1554 FT_UINT8
, BASE_HEX
, VALS(vals_read_status
), 0x00,
1555 "MMS-specific message read status.",
1559 { &hf_mmse_reply_charging
,
1560 { "X-Mms-Reply-Charging", "mmse.reply_charging",
1561 FT_UINT8
, BASE_HEX
, VALS(vals_reply_charging
), 0x00,
1562 "MMS-specific message reply charging method.",
1566 { &hf_mmse_reply_charging_deadline_abs
,
1567 { "X-Mms-Reply-Charging-Deadline", "mmse.reply_charging_deadline.abs",
1568 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x00,
1569 "The latest time of the recipient(s) to submit the Reply MM.",
1573 { &hf_mmse_reply_charging_deadline_rel
,
1574 { "X-Mms-Reply-Charging-Deadline", "mmse.reply_charging_deadline.rel",
1575 FT_RELATIVE_TIME
, BASE_NONE
, NULL
, 0x00,
1576 "The latest time of the recipient(s) to submit the Reply MM.",
1580 { &hf_mmse_reply_charging_id
,
1581 { "X-Mms-Reply-Charging-Id", "mmse.reply_charging_id",
1582 FT_STRING
, BASE_NONE
, NULL
, 0x00,
1583 "Unique reply charging identification of the message.",
1587 { &hf_mmse_reply_charging_size
,
1588 { "X-Mms-Reply-Charging-Size", "mmse.reply_charging_size",
1589 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
1590 "The size of the reply charging in octets.",
1594 { &hf_mmse_prev_sent_by
,
1595 { "X-Mms-Previously-Sent-By", "mmse.previously_sent_by",
1596 FT_STRING
, BASE_NONE
, NULL
, 0x00,
1597 "Indicates that the MM has been previously sent by this user.",
1601 { &hf_mmse_prev_sent_by_fwd_count
,
1602 { "Forward Count", "mmse.previously_sent_by.forward_count",
1603 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
1604 "Forward count of the previously sent MM.",
1608 { &hf_mmse_prev_sent_by_address
,
1609 { "Address", "mmse.previously_sent_by.address",
1610 FT_STRING
, BASE_NONE
, NULL
, 0x00,
1611 "Indicates from whom the MM has been previously sent.",
1615 { &hf_mmse_prev_sent_date
,
1616 { "X-Mms-Previously-Sent-Date", "mmse.previously_sent_date",
1617 FT_STRING
, BASE_NONE
, NULL
, 0x00,
1618 "Indicates the date that the MM has been previously sent.",
1622 { &hf_mmse_prev_sent_date_fwd_count
,
1623 { "Forward Count", "mmse.previously_sent_date.forward_count",
1624 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
1625 "Forward count of the previously sent MM.",
1629 { &hf_mmse_prev_sent_date_date
,
1630 { "Date", "mmse.previously_sent_date.date",
1631 FT_STRING
, BASE_NONE
, NULL
, 0x00,
1632 "Time when the MM has been previously sent.",
1640 /* Setup protocol subtree array */
1641 static gint
*ett
[] = {
1643 &ett_mmse_hdr_details
,
1646 /* Register the protocol name and description */
1647 proto_mmse
= proto_register_protocol("MMS Message Encapsulation",
1650 /* Required function calls to register header fields and subtrees used */
1651 proto_register_field_array(proto_mmse
, hf
, array_length(hf
));
1652 proto_register_subtree_array(ett
, array_length(ett
));
1655 /* If this dissector uses sub-dissector registration add registration routine.
1656 * This format is required because a script is used to find these routines and
1657 * create the code that calls these routines.
1660 proto_reg_handoff_mmse(void)
1662 dissector_handle_t mmse_standalone_handle
;
1663 dissector_handle_t mmse_encapsulated_handle
;
1665 heur_dissector_add("wsp", dissect_mmse_heur
, proto_mmse
);
1666 mmse_standalone_handle
= create_dissector_handle(
1667 dissect_mmse_standalone
, proto_mmse
);
1668 mmse_encapsulated_handle
= create_dissector_handle(
1669 dissect_mmse_encapsulated
, proto_mmse
);
1670 /* As the media types for WSP and HTTP are the same, the WSP dissector
1671 * uses the same string dissector table as the HTTP protocol. */
1672 dissector_add_string("media_type",
1673 "application/vnd.wap.mms-message", mmse_standalone_handle
);
1674 dissector_add_string("multipart_media_type",
1675 "application/vnd.wap.mms-message", mmse_encapsulated_handle
);