Coverage Report

Created: 2026-08-14 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-mmse.c
Line
Count
Source
1
/* packet-mmse.c
2
 * Routines for MMS Message Encapsulation dissection
3
 * Copyright 2001, Tom Uijldert <tom.uijldert@cmg.nl>
4
 * Copyright 2004, Olivier Biot
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 * ----------
12
 *
13
 * Dissector of an encoded Multimedia message PDU, as defined by the WAPForum
14
 * (http://www.wapforum.org) in "WAP-209-MMSEncapsulation-20020105-a".
15
 * Subsequent releases of MMS are in control of the Open Mobile Alliance (OMA):
16
 * Dissection of MMS 1.1 as in OMA-MMS-ENC-v1.1.
17
 * Dissection of MMS 1.2 as in OMA-MMS-ENC-v1.2 (not finished yet).
18
 */
19
20
/* This file has been edited with 8-space tabs and 4-space indentation */
21
22
#include "config.h"
23
24
25
#include <epan/packet.h>
26
#include <epan/expert.h>
27
#include <epan/to_str.h>
28
#include <epan/strutil.h>
29
#include <epan/iana_charsets.h>
30
#include "packet-wap.h"
31
#include "packet-wsp.h"
32
33
void proto_register_mmse(void);
34
void proto_reg_handoff_mmse(void);
35
36
static dissector_handle_t mmse_standalone_handle;
37
static dissector_handle_t mmse_encapsulated_handle;
38
39
17.4k
#define MM_QUOTE                0x7F    /* Quoted string        */
40
41
#define MMS_CONTENT_TYPE        0x3E    /* WINA-value for mms-message   */
42
43
/* General-purpose debug logger.
44
 * Requires double parentheses because of variable arguments of printf().
45
 *
46
 * Enable debug logging for MMSE by defining AM_CFLAGS
47
 * so that it contains "-DDEBUG_mmse"
48
 */
49
#ifdef DEBUG_mmse
50
#define DebugLog(x) \
51
        g_print("%s:%u: ", __FILE__, __LINE__); \
52
        g_print x
53
#else
54
74.4k
#define DebugLog(x) ;
55
#endif
56
57
/*
58
 * Forward declarations
59
 */
60
static int dissect_mmse_standalone(tvbuff_t *, packet_info *, proto_tree *, void*);
61
static void dissect_mmse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
62
        uint8_t pdut, const char *message_type);
63
64
/*
65
 * Header field values
66
 */
67
/* MMS 1.0 */
68
75
#define MM_BCC_HDR              0x81    /* Bcc                          */
69
172
#define MM_CC_HDR               0x82    /* Cc                           */
70
30
#define MM_CLOCATION_HDR        0x83    /* X-Mms-Content-Location       */
71
13.7k
#define MM_CTYPE_HDR            0x84    /* Content-Type                 */
72
21
#define MM_DATE_HDR             0x85    /* Date                         */
73
257
#define MM_DREPORT_HDR          0x86    /* X-Mms-Delivery-Report        */
74
23
#define MM_DTIME_HDR            0x87    /* X-Mms-Delivery-Time          */
75
60
#define MM_EXPIRY_HDR           0x88    /* X-Mms-Expiry                 */
76
110
#define MM_FROM_HDR             0x89    /* From                         */
77
181
#define MM_MCLASS_HDR           0x8A    /* X-Mms-Message-Class          */
78
18
#define MM_MID_HDR              0x8B    /* Message-ID                   */
79
524
#define MM_MTYPE_HDR            0x8C    /* X-Mms-Message-Type           */
80
155
#define MM_VERSION_HDR          0x8D    /* X-Mms-MMS-Version            */
81
48
#define MM_MSIZE_HDR            0x8E    /* X-Mms-Message-Size           */
82
122
#define MM_PRIORITY_HDR         0x8F    /* X-Mms-Priority               */
83
174
#define MM_RREPLY_HDR           0x90    /* X-Mms-Read-Reply             */
84
115
#define MM_RALLOWED_HDR         0x91    /* X-Mms-Report-Allowed         */
85
173
#define MM_RSTATUS_HDR          0x92    /* X-Mms-Response-Status        */
86
21
#define MM_RTEXT_HDR            0x93    /* X-Mms-Response-Text          */
87
95
#define MM_SVISIBILITY_HDR      0x94    /* X-Mms-Sender-Visibility      */
88
145
#define MM_STATUS_HDR           0x95    /* X-Mms-Status                 */
89
40
#define MM_SUBJECT_HDR          0x96    /* Subject                      */
90
37
#define MM_TO_HDR               0x97    /* To                           */
91
22
#define MM_TID_HDR              0x98    /* X-Mms-Transaction-Id         */
92
/* MMS 1.1 */
93
93
#define MM_RETRIEVE_STATUS_HDR  0x99    /* X-Mms-Retrieve-Status        */
94
48
#define MM_RETRIEVE_TEXT_HDR    0x9A    /* X-Mms-Retrieve-Text          */
95
247
#define MM_READ_STATUS_HDR      0x9B    /* X-Mms-Read-Status            */
96
100
#define MM_REPLY_CHARGING_HDR   0x9C    /* X-Mms-Reply-Charging         */
97
#define MM_REPLY_CHARGING_DEADLINE_HDR  \
98
28
                                0x9D    /* X-Mms-Reply-Charging-Deadline*/
99
#define MM_REPLY_CHARGING_ID_HDR        \
100
25
                                0x9E    /* X-Mms-Reply-Charging-ID      */
101
#define MM_REPLY_CHARGING_SIZE_HDR      \
102
18
                                0x9F    /* X-Mms-Reply-Charging-Size    */
103
65
#define MM_PREV_SENT_BY_HDR     0xA0    /* X-Mms-Previously-Sent-By     */
104
72
#define MM_PREV_SENT_DATE_HDR   0xA1    /* X-Mms-Previously-Sent-Date   */
105
/* MMS 1.2 */
106
#define MM_STORE_HDR            0xA2    /* X-Mms-Store                  */
107
#define MM_MM_STATE_HDR         0xA3    /* X-Mms-MM-State               */
108
#define MM_MM_FLAGS_HDR         0xA4    /* X-Mms-MM-Flags               */
109
#define MM_STORE_STATUS_HDR     0xA5    /* X-Mms-Store-Status           */
110
#define MM_STORE_STATUS_TEXT_HDR        \
111
                                0xA6    /* X-Mms-Store-Status-Text      */
112
#define MM_STORED_HDR           0xA7    /* X-Mms-Stored                 */
113
#define MM_ATTRIBUTES_HDR       0xA8    /* X-Mms-Attributes             */
114
#define MM_TOTALS_HDR           0xA9    /* X-Mms-Totals                 */
115
#define MM_MBOX_TOTALS_HDR      0xAA    /* X-Mms-Mbox-Totals            */
116
#define MM_QUOTAS_HDR           0xAB    /* X-Mms-Quotas                 */
117
#define MM_MBOX_QUOTAS_HDR      0xAC    /* X-Mms-Mbox-Quotas            */
118
#define MM_MBOX_MSG_COUNT_HDR   0xAD    /* X-Mms-Message-Count          */
119
#define MM_CONTENT_HDR          0xAE    /* Content                      */
120
#define MM_START_HDR            0xAF    /* X-Mms-Start                  */
121
#define MM_ADDITIONAL_HDR       0xB0    /* Additional-headers           */
122
#define MM_DISTRIBUION_IND_HDR  0xB1    /* X-Mms-Distribution-Indicator */
123
#define MM_ELEMENT_DESCR_HDR    0xB2    /* X-Mms-Element-Descriptor     */
124
#define MM_LIMIT_HDR            0xB3    /* X-Mms-Limit                  */
125
126
static const value_string vals_mm_header_names[] = {
127
        /* MMS 1.0 */
128
        { MM_BCC_HDR,                   "Bcc" },
129
        { MM_CC_HDR,                    "Cc" },
130
        { MM_CLOCATION_HDR,             "X-Mms-Content-Location" },
131
        { MM_CTYPE_HDR,                 "X-Mms-Content-Type" },
132
        { MM_DATE_HDR,                  "Date" },
133
        { MM_DREPORT_HDR,               "X-Mms-Delivery-Report" },
134
        { MM_DTIME_HDR,                 "X-Mms-Delivery-Time" },
135
        { MM_EXPIRY_HDR,                "X-Mms-Expiry" },
136
        { MM_FROM_HDR,                  "From" },
137
        { MM_MCLASS_HDR,                "X-Mms-Message-Class" },
138
        { MM_MID_HDR,                   "Message-ID" },
139
        { MM_MTYPE_HDR,                 "X-Mms-Message-Type" },
140
        { MM_VERSION_HDR,               "X-Mms-MMS-Version" },
141
        { MM_MSIZE_HDR,                 "X-Mms-Message-Size" },
142
        { MM_PRIORITY_HDR,              "X-Mms-Priority" },
143
        { MM_RREPLY_HDR,                "X-Mms-Read-Reply" },
144
        { MM_RALLOWED_HDR,              "X-Mms-Report-Allowed" },
145
        { MM_RSTATUS_HDR,               "X-Mms-Response-Status" },
146
        { MM_RTEXT_HDR,                 "X-Mms-Response-Text" },
147
        { MM_SVISIBILITY_HDR,           "X-Mms-Sender-Visibility" },
148
        { MM_STATUS_HDR,                "X-Mms-Status" },
149
        { MM_SUBJECT_HDR,               "Subject" },
150
        { MM_TO_HDR,                    "To" },
151
        { MM_TID_HDR,                   "X-Mms-Transaction-Id" },
152
        /* MMS 1.1 */
153
        { MM_RETRIEVE_STATUS_HDR,       "X-Mms-Retrieve-Status" },
154
        { MM_RETRIEVE_TEXT_HDR,         "X-Mms-Retrieve-Text" },
155
        { MM_READ_STATUS_HDR,           "X-Mms-Read-Status" },
156
        { MM_REPLY_CHARGING_HDR,        "X-Mms-Reply-Charging" },
157
        { MM_REPLY_CHARGING_DEADLINE_HDR,
158
                                        "X-Mms-Reply-Charging-Deadline" },
159
        { MM_REPLY_CHARGING_ID_HDR,     "X-Mms-Reply-Charging-ID" },
160
        { MM_REPLY_CHARGING_SIZE_HDR,   "X-Mms-Reply-Charging-Size" },
161
        { MM_PREV_SENT_BY_HDR,          "X-Mms-Previously-Sent-By" },
162
        { MM_PREV_SENT_DATE_HDR,        "X-Mms-Previously-Sent-Date" },
163
        /* MMS 1.2 */
164
        { MM_STORE_HDR,                 "X-Mms-Store" },
165
        { MM_MM_STATE_HDR,              "X-Mms-MM-State" },
166
        { MM_MM_FLAGS_HDR,              "X-Mms-MM-Flags" },
167
        { MM_STORE_STATUS_HDR,          "X-Mms-Store-Status" },
168
        { MM_STORE_STATUS_TEXT_HDR,     "X-Mms-Store-Status-Text" },
169
        { MM_STORED_HDR,                "X-Mms-Stored" },
170
        { MM_ATTRIBUTES_HDR,            "X-Mms-Attributes" },
171
        { MM_TOTALS_HDR,                "X-Mms-Totals" },
172
        { MM_MBOX_TOTALS_HDR,           "X-Mms-Mbox-Totals" },
173
        { MM_QUOTAS_HDR,                "X-Mms-Quotas" },
174
        { MM_MBOX_QUOTAS_HDR,           "X-Mms-Mbox-Quotas" },
175
        { MM_MBOX_MSG_COUNT_HDR,        "X-Mms-Message-Count" },
176
        { MM_CONTENT_HDR,               "Content" },
177
        { MM_START_HDR,                 "X-Mms-Start" },
178
        { MM_ADDITIONAL_HDR,            "Additional-headers" },
179
        { MM_DISTRIBUION_IND_HDR,       "X-Mms-Distribution-Indicator" },
180
        { MM_ELEMENT_DESCR_HDR,         "X-Mms-Element-Descriptor" },
181
        { MM_LIMIT_HDR,                 "X-Mms-Limit" },
182
183
        { 0x00, NULL },
184
};
185
/*
186
 * Initialize the protocol and registered fields
187
 */
188
static int proto_mmse;
189
190
static int hf_mmse_message_type;
191
static int hf_mmse_transaction_id;
192
static int hf_mmse_mms_version;
193
static int hf_mmse_bcc;
194
static int hf_mmse_cc;
195
static int hf_mmse_content_location;
196
static int hf_mmse_date;
197
static int hf_mmse_delivery_report;
198
static int hf_mmse_delivery_time_abs;
199
static int hf_mmse_delivery_time_rel;
200
static int hf_mmse_expiry_abs;
201
static int hf_mmse_expiry_rel;
202
static int hf_mmse_from;
203
static int hf_mmse_message_class_id;
204
static int hf_mmse_message_class_str;
205
static int hf_mmse_message_id;
206
static int hf_mmse_message_size;
207
static int hf_mmse_priority;
208
static int hf_mmse_read_reply;
209
static int hf_mmse_report_allowed;
210
static int hf_mmse_response_status;
211
static int hf_mmse_response_text;
212
static int hf_mmse_sender_visibility;
213
static int hf_mmse_status;
214
static int hf_mmse_subject;
215
static int hf_mmse_to;
216
/* static int hf_mmse_content_type; */
217
static int hf_mmse_ffheader;
218
/* MMSE 1.1 */
219
static int hf_mmse_read_report;
220
static int hf_mmse_retrieve_status;
221
static int hf_mmse_retrieve_text;
222
static int hf_mmse_read_status;
223
static int hf_mmse_reply_charging;
224
static int hf_mmse_reply_charging_deadline_abs;
225
static int hf_mmse_reply_charging_deadline_rel;
226
static int hf_mmse_reply_charging_id;
227
static int hf_mmse_reply_charging_size;
228
static int hf_mmse_prev_sent_by;
229
static int hf_mmse_prev_sent_by_fwd_count;
230
static int hf_mmse_prev_sent_by_address;
231
static int hf_mmse_prev_sent_date;
232
static int hf_mmse_prev_sent_date_fwd_count;
233
static int hf_mmse_prev_sent_date_date;
234
static int hf_mmse_header_uint;
235
static int hf_mmse_header_string;
236
static int hf_mmse_header_bytes;
237
238
/*
239
 * Initialize the subtree pointers
240
 */
241
static int ett_mmse;
242
static int ett_mmse_hdr_details;
243
244
static expert_field ei_mmse_oversized_uintvar;
245
246
/*
247
 * Valuestrings for PDU types
248
 */
249
/* MMS 1.0 */
250
0
#define PDU_M_SEND_REQ          0x80
251
#define PDU_M_SEND_CONF         0x81
252
#define PDU_M_NOTIFICATION_IND  0x82
253
#define PDU_M_NOTIFYRESP_IND    0x83
254
0
#define PDU_M_RETRIEVE_CONF     0x84
255
#define PDU_M_ACKNOWLEDGE_IND   0x85
256
0
#define PDU_M_DELIVERY_IND      0x86
257
/* MMS 1.1 */
258
#define PDU_M_READ_REC_IND      0x87
259
#define PDU_M_READ_ORIG_IND     0x88
260
#define PDU_M_FORWARD_REQ       0x89
261
#define PDU_M_FORWARD_CONF      0x8A
262
/* MMS 1.2 */
263
#define PDU_M_MBOX_STORE_REQ    0x8B
264
#define PDU_M_MBOX_STORE_CONF   0x8C
265
#define PDU_M_MBOX_VIEW_REQ     0x8D
266
0
#define PDU_M_MBOX_VIEW_CONF    0x8E
267
0
#define PDU_M_MBOX_UPLOAD_REQ   0x8F
268
#define PDU_M_MBOX_UPLOAD_CONF  0x90
269
#define PDU_M_MBOX_DELETE_REQ   0x91
270
99
#define PDU_M_MBOX_DELETE_CONF  0x92
271
0
#define PDU_M_MBOX_DESCR        0x93
272
273
#define pdu_has_content(pdut) \
274
0
        (  ((pdut) == PDU_M_SEND_REQ) \
275
0
        || ((pdut) == PDU_M_DELIVERY_IND) \
276
0
        || ((pdut) == PDU_M_RETRIEVE_CONF) \
277
0
        || ((pdut) == PDU_M_MBOX_VIEW_CONF) \
278
0
        || ((pdut) == PDU_M_MBOX_DESCR) \
279
0
        || ((pdut) == PDU_M_MBOX_UPLOAD_REQ) \
280
0
        )
281
282
static const value_string vals_message_type[] = {
283
    /* MMS 1.0 */
284
    { PDU_M_SEND_REQ,           "m-send-req" },
285
    { PDU_M_SEND_CONF,          "m-send-conf" },
286
    { PDU_M_NOTIFICATION_IND,   "m-notification-ind" },
287
    { PDU_M_NOTIFYRESP_IND,     "m-notifyresp-ind" },
288
    { PDU_M_RETRIEVE_CONF,      "m-retrieve-conf" },
289
    { PDU_M_ACKNOWLEDGE_IND,    "m-acknowledge-ind" },
290
    { PDU_M_DELIVERY_IND,       "m-delivery-ind" },
291
    /* MMS 1.1 */
292
    { PDU_M_READ_REC_IND,       "m-read-rec-ind" },
293
    { PDU_M_READ_ORIG_IND,      "m-read-orig-ind" },
294
    { PDU_M_FORWARD_REQ,        "m-forward-req" },
295
    { PDU_M_FORWARD_CONF,       "m-forward-conf" },
296
    /* MMS 1.2 */
297
    { PDU_M_MBOX_STORE_REQ,     "m-mbox-store-req" },
298
    { PDU_M_MBOX_STORE_CONF,    "m-mbox-store-conf" },
299
    { PDU_M_MBOX_VIEW_REQ,      "m-mbox-view-req" },
300
    { PDU_M_MBOX_VIEW_CONF,     "m-mbox-view-conf" },
301
    { PDU_M_MBOX_UPLOAD_REQ,    "m-mbox-upload-req" },
302
    { PDU_M_MBOX_UPLOAD_CONF,   "m-mbox-upload-conf" },
303
    { PDU_M_MBOX_DELETE_REQ,    "m-mbox-delete-req" },
304
    { PDU_M_MBOX_DELETE_CONF,   "m-mbox-delete-conf" },
305
    { PDU_M_MBOX_DESCR,         "m-mbox-descr" },
306
    { 0x00, NULL },
307
};
308
309
static const value_string vals_yes_no[] = {
310
    { 0x80, "Yes" },
311
    { 0x81, "No" },
312
    { 0x00, NULL },
313
};
314
315
static const value_string vals_message_class[] = {
316
    { 0x80, "Personal" },
317
    { 0x81, "Advertisement" },
318
    { 0x82, "Informational" },
319
    { 0x83, "Auto" },
320
    { 0x00, NULL },
321
};
322
323
static const value_string vals_priority[] = {
324
    { 0x80, "Low" },
325
    { 0x81, "Normal" },
326
    { 0x82, "High" },
327
    { 0x00, NULL },
328
};
329
330
static const value_string vals_response_status[] = {
331
    /* MMS 1.0 - obsolete as from MMS 1.1 */
332
    { 0x80, "Ok" },
333
    { 0x81, "Unspecified" },
334
    { 0x82, "Service denied" },
335
    { 0x83, "Message format corrupt" },
336
    { 0x84, "Sending address unresolved" },
337
    { 0x85, "Message not found" },
338
    { 0x86, "Network problem" },
339
    { 0x87, "Content not accepted" },
340
    { 0x88, "Unsupported message" },
341
342
    /*
343
     * Transient errors
344
     */
345
    /* MMS 1.1 */
346
    { 0xC0, "Transient failure" },
347
    { 0xC1, "Transient: Sending address unresolved" },
348
    { 0xC2, "Transient: Message not found" },
349
    { 0xC3, "Transient: Network problem" },
350
    /* MMS 1.2 */
351
    { 0xC4, "Transient: Partial success" },
352
353
    /*
354
     * Permanent errors
355
     */
356
    /* MMS 1.1 */
357
    { 0xE0, "Permanent failure" },
358
    { 0xE1, "Permanent: Service denied" },
359
    { 0xE2, "Permanent: Message format corrupt" },
360
    { 0xE3, "Permanent: Sending address unresolved" },
361
    { 0xE4, "Permanent: Message not found" },
362
    { 0xE5, "Permanent: Content not accepted" },
363
    { 0xE6, "Permanent: Reply charging limitations not met" },
364
    { 0xE7, "Permanent: Reply charging request not accepted" },
365
    { 0xE8, "Permanent: Reply charging forwarding denied" },
366
    { 0xE9, "Permanent: Reply charging not supported" },
367
    /* MMS 1.2 */
368
    { 0xEA, "Permanent: Address hiding not supported" },
369
370
    { 0x00, NULL },
371
};
372
373
static const value_string vals_sender_visibility[] = {
374
    { 0x80, "Hide" },
375
    { 0x81, "Show" },
376
    { 0x00, NULL },
377
};
378
379
static const value_string vals_message_status[] = {
380
    /* MMS 1.0 */
381
    { 0x80, "Expired" },
382
    { 0x81, "Retrieved" },
383
    { 0x82, "Rejected" },
384
    { 0x83, "Deferred" },
385
    { 0x84, "Unrecognized" },
386
    /* MMS 1.1 */
387
    { 0x85, "Indeterminate" },
388
    { 0x86, "Forwarded" },
389
    /* MMS 1.2 */
390
    { 0x87, "Unreachable" },
391
392
    { 0x00, NULL },
393
};
394
395
static const value_string vals_retrieve_status[] = {
396
    /* MMS 1.1 */
397
    { 0x80, "Ok" },
398
399
    /*
400
     * Transient errors
401
     */
402
    /* MMS 1.1 */
403
    { 0xC0, "Transient failure" },
404
    { 0xC1, "Transient: Message not found" },
405
    { 0xC2, "Transient: Network problem" },
406
407
    /*
408
     * Permanent errors
409
     */
410
    /* MMS 1.1 */
411
    { 0xE0, "Permanent failure" },
412
    { 0xE1, "Permanent: Service denied" },
413
    { 0xE2, "Permanent: Message not found" },
414
    { 0xE3, "Permanent: Content unsupported" },
415
416
    { 0x00, NULL },
417
};
418
419
static const value_string vals_read_status[] = {
420
    { 0x80, "Read" },
421
    { 0x81, "Deleted without being read" },
422
423
    { 0x00, NULL },
424
};
425
426
static const value_string vals_reply_charging[] = {
427
    { 0x80, "Requested" },
428
    { 0x81, "Requested text only" },
429
    { 0x82, "Accepted" },
430
    { 0x83, "Accepted text only" },
431
432
    { 0x00, NULL },
433
};
434
435
/*!
436
 * Decodes a Text-string from the protocol data
437
 *      Text-string = [Quote] *TEXT End-of-string
438
 *      Quote       = <Octet 127>
439
 *      End-of-string = <Octet 0>
440
 *
441
 * \todo Shouldn't we be sharing this with WSP (packet-wap.c)?
442
 *
443
 * \param       tvb     The buffer with PDU-data
444
 * \param       offset  Offset within that buffer
445
 * \param       pool    wmem allocation pool from which to allocate
446
 *                      memory for strval
447
 * \param       strval  Pointer to variable into which to put pointer to
448
 *                      buffer allocated to hold the text; must be freed
449
 *                      when no longer used
450
 *
451
 * \return              The length in bytes of the entire field
452
 */
453
static unsigned
454
get_text_string(tvbuff_t *tvb, unsigned offset, wmem_allocator_t *pool, const char **strval)
455
17.4k
{
456
17.4k
    unsigned len;
457
458
17.4k
    DebugLog(("get_text_string(tvb = %p, offset = %u, **strval) - start\n",
459
17.4k
                tvb, offset));
460
    /* OMA-TS-MMS-CONF says that Text-string encoding is always US-ASCII.
461
     * (In other WSP protocols it might be the document encoding.)
462
     * It is allowed to be Base64 or Quoted-Printable encoded, but
463
     * we won't bother with that.
464
     */
465
17.4k
    if (tvb_get_uint8(tvb, offset) == MM_QUOTE) {
466
47
        *strval = (const char *)tvb_get_stringz_enc(pool, tvb, offset+1, &len, ENC_ASCII);
467
47
        len += 1;
468
17.3k
    } else {
469
17.3k
        *strval = (const char *)tvb_get_stringz_enc(pool, tvb, offset, &len, ENC_ASCII);
470
17.3k
    }
471
17.4k
    DebugLog((" [3] Return(len) == %u\n", len));
472
17.4k
    return len;
473
17.4k
}
474
475
/*!
476
 * Decodes a Value-length from the protocol data.
477
 *      Value-length = Short-length | (Length-quote Length)
478
 *      Short-length = <Any octet 0-30>
479
 *      Length-quote = <Octet 31>
480
 *      Length       = Uintvar-integer
481
 *
482
 * \todo Shouldn't we be sharing this with WSP (packet-wap.c)?
483
 *
484
 * \param       tvb             The buffer with PDU-data
485
 * \param       offset          Offset within that buffer
486
 * \param       byte_count      Returns the length in bytes of
487
 *                              the "Value-length" field.
488
 * \param       pinfo           packet_info structure
489
 *
490
 * \return                      The actual value of "Value-length"
491
 */
492
static unsigned
493
get_value_length(tvbuff_t *tvb, unsigned offset, unsigned *byte_count, packet_info *pinfo)
494
691
{
495
691
    unsigned     field;
496
497
691
    field = tvb_get_uint8(tvb, offset++);
498
691
    if (field < 31)
499
489
        *byte_count = 1;
500
202
    else {                      /* Must be 31 so, Uintvar follows       */
501
202
        field = tvb_get_uintvar(tvb, offset, byte_count, pinfo, &ei_mmse_oversized_uintvar);
502
202
        (*byte_count)++;
503
202
    }
504
505
    /* The packet says there are this many bytes; ensure they're there.
506
     * We do this here because several callers do math on the length we
507
     * return here and may not catch an overflow.
508
     */
509
691
    tvb_ensure_bytes_exist(tvb, offset, field);
510
691
    return field;
511
691
}
512
513
/*!
514
 * Decodes a Long-integer from the protocol data
515
 *      Long-integer = Short-length Multi-octet-integer
516
 *      Short-length = <Any octet 0-30>
517
 *      Multi-octet-integer = 1*30OCTET
518
 *
519
 * \todo Shouldn't we be sharing this with WSP (packet-wap.c)?
520
 *
521
 * \param       tvb             The buffer with PDU-data
522
 * \param       offset          Offset within that buffer
523
 * \param       byte_count      Returns the length in bytes of the field
524
 *
525
 * \return                      The value of the Long-integer
526
 *
527
 * \note        A maximum of 4-byte integers will be handled.
528
 */
529
static unsigned
530
get_long_integer(tvbuff_t *tvb, unsigned offset, unsigned *byte_count)
531
262
{
532
262
    unsigned     val;
533
534
262
    *byte_count = tvb_get_uint8(tvb, offset++);
535
262
    switch (*byte_count) {
536
20
        case 1:
537
20
            val = tvb_get_uint8(tvb, offset);
538
20
            break;
539
15
        case 2:
540
15
            val = tvb_get_ntohs(tvb, offset);
541
15
            break;
542
32
        case 3:
543
32
            val = tvb_get_ntoh24(tvb, offset);
544
32
            break;
545
8
        case 4:
546
8
            val = tvb_get_ntohl(tvb, offset);
547
8
            break;
548
186
        default:
549
186
            val = 0;
550
186
            break;
551
262
    }
552
260
    (*byte_count)++;
553
260
    return val;
554
262
}
555
556
/*!
557
 * Decodes an Integer-value from the protocol data
558
 *      Integer-value = Short-integer | Long-integer
559
 *      Short-integer = OCTET
560
 *      Long-integer = Short-length Multi-octet-integer
561
 *      Short-length = <Any octet 0-30>
562
 *      Multi-octet-integer = 1*30OCTET
563
 *
564
 * \todo Shouldn't we be sharing this with WSP (packet-wap.c)?
565
 *
566
 * \param       tvb             The buffer with PDU-data
567
 * \param       offset          Offset within that buffer
568
 * \param       byte_count      Returns the length in bytes of the field
569
 *
570
 * \return                      The value of the Long-integer
571
 *
572
 * \note        A maximum of 4-byte integers will be handled.
573
 */
574
static unsigned
575
get_integer_value(tvbuff_t *tvb, unsigned offset, unsigned *byte_count)
576
287
{
577
287
    unsigned     val;
578
287
    uint8_t peek;
579
580
287
    peek = tvb_get_uint8(tvb, offset++);
581
287
    if (peek & 0x80) {
582
135
        val = peek & 0x7F;
583
135
        *byte_count = 1;
584
135
        return val;
585
152
    } else {
586
152
        *byte_count = peek;
587
152
        switch (peek) {
588
38
        case 1:
589
38
            val = tvb_get_uint8(tvb, offset);
590
38
            break;
591
10
        case 2:
592
10
            val = tvb_get_ntohs(tvb, offset);
593
10
            break;
594
15
        case 3:
595
15
            val = tvb_get_ntoh24(tvb, offset);
596
15
            break;
597
10
        case 4:
598
10
            val = tvb_get_ntohl(tvb, offset);
599
10
            break;
600
77
        default:
601
77
            val = 0;
602
77
            break;
603
152
        }
604
152
    }
605
150
    (*byte_count)++;
606
150
    return val;
607
287
}
608
609
/*!
610
 * Decodes an Encoded-string-value from the protocol data
611
 *      Encoded-string-value = Text-string | Value-length Char-set Text-string
612
 *
613
 * \param       tvb     The buffer with PDU-data
614
 * \param       offset  Offset within that buffer
615
 * \param       strval  Pointer to variable into which to put pointer to
616
 *                      buffer allocated to hold the text; must be freed
617
 *                      when no longer used
618
 *
619
 * \return              The length in bytes of the entire field
620
 */
621
static unsigned
622
get_encoded_strval(tvbuff_t *tvb, unsigned offset, const char **strval, packet_info *pinfo)
623
559
{
624
559
    unsigned     field;
625
559
    unsigned     length;
626
559
    unsigned     count, count1;
627
559
    unsigned     charset;
628
629
559
    field = tvb_get_uint8(tvb, offset);
630
631
559
    if (field < 32) {
632
333
        length = get_value_length(tvb, offset, &count, pinfo);
633
333
        if (length < 2) {
634
131
            *strval = "";
635
202
        } else {
636
            /* OMA-TS-MMS-CONF says that char-set is encoded as an integer
637
             * value, so don't bother to handle the string case. */
638
202
            field = tvb_get_uint8(tvb, offset + count);
639
202
            if ((field < 32) | (field & 0x80)) {
640
151
                charset = get_integer_value(tvb, offset + count, &count1);
641
151
                *strval = (char *)tvb_get_string_enc(pinfo->pool, tvb, offset + count + count1, length - count1, mibenum_charset_to_encoding(charset));
642
151
            } else {
643
51
                *strval = (char *)tvb_get_string_enc(pinfo->pool, tvb, offset + count, length, ENC_ASCII);
644
51
            }
645
202
        }
646
333
        return count + length;
647
333
    } else
648
226
        return get_text_string(tvb, offset, pinfo->pool, strval);
649
559
}
650
651
/* Code to actually dissect the packets */
652
static bool
653
dissect_mmse_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
654
524
{
655
524
    uint8_t      pdut;
656
657
524
        DebugLog(("dissect_mmse_heur()\n"));
658
    /*
659
     * Check if data makes sense for it to be dissected as MMSE:  Message-type
660
     * field must make sense and followed by either Transaction-Id
661
     * or MMS-Version header
662
     */
663
524
    if (tvb_get_uint8(tvb, 0) != MM_MTYPE_HDR)
664
512
        return false;
665
12
    pdut = tvb_get_uint8(tvb, 1);
666
12
    if (try_val_to_str(pdut, vals_message_type) == NULL)
667
2
        return false;
668
10
    if ((tvb_get_uint8(tvb, 2) != MM_TID_HDR) &&
669
2
        (tvb_get_uint8(tvb, 2) != MM_VERSION_HDR))
670
1
        return false;
671
9
    dissect_mmse_standalone(tvb, pinfo, tree, data);
672
9
    return true;
673
10
}
674
675
static int
676
dissect_mmse_standalone(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
677
414
{
678
414
    uint8_t      pdut;
679
414
    const char   *message_type;
680
681
414
    DebugLog(("dissect_mmse_standalone() - START (Packet %u)\n",
682
414
                pinfo->num));
683
684
414
    pdut = tvb_get_uint8(tvb, 1);
685
414
    message_type = val_to_str(pinfo->pool, pdut, vals_message_type, "Unknown type %u");
686
687
    /* Make entries in Protocol column and Info column on summary display */
688
414
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "MMSE");
689
414
    col_add_fstr(pinfo->cinfo, COL_INFO, "MMS %s", message_type);
690
691
414
    dissect_mmse(tvb, pinfo, tree, pdut, message_type);
692
414
    return tvb_captured_length(tvb);
693
414
}
694
695
static int
696
dissect_mmse_encapsulated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
697
0
{
698
0
    uint8_t      pdut;
699
0
    const char   *message_type;
700
701
0
    DebugLog(("dissect_mmse_encapsulated() - START (Packet %u)\n",
702
0
                pinfo->num));
703
704
0
    pdut = tvb_get_uint8(tvb, 1);
705
0
    message_type = val_to_str(pinfo->pool, pdut, vals_message_type, "Unknown type %u");
706
707
    /* Make entries in Info column on summary display */
708
0
    col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "(MMS %s)", message_type);
709
710
0
    dissect_mmse(tvb, pinfo, tree, pdut, message_type);
711
0
    return tvb_captured_length(tvb);
712
0
}
713
714
static void
715
dissect_mmse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint8_t pdut,
716
        const char *message_type)
717
413
{
718
413
    unsigned     offset, old_offset;
719
413
    uint8_t      field = 0;
720
413
    const char   *strval;
721
413
    unsigned     length;
722
413
    unsigned     count;
723
413
    uint8_t      version = 0x80; /* Default to MMSE 1.0 */
724
725
    /* Set up structures needed to add the protocol subtree and manage it */
726
413
    proto_item  *ti = NULL;
727
413
    proto_tree  *mmse_tree = NULL;
728
729
413
    DebugLog(("dissect_mmse() - START (Packet %u)\n", pinfo->num));
730
731
413
    ti = proto_tree_add_item(tree, proto_mmse, tvb, 0, -1, ENC_NA);
732
413
    proto_item_append_text(ti, ", Type: %s", message_type);
733
    /* create display subtree for the protocol */
734
413
    mmse_tree = proto_item_add_subtree(ti, ett_mmse);
735
736
    /* Report PDU-type      */
737
413
    proto_tree_add_uint(mmse_tree, hf_mmse_message_type, tvb, 0, 2, pdut);
738
739
413
    offset = 2;                 /* Skip Message-Type    */
740
413
    old_offset = 1;
741
742
    /*
743
     * Cycle through MMS-headers
744
     *
745
     * NOTE - some PDUs may convey content that can be handed off
746
     *        to subdissectors.
747
     */
748
413
    if (tree == NULL && !pdu_has_content(pdut)) {
749
0
        DebugLog(("tree == NULL and PDU has no potential content\n"));
750
0
        return;
751
0
    }
752
753
13.6k
    while ((offset < tvb_reported_length(tvb)) &&
754
13.5k
            (field = tvb_get_uint8(tvb, offset++)) != MM_CTYPE_HDR)
755
13.4k
    {
756
13.4k
        DebugLog(("\tField =  0x%02X (offset = %u): %s\n",
757
13.4k
                    field, offset,
758
13.4k
                    val_to_str(pinfo->pool, field, vals_mm_header_names,
759
13.4k
                        "Unknown MMS header 0x%02X")));
760
13.4k
        switch (field)
761
13.4k
        {
762
12
            case MM_TID_HDR:                /* Text-string  */
763
12
                length = get_text_string(tvb, offset, pinfo->pool, &strval);
764
12
                proto_tree_add_string(mmse_tree, hf_mmse_transaction_id,
765
12
                        tvb, offset - 1, length + 1,strval);
766
12
                offset += length;
767
12
                break;
768
153
            case MM_VERSION_HDR:            /* nibble-Major/nibble-minor*/
769
153
                {
770
153
                    uint8_t  major, minor;
771
153
                    char    *vers_string;
772
773
153
                    version = tvb_get_uint8(tvb, offset++);
774
153
                    major = (version & 0x70) >> 4;
775
153
                    minor = version & 0x0F;
776
153
                    if (minor == 0x0F)
777
19
                        vers_string = wmem_strdup_printf(pinfo->pool, "%u", major);
778
134
                    else
779
134
                        vers_string = wmem_strdup_printf(pinfo->pool, "%u.%u", major, minor);
780
153
                    proto_tree_add_string(mmse_tree, hf_mmse_mms_version,
781
153
                            tvb, offset - 2, 2, vers_string);
782
153
                }
783
153
                break;
784
75
            case MM_BCC_HDR:                /* Encoded-string-value */
785
75
                length = get_encoded_strval(tvb, offset, &strval, pinfo);
786
75
                proto_tree_add_string(mmse_tree, hf_mmse_bcc, tvb,
787
75
                        offset - 1, length + 1, strval);
788
75
                offset += length;
789
75
                break;
790
172
            case MM_CC_HDR:                 /* Encoded-string-value */
791
172
                length = get_encoded_strval(tvb, offset, &strval, pinfo);
792
172
                proto_tree_add_string(mmse_tree, hf_mmse_cc, tvb,
793
172
                        offset - 1, length + 1, strval);
794
172
                offset += length;
795
172
                break;
796
30
            case MM_CLOCATION_HDR:          /* Uri-value            */
797
30
                if (pdut == PDU_M_MBOX_DELETE_CONF) {
798
                    /* General form with length */
799
6
                    length = tvb_get_uint8(tvb, offset);
800
6
                    if (length == 0x1F) {
801
0
                        unsigned length_len = 0;
802
0
                        length = tvb_get_uintvar(tvb, offset + 1,
803
0
                                &length_len, pinfo, &ei_mmse_oversized_uintvar);
804
0
                        length += 1 + length_len;
805
6
                    } else {
806
6
                        length += 1;
807
6
                    }
808
6
                    proto_tree_add_string(mmse_tree,
809
6
                            hf_mmse_content_location,
810
6
                            tvb, offset - 1, length + 1,
811
6
                            "<Undecoded value for m-mbox-delete-conf>");
812
24
                } else {
813
24
                    length = get_text_string(tvb, offset, pinfo->pool, &strval);
814
24
                    proto_tree_add_string(mmse_tree,
815
24
                            hf_mmse_content_location,
816
24
                            tvb, offset - 1, length + 1, strval);
817
24
                }
818
30
                offset += length;
819
30
                break;
820
21
            case MM_DATE_HDR:               /* Long-integer         */
821
21
                {
822
21
                    unsigned         tval;
823
21
                    nstime_t         tmptime;
824
825
21
                    tval = get_long_integer(tvb, offset, &count);
826
21
                    tmptime.secs = tval;
827
21
                    tmptime.nsecs = 0;
828
21
                    proto_tree_add_time(mmse_tree, hf_mmse_date, tvb,
829
21
                            offset - 1, count + 1, &tmptime);
830
21
                }
831
21
                offset += count;
832
21
                break;
833
257
            case MM_DREPORT_HDR:            /* Yes|No               */
834
257
                field = tvb_get_uint8(tvb, offset++);
835
257
                proto_tree_add_uint(mmse_tree,
836
257
                        hf_mmse_delivery_report,
837
257
                        tvb, offset - 2, 2, field);
838
257
                break;
839
23
            case MM_DTIME_HDR:
840
23
                {
841
23
                    unsigned         tval;
842
23
                    nstime_t         tmptime;
843
23
                    unsigned         cnt;
844
845
                    /*
846
                     * Value-length(Absolute-token Date-value|
847
                     *              Relative-token Delta-seconds-value)
848
                     */
849
23
                    length = get_value_length(tvb, offset, &count, pinfo);
850
23
                    field = tvb_get_uint8(tvb, offset + count);
851
852
23
                    tval =  get_long_integer(tvb, offset + count + 1, &cnt);
853
23
                    tmptime.secs = tval;
854
23
                    tmptime.nsecs = 0;
855
856
23
                    if (field == 0x80)
857
1
                        proto_tree_add_time(mmse_tree,
858
1
                                hf_mmse_delivery_time_abs,
859
1
                                tvb, offset - 1,
860
1
                                length + count + 1, &tmptime);
861
22
                    else
862
22
                        proto_tree_add_time(mmse_tree,
863
22
                                hf_mmse_delivery_time_rel,
864
22
                                tvb, offset - 1,
865
22
                                length + count + 1, &tmptime);
866
23
                }
867
23
                offset += length + count;
868
23
                break;
869
60
            case MM_EXPIRY_HDR:
870
60
                {
871
60
                    unsigned         tval;
872
60
                    nstime_t         tmptime;
873
60
                    unsigned         cnt;
874
875
                    /*
876
                     * Value-length(Absolute-token Date-value|
877
                     *              Relative-token Delta-seconds-value)
878
                     */
879
60
                    length = get_value_length(tvb, offset, &count, pinfo);
880
60
                    field = tvb_get_uint8(tvb, offset + count);
881
882
60
                    tval = get_long_integer(tvb, offset + count + 1, &cnt);
883
60
                    tmptime.secs = tval;
884
60
                    tmptime.nsecs = 0;
885
886
60
                    if (field == 0x80)
887
1
                        proto_tree_add_time(mmse_tree, hf_mmse_expiry_abs,
888
1
                                tvb, offset - 1,
889
1
                                length + count + 1, &tmptime);
890
59
                    else
891
59
                        proto_tree_add_time(mmse_tree, hf_mmse_expiry_rel,
892
59
                                tvb, offset - 1,
893
59
                                length + count + 1, &tmptime);
894
60
                }
895
60
                offset += length + count;
896
60
                break;
897
110
            case MM_FROM_HDR:
898
                /*
899
                 * Value-length(Address-present-token Encoded-string-value
900
                 *              |Insert-address-token)
901
                 */
902
110
                length = get_value_length(tvb, offset, &count, pinfo);
903
110
                field = tvb_get_uint8(tvb, offset + count);
904
110
                if (field == 0x81) {
905
1
                    proto_tree_add_string(mmse_tree, hf_mmse_from, tvb,
906
1
                            offset-1, length + count + 1,
907
1
                            "<insert address>");
908
109
                } else {
909
109
                    (void) get_encoded_strval(tvb, offset + count + 1,
910
109
                            &strval, pinfo);
911
109
                    proto_tree_add_string(mmse_tree, hf_mmse_from, tvb,
912
109
                            offset-1, length + count + 1, strval);
913
109
                }
914
110
                offset += length + count;
915
110
                break;
916
181
            case MM_MCLASS_HDR:
917
                /*
918
                 * Class-identifier|Text-string
919
                 */
920
181
                field = tvb_get_uint8(tvb, offset);
921
181
                if (field & 0x80) {
922
161
                    offset++;
923
161
                    proto_tree_add_uint(mmse_tree,
924
161
                            hf_mmse_message_class_id,
925
161
                            tvb, offset - 2, 2, field);
926
161
                } else {
927
20
                    length = get_text_string(tvb, offset, pinfo->pool, &strval);
928
20
                    proto_tree_add_string(mmse_tree,
929
20
                            hf_mmse_message_class_str,
930
20
                            tvb, offset - 1, length + 1,
931
20
                            strval);
932
20
                    offset += length;
933
20
                }
934
181
                break;
935
18
            case MM_MID_HDR:                /* Text-string          */
936
18
                length = get_text_string(tvb, offset, pinfo->pool, &strval);
937
18
                proto_tree_add_string(mmse_tree, hf_mmse_message_id,
938
18
                        tvb, offset - 1, length + 1, strval);
939
18
                offset += length;
940
18
                break;
941
48
            case MM_MSIZE_HDR:              /* Long-integer         */
942
48
                length = get_long_integer(tvb, offset, &count);
943
48
                proto_tree_add_uint(mmse_tree, hf_mmse_message_size,
944
48
                        tvb, offset - 1, count + 1, length);
945
48
                offset += count;
946
48
                break;
947
122
            case MM_PRIORITY_HDR:           /* Low|Normal|High      */
948
122
                field = tvb_get_uint8(tvb, offset++);
949
122
                proto_tree_add_uint(mmse_tree, hf_mmse_priority, tvb,
950
122
                        offset - 2, 2, field);
951
122
                break;
952
174
            case MM_RREPLY_HDR:             /* Yes|No               */
953
174
                field = tvb_get_uint8(tvb, offset++);
954
174
                if (version == 0x80) { /* MMSE 1.0 */
955
93
                    proto_tree_add_uint(mmse_tree, hf_mmse_read_reply,
956
93
                            tvb, offset - 2, 2, field);
957
93
                } else {
958
81
                    proto_tree_add_uint(mmse_tree, hf_mmse_read_report,
959
81
                            tvb, offset - 2, 2, field);
960
81
                }
961
174
                break;
962
115
            case MM_RALLOWED_HDR:           /* Yes|No               */
963
115
                field = tvb_get_uint8(tvb, offset++);
964
115
                proto_tree_add_uint(mmse_tree, hf_mmse_report_allowed,
965
115
                        tvb, offset - 2, 2, field);
966
115
                break;
967
173
            case MM_RSTATUS_HDR:
968
173
                field = tvb_get_uint8(tvb, offset++);
969
173
                proto_tree_add_uint(mmse_tree, hf_mmse_response_status,
970
173
                        tvb, offset - 2, 2, field);
971
173
                break;
972
21
            case MM_RTEXT_HDR:              /* Encoded-string-value */
973
21
                if (pdut == PDU_M_MBOX_DELETE_CONF) {
974
                    /* General form with length */
975
0
                    length = tvb_get_uint8(tvb, offset);
976
0
                    if (length == 0x1F) {
977
0
                        unsigned length_len = 0;
978
0
                        length = tvb_get_uintvar(tvb, offset + 1,
979
0
                                &length_len, pinfo, &ei_mmse_oversized_uintvar);
980
0
                        length += 1 + length_len;
981
0
                    } else {
982
0
                        length += 1;
983
0
                    }
984
0
                    proto_tree_add_string(mmse_tree,
985
0
                            hf_mmse_content_location,
986
0
                            tvb, offset - 1, length + 1,
987
0
                            "<Undecoded value for m-mbox-delete-conf>");
988
21
                } else {
989
21
                    length = get_encoded_strval(tvb, offset, &strval, pinfo);
990
21
                    proto_tree_add_string(mmse_tree,
991
21
                            hf_mmse_response_text, tvb, offset - 1,
992
21
                            length + 1, strval);
993
21
                }
994
21
                offset += length;
995
21
                break;
996
95
            case MM_SVISIBILITY_HDR:        /* Hide|Show            */
997
95
                field = tvb_get_uint8(tvb, offset++);
998
95
                proto_tree_add_uint(mmse_tree,hf_mmse_sender_visibility,
999
95
                        tvb, offset - 2, 2, field);
1000
95
                break;
1001
145
            case MM_STATUS_HDR:
1002
145
                field = tvb_get_uint8(tvb, offset++);
1003
145
                proto_tree_add_uint(mmse_tree, hf_mmse_status, tvb,
1004
145
                        offset - 2, 2, field);
1005
145
                break;
1006
40
            case MM_SUBJECT_HDR:            /* Encoded-string-value */
1007
40
                length = get_encoded_strval(tvb, offset, &strval, pinfo);
1008
40
                proto_tree_add_string(mmse_tree, hf_mmse_subject, tvb,
1009
40
                        offset - 1, length + 1, strval);
1010
40
                offset += length;
1011
40
                break;
1012
37
            case MM_TO_HDR:                 /* Encoded-string-value */
1013
37
                length = get_encoded_strval(tvb, offset, &strval, pinfo);
1014
37
                proto_tree_add_string(mmse_tree, hf_mmse_to, tvb,
1015
37
                        offset - 1, length + 1, strval);
1016
37
                offset += length;
1017
37
                break;
1018
1019
                /*
1020
                 * MMS Encapsulation 1.1
1021
                 */
1022
93
            case MM_RETRIEVE_STATUS_HDR:    /* Well-known-value */
1023
93
                field = tvb_get_uint8(tvb, offset++);
1024
93
                proto_tree_add_uint(mmse_tree, hf_mmse_retrieve_status,
1025
93
                        tvb, offset - 2, 2, field);
1026
93
                break;
1027
48
            case MM_RETRIEVE_TEXT_HDR:
1028
48
                if (pdut == PDU_M_MBOX_DELETE_CONF) {
1029
                    /* General form with length */
1030
3
                    length = tvb_get_uint8(tvb, offset);
1031
3
                    if (length == 0x1F) {
1032
0
                        unsigned length_len = 0;
1033
0
                        length = tvb_get_uintvar(tvb, offset + 1,
1034
0
                                &length_len, pinfo, &ei_mmse_oversized_uintvar);
1035
0
                        length += 1 + length_len;
1036
3
                    } else {
1037
3
                        length += 1;
1038
3
                    }
1039
1040
3
                    proto_tree_add_string(mmse_tree,
1041
3
                            hf_mmse_content_location,
1042
3
                            tvb, offset - 1, length + 1,
1043
3
                            "<Undecoded value for m-mbox-delete-conf>");
1044
45
                } else {
1045
                    /* Encoded-string-value */
1046
45
                    length = get_encoded_strval(tvb, offset, &strval, pinfo);
1047
45
                    proto_tree_add_string(mmse_tree,
1048
45
                            hf_mmse_retrieve_text, tvb, offset - 1,
1049
45
                            length + 1, strval);
1050
45
                }
1051
48
                offset += length;
1052
48
                break;
1053
247
            case MM_READ_STATUS_HDR:        /* Well-known-value */
1054
247
                field = tvb_get_uint8(tvb, offset++);
1055
247
                proto_tree_add_uint(mmse_tree, hf_mmse_read_status,
1056
247
                        tvb, offset - 2, 2, field);
1057
247
                break;
1058
100
            case MM_REPLY_CHARGING_HDR:     /* Well-known-value */
1059
100
                field = tvb_get_uint8(tvb, offset++);
1060
100
                proto_tree_add_uint(mmse_tree, hf_mmse_reply_charging,
1061
100
                        tvb, offset - 2, 2, field);
1062
100
                break;
1063
28
            case MM_REPLY_CHARGING_DEADLINE_HDR:    /* Well-known-value */
1064
28
                {
1065
28
                    unsigned         tval;
1066
28
                    nstime_t         tmptime;
1067
28
                    unsigned         cnt;
1068
1069
                    /*
1070
                     * Value-length(Absolute-token Date-value|
1071
                     *              Relative-token Delta-seconds-value)
1072
                     */
1073
1074
28
                    length = get_value_length(tvb, offset, &count, pinfo);
1075
28
                    field = tvb_get_uint8(tvb, offset + count);
1076
1077
28
                    tval = get_long_integer(tvb, offset + count + 1, &cnt);
1078
28
                    tmptime.secs = tval;
1079
28
                    tmptime.nsecs = 0;
1080
1081
28
                    if (field == 0x80)
1082
0
                        proto_tree_add_time(mmse_tree, hf_mmse_reply_charging_deadline_abs,
1083
0
                                tvb, offset - 1,
1084
0
                                length + count + 1, &tmptime);
1085
28
                    else
1086
28
                        proto_tree_add_time(mmse_tree, hf_mmse_reply_charging_deadline_rel,
1087
28
                                tvb, offset - 1,
1088
28
                                length + count + 1, &tmptime);
1089
28
                }
1090
28
                offset += length + count;
1091
28
                break;
1092
25
            case MM_REPLY_CHARGING_ID_HDR:  /* Text-string */
1093
25
                length = get_text_string(tvb, offset, pinfo->pool, &strval);
1094
25
                proto_tree_add_string(mmse_tree,
1095
25
                        hf_mmse_reply_charging_id,
1096
25
                        tvb, offset - 1, length + 1, strval);
1097
25
                offset += length;
1098
25
                break;
1099
18
            case MM_REPLY_CHARGING_SIZE_HDR:        /* Long-integer */
1100
18
                length = get_long_integer(tvb, offset, &count);
1101
18
                proto_tree_add_uint(mmse_tree,
1102
18
                        hf_mmse_reply_charging_size,
1103
18
                        tvb, offset - 1, count + 1, length);
1104
18
                offset += count;
1105
18
                break;
1106
65
            case MM_PREV_SENT_BY_HDR:
1107
65
                {
1108
65
                    uint32_t fwd_count, count1, count2;
1109
65
                    proto_tree *subtree = NULL;
1110
65
                    proto_item *tii = NULL;
1111
1112
                    /* Value-length Integer-value Encoded-string-value */
1113
65
                    length = get_value_length(tvb, offset, &count, pinfo);
1114
1115
                    /* 1. Forwarded-count-value := Integer-value */
1116
65
                    fwd_count = get_integer_value(tvb, offset + count,
1117
65
                            &count1);
1118
                    /* 2. Encoded-string-value */
1119
65
                    count2 = get_encoded_strval(tvb,
1120
65
                            offset + count + count1, &strval, pinfo);
1121
                    /* Now render the fields */
1122
65
                    tii = proto_tree_add_string_format(mmse_tree,
1123
65
                            hf_mmse_prev_sent_by,
1124
65
                            tvb, offset - 1, 1 + count + length,
1125
65
                            strval, "%s (Forwarded-count=%u)",
1126
65
                            format_text(pinfo->pool, strval, strlen(strval)),
1127
65
                            fwd_count);
1128
65
                    subtree = proto_item_add_subtree(tii,
1129
65
                            ett_mmse_hdr_details);
1130
65
                    proto_tree_add_uint(subtree,
1131
65
                            hf_mmse_prev_sent_by_fwd_count,
1132
65
                            tvb, offset + count, count1, fwd_count);
1133
65
                    proto_tree_add_string(subtree,
1134
65
                            hf_mmse_prev_sent_by_address,
1135
65
                            tvb, offset + count + count1, count2, strval);
1136
65
                }
1137
65
                offset += length + count;
1138
65
                break;
1139
72
            case MM_PREV_SENT_DATE_HDR:
1140
72
                {
1141
72
                    uint32_t fwd_count, count1, count2;
1142
72
                    unsigned         tval;
1143
72
                    nstime_t         tmptime;
1144
72
                    proto_tree *subtree = NULL;
1145
72
                    proto_item *tii = NULL;
1146
1147
                    /* Value-Length Forwarded-count-value Date-value */
1148
72
                    length = get_value_length(tvb, offset, &count, pinfo);
1149
                    /* 1. Forwarded-count-value := Integer-value */
1150
72
                    fwd_count = get_integer_value(tvb, offset + count, &count1);
1151
                    /* 2. Date-value := Long-integer */
1152
72
                    tval = get_long_integer(tvb, offset + count + count1,
1153
72
                            &count2);
1154
72
                    tmptime.secs = tval;
1155
72
                    tmptime.nsecs = 0;
1156
72
                    strval = abs_time_to_str(pinfo->pool, &tmptime, ABSOLUTE_TIME_LOCAL,
1157
72
                            true);
1158
                    /* Now render the fields */
1159
72
                    tii = proto_tree_add_string_format(mmse_tree,
1160
72
                            hf_mmse_prev_sent_date,
1161
72
                            tvb, offset - 1, 1 + count + length,
1162
72
                            strval, "%s (Forwarded-count=%u)",
1163
72
                            format_text(pinfo->pool, strval, strlen(strval)),
1164
72
                            fwd_count);
1165
72
                    subtree = proto_item_add_subtree(tii,
1166
72
                            ett_mmse_hdr_details);
1167
72
                    proto_tree_add_uint(subtree,
1168
72
                            hf_mmse_prev_sent_date_fwd_count,
1169
72
                            tvb, offset + count, count1, fwd_count);
1170
72
                    proto_tree_add_string(subtree,
1171
72
                            hf_mmse_prev_sent_date_date,
1172
72
                            tvb, offset + count + count1, count2, strval);
1173
72
                }
1174
72
                offset += length + count;
1175
72
                break;
1176
1177
                /* MMS Encapsulation 1.2 */
1178
1179
10.6k
            default:
1180
10.6k
                if (field & 0x80) { /* Well-known WSP header encoding */
1181
2.35k
                    uint8_t peek = tvb_get_uint8(tvb, offset);
1182
2.35k
                    const char *hdr_name = val_to_str(pinfo->pool, field, vals_mm_header_names,
1183
2.35k
                            "Unknown field (0x%02x)");
1184
2.35k
                    const char *str;
1185
2.35k
                    DebugLog(("\t\tUndecoded well-known header: %s\n",
1186
2.35k
                                hdr_name));
1187
1188
2.35k
                    if (peek & 0x80) { /* Well-known value */
1189
1.54k
                        length = 1;
1190
1.54k
                        proto_tree_add_uint_format(mmse_tree, hf_mmse_header_uint, tvb, offset - 1,
1191
1.54k
                                length + 1, peek,
1192
1.54k
                                "%s: <Well-known value 0x%02x>"
1193
1.54k
                                " (not decoded)",
1194
1.54k
                                hdr_name, peek);
1195
1.54k
                    } else if ((peek == 0) || (peek >= 0x20)) { /* Text */
1196
563
                        length = get_text_string(tvb, offset, pinfo->pool, &strval);
1197
563
                        str = format_text(pinfo->pool, strval, strlen(strval));
1198
563
                        proto_tree_add_string_format(mmse_tree, hf_mmse_header_string, tvb, offset - 1,
1199
563
                                length + 1, str, "%s: %s (Not decoded)", hdr_name, str);
1200
563
                    } else { /* General form with length */
1201
250
                        if (peek == 0x1F) { /* Value length in uintvar */
1202
10
                            unsigned length_len = 0;
1203
10
                            length = 1 + tvb_get_uintvar(tvb, offset + 1,
1204
10
                                    &length_len, pinfo, &ei_mmse_oversized_uintvar);
1205
10
                            length += length_len;
1206
240
                        } else { /* Value length in octet */
1207
240
                            length = 1 + tvb_get_uint8(tvb, offset);
1208
240
                        }
1209
250
                        proto_tree_add_bytes_format(mmse_tree, hf_mmse_header_bytes, tvb, offset - 1,
1210
250
                                length + 1, NULL, "%s: "
1211
250
                                "<Value in general form> (not decoded)",
1212
250
                                hdr_name);
1213
250
                    }
1214
2.35k
                    offset += length;
1215
8.29k
                } else { /* Literal WSP header encoding */
1216
8.29k
                    unsigned         length2;
1217
8.29k
                    const char       *strval2;
1218
1219
8.29k
                    --offset;
1220
8.29k
                    length = get_text_string(tvb, offset, pinfo->pool, &strval);
1221
8.29k
                    DebugLog(("\t\tUndecoded literal header: %s\n",
1222
8.29k
                                strval));
1223
8.29k
                    length2= get_text_string(tvb, offset+length, pinfo->pool, &strval2);
1224
1225
8.29k
                    proto_tree_add_string_format(mmse_tree,
1226
8.29k
                            hf_mmse_ffheader, tvb, offset,
1227
8.29k
                            length + length2,
1228
8.29k
                            (char*)tvb_get_string_enc(pinfo->pool, tvb, offset,
1229
8.29k
                                length + length2, ENC_ASCII),
1230
8.29k
                            "%s: %s",
1231
8.29k
                            format_text(pinfo->pool, strval, strlen(strval)),
1232
8.29k
                            format_text(pinfo->pool, strval2, strlen(strval2)));
1233
1234
8.29k
                    offset += length + length2;
1235
8.29k
                }
1236
10.6k
                break;
1237
13.4k
        }
1238
13.1k
        DebugLog(("\tEnd(case)\n"));
1239
1240
13.1k
        if (offset <= old_offset) {
1241
0
            REPORT_DISSECTOR_BUG("Offset isn't increasing (offset=%u, old offset=%u)", offset, old_offset);
1242
0
        }
1243
13.1k
        old_offset = offset;
1244
13.1k
    }
1245
1246
172
    DebugLog(("\tEnd(switch)\n"));
1247
172
    if (field == MM_CTYPE_HDR) {
1248
        /*
1249
         * Eeehh, we're now actually back to good old WSP content-type
1250
         * encoding. Let's steal that from the WSP-dissector.
1251
         */
1252
133
        tvbuff_t    *tmp_tvb;
1253
133
        unsigned     type;
1254
133
        const char  *type_str;
1255
1256
133
        DebugLog(("Content-Type: [from WSP dissector]\n"));
1257
133
        DebugLog(("Calling add_content_type() in WSP dissector\n"));
1258
133
        offset = add_content_type(mmse_tree, pinfo, tvb, offset, &type, &type_str);
1259
133
        DebugLog(("Generating new TVB subset (offset = %u)\n", offset));
1260
133
        tmp_tvb = tvb_new_subset_remaining(tvb, offset);
1261
133
        DebugLog(("Add POST data\n"));
1262
133
        add_post_data(mmse_tree, tmp_tvb, type, type_str, pinfo);
1263
133
        DebugLog(("Done!\n"));
1264
133
    }
1265
1266
    /* If this protocol has a sub-dissector call it here, see section 1.8 */
1267
172
    DebugLog(("dissect_mmse() - END\n"));
1268
172
}
1269
1270
1271
/* Register the protocol with Wireshark */
1272
1273
/* this format is required because a script is used to build the C function
1274
 * that calls all the protocol registration.
1275
 */
1276
void
1277
proto_register_mmse(void)
1278
16
{
1279
    /* Setup list of header fields  See Section 1.6.1 for details       */
1280
16
    static hf_register_info hf[] = {
1281
16
        {   &hf_mmse_message_type,
1282
16
            {   "X-Mms-Message-Type", "mmse.message_type",
1283
16
                FT_UINT8, BASE_HEX, VALS(vals_message_type), 0x00,
1284
16
                "Specifies the transaction type. Effectively defines PDU.",
1285
16
                HFILL
1286
16
            }
1287
16
        },
1288
16
        {   &hf_mmse_transaction_id,
1289
16
            {   "X-Mms-Transaction-ID", "mmse.transaction_id",
1290
16
                FT_STRING, BASE_NONE, NULL, 0x00,
1291
16
                "A unique identifier for this transaction. Identifies request and corresponding response only.",
1292
16
                HFILL
1293
16
            }
1294
16
        },
1295
16
        {   &hf_mmse_mms_version,
1296
16
            {   "X-Mms-MMS-Version", "mmse.mms_version",
1297
16
                FT_STRING, BASE_NONE, NULL, 0x00,
1298
16
                "Version of the protocol used.",
1299
16
                HFILL
1300
16
            }
1301
16
        },
1302
16
        {   &hf_mmse_bcc,
1303
16
            {   "Bcc", "mmse.bcc",
1304
16
                FT_STRING, BASE_NONE, NULL, 0x00,
1305
16
                "Blind carbon copy.",
1306
16
                HFILL
1307
16
            }
1308
16
        },
1309
16
        {   &hf_mmse_cc,
1310
16
            {   "Cc", "mmse.cc",
1311
16
                FT_STRING, BASE_NONE, NULL, 0x00,
1312
16
                "Carbon copy.",
1313
16
                HFILL
1314
16
            }
1315
16
        },
1316
16
        {   &hf_mmse_content_location,
1317
16
            {   "X-Mms-Content-Location", "mmse.content_location",
1318
16
                FT_STRING, BASE_NONE, NULL, 0x00,
1319
16
                "Defines the location of the message.",
1320
16
                HFILL
1321
16
            }
1322
16
        },
1323
16
        {   &hf_mmse_date,
1324
16
            {   "Date", "mmse.date",
1325
16
                FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x00,
1326
16
                "Arrival timestamp of the message or sending timestamp.",
1327
16
                HFILL
1328
16
            }
1329
16
        },
1330
16
        {   &hf_mmse_delivery_report,
1331
16
            {   "X-Mms-Delivery-Report", "mmse.delivery_report",
1332
16
                FT_UINT8, BASE_HEX, VALS(vals_yes_no), 0x00,
1333
16
                "Whether a report of message delivery is wanted or not.",
1334
16
                HFILL
1335
16
            }
1336
16
        },
1337
16
        {   &hf_mmse_delivery_time_abs,
1338
16
            {   "X-Mms-Delivery-Time", "mmse.delivery_time.abs",
1339
16
                FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x00,
1340
16
                "The time at which message delivery is desired.",
1341
16
                HFILL
1342
16
            }
1343
16
        },
1344
16
        {   &hf_mmse_delivery_time_rel,
1345
16
            {   "X-Mms-Delivery-Time", "mmse.delivery_time.rel",
1346
16
                FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
1347
16
                "The desired message delivery delay.",
1348
16
                HFILL
1349
16
            }
1350
16
        },
1351
16
        {   &hf_mmse_expiry_abs,
1352
16
            {   "X-Mms-Expiry", "mmse.expiry.abs",
1353
16
                FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x00,
1354
16
                "Time when message expires and need not be delivered anymore.",
1355
16
                HFILL
1356
16
            }
1357
16
        },
1358
16
        {   &hf_mmse_expiry_rel,
1359
16
            {   "X-Mms-Expiry", "mmse.expiry.rel",
1360
16
                FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
1361
16
                "Delay before message expires and need not be delivered anymore.",
1362
16
                HFILL
1363
16
            }
1364
16
        },
1365
16
        {   &hf_mmse_from,
1366
16
            {   "From", "mmse.from",
1367
16
                FT_STRING, BASE_NONE, NULL, 0x00,
1368
16
                "Address of the message sender.",
1369
16
                HFILL
1370
16
            }
1371
16
        },
1372
16
        {   &hf_mmse_message_class_id,
1373
16
            {   "X-Mms-Message-Class", "mmse.message_class.id",
1374
16
                FT_UINT8, BASE_HEX, VALS(vals_message_class), 0x00,
1375
16
                "Of what category is the message.",
1376
16
                HFILL
1377
16
            }
1378
16
        },
1379
16
        {   &hf_mmse_message_class_str,
1380
16
            {   "X-Mms-Message-Class", "mmse.message_class.str",
1381
16
                FT_STRING, BASE_NONE, NULL, 0x00,
1382
16
                "Of what category is the message.",
1383
16
                HFILL
1384
16
            }
1385
16
        },
1386
16
        {   &hf_mmse_message_id,
1387
16
            {   "Message-Id", "mmse.message_id",
1388
16
                FT_STRING, BASE_NONE, NULL, 0x00,
1389
16
                "Unique identification of the message.",
1390
16
                HFILL
1391
16
            }
1392
16
        },
1393
16
        {   &hf_mmse_message_size,
1394
16
            {   "X-Mms-Message-Size", "mmse.message_size",
1395
16
                FT_UINT32, BASE_DEC, NULL, 0x00,
1396
16
                "The size of the message in octets.",
1397
16
                HFILL
1398
16
            }
1399
16
        },
1400
16
        {   &hf_mmse_priority,
1401
16
            {   "X-Mms-Priority", "mmse.priority",
1402
16
                FT_UINT8, BASE_HEX, VALS(vals_priority), 0x00,
1403
16
                "Priority of the message.",
1404
16
                HFILL
1405
16
            }
1406
16
        },
1407
16
        {   &hf_mmse_read_reply,
1408
16
            {   "X-Mms-Read-Reply", "mmse.read_reply",
1409
16
                FT_UINT8, BASE_HEX, VALS(vals_yes_no), 0x00,
1410
16
                "Whether a read report from every recipient is wanted.",
1411
16
                HFILL
1412
16
            }
1413
16
        },
1414
16
        {   &hf_mmse_read_report,
1415
16
            {   "X-Mms-Read-Report", "mmse.read_report",
1416
16
                FT_UINT8, BASE_HEX, VALS(vals_yes_no), 0x00,
1417
16
                "Whether a read report from every recipient is wanted.",
1418
16
                HFILL
1419
16
            }
1420
16
        },
1421
16
        {   &hf_mmse_report_allowed,
1422
16
            {   "X-Mms-Report-Allowed", "mmse.report_allowed",
1423
16
                FT_UINT8, BASE_HEX, VALS(vals_yes_no), 0x00,
1424
16
                "Sending of delivery report allowed or not.",
1425
16
                HFILL
1426
16
            }
1427
16
        },
1428
16
        {   &hf_mmse_response_status,
1429
16
            {   "Response-Status", "mmse.response_status",
1430
16
                FT_UINT8, BASE_HEX, VALS(vals_response_status), 0x00,
1431
16
                "MMS-specific result of a message submission or retrieval.",
1432
16
                HFILL
1433
16
            }
1434
16
        },
1435
16
        {   &hf_mmse_response_text,
1436
16
            {   "Response-Text", "mmse.response_text",
1437
16
                FT_STRING, BASE_NONE, NULL, 0x00,
1438
16
                "Additional information on MMS-specific result.",
1439
16
                HFILL
1440
16
            }
1441
16
        },
1442
16
        {   &hf_mmse_sender_visibility,
1443
16
            {   "Sender-Visibility", "mmse.sender_visibility",
1444
16
                FT_UINT8, BASE_HEX, VALS(vals_sender_visibility), 0x00,
1445
16
                "Disclose sender identity to receiver or not.",
1446
16
                HFILL
1447
16
            }
1448
16
        },
1449
16
        {   &hf_mmse_status,
1450
16
            {   "Status", "mmse.status",
1451
16
                FT_UINT8, BASE_HEX, VALS(vals_message_status), 0x00,
1452
16
                "Current status of the message.",
1453
16
                HFILL
1454
16
            }
1455
16
        },
1456
16
        {   &hf_mmse_subject,
1457
16
            {   "Subject", "mmse.subject",
1458
16
                FT_STRING, BASE_NONE, NULL, 0x00,
1459
16
                "Subject of the message.",
1460
16
                HFILL
1461
16
            }
1462
16
        },
1463
16
        {   &hf_mmse_to,
1464
16
            {   "To", "mmse.to",
1465
16
                FT_STRING, BASE_NONE, NULL, 0x00,
1466
16
                "Recipient(s) of the message.",
1467
16
                HFILL
1468
16
            }
1469
16
        },
1470
#if 0
1471
        {   &hf_mmse_content_type,
1472
            {   "Data", "mmse.content_type",
1473
                FT_NONE, BASE_NONE, NULL, 0x00,
1474
                "Media content of the message.",
1475
                HFILL
1476
            }
1477
        },
1478
#endif
1479
16
        {   &hf_mmse_ffheader,
1480
16
            {   "Free format (not encoded) header", "mmse.ffheader",
1481
16
                FT_STRING, BASE_NONE, NULL, 0x00,
1482
16
                "Application header without corresponding encoding.",
1483
16
                HFILL
1484
16
            }
1485
16
        },
1486
        /* MMSE 1.1 */
1487
16
        {   &hf_mmse_retrieve_status,
1488
16
            {   "X-Mms-Retrieve-Status", "mmse.retrieve_status",
1489
16
                FT_UINT8, BASE_HEX, VALS(vals_retrieve_status), 0x00,
1490
16
                "MMS-specific result of a message retrieval.",
1491
16
                HFILL
1492
16
            }
1493
16
        },
1494
16
        {   &hf_mmse_retrieve_text,
1495
16
            {   "X-Mms-Retrieve-Text", "mmse.retrieve_text",
1496
16
                FT_STRING, BASE_NONE, NULL, 0x00,
1497
16
                "Status text of a MMS message retrieval.",
1498
16
                HFILL
1499
16
            }
1500
16
        },
1501
16
        {   &hf_mmse_read_status,
1502
16
            {   "X-Mms-Read-Status", "mmse.read_status",
1503
16
                FT_UINT8, BASE_HEX, VALS(vals_read_status), 0x00,
1504
16
                "MMS-specific message read status.",
1505
16
                HFILL
1506
16
            }
1507
16
        },
1508
16
        {   &hf_mmse_reply_charging,
1509
16
            {   "X-Mms-Reply-Charging", "mmse.reply_charging",
1510
16
                FT_UINT8, BASE_HEX, VALS(vals_reply_charging), 0x00,
1511
16
                "MMS-specific message reply charging method.",
1512
16
                HFILL
1513
16
            }
1514
16
        },
1515
16
        {   &hf_mmse_reply_charging_deadline_abs,
1516
16
            {   "X-Mms-Reply-Charging-Deadline", "mmse.reply_charging_deadline.abs",
1517
16
                FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x00,
1518
16
                "The latest time of the recipient(s) to submit the Reply MM.",
1519
16
                HFILL
1520
16
            }
1521
16
        },
1522
16
        {   &hf_mmse_reply_charging_deadline_rel,
1523
16
            {   "X-Mms-Reply-Charging-Deadline", "mmse.reply_charging_deadline.rel",
1524
16
                FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
1525
16
                "The latest time of the recipient(s) to submit the Reply MM.",
1526
16
                HFILL
1527
16
            }
1528
16
        },
1529
16
        {   &hf_mmse_reply_charging_id,
1530
16
            {   "X-Mms-Reply-Charging-Id", "mmse.reply_charging_id",
1531
16
                FT_STRING, BASE_NONE, NULL, 0x00,
1532
16
                "Unique reply charging identification of the message.",
1533
16
                HFILL
1534
16
            }
1535
16
        },
1536
16
        {   &hf_mmse_reply_charging_size,
1537
16
            {   "X-Mms-Reply-Charging-Size", "mmse.reply_charging_size",
1538
16
                FT_UINT32, BASE_DEC, NULL, 0x00,
1539
16
                "The size of the reply charging in octets.",
1540
16
                HFILL
1541
16
            }
1542
16
        },
1543
16
        {   &hf_mmse_prev_sent_by,
1544
16
            {   "X-Mms-Previously-Sent-By", "mmse.previously_sent_by",
1545
16
                FT_STRING, BASE_NONE, NULL, 0x00,
1546
16
                "Indicates that the MM has been previously sent by this user.",
1547
16
                HFILL
1548
16
            }
1549
16
        },
1550
16
        {   &hf_mmse_prev_sent_by_fwd_count,
1551
16
            {   "Forward Count", "mmse.previously_sent_by.forward_count",
1552
16
                FT_UINT32, BASE_DEC, NULL, 0x00,
1553
16
                "Forward count of the previously sent MM.",
1554
16
                HFILL
1555
16
            }
1556
16
        },
1557
16
        {   &hf_mmse_prev_sent_by_address,
1558
16
            {   "Address", "mmse.previously_sent_by.address",
1559
16
                FT_STRING, BASE_NONE, NULL, 0x00,
1560
16
                "Indicates from whom the MM has been previously sent.",
1561
16
                HFILL
1562
16
            }
1563
16
        },
1564
16
        {   &hf_mmse_prev_sent_date,
1565
16
            {   "X-Mms-Previously-Sent-Date", "mmse.previously_sent_date",
1566
16
                FT_STRING, BASE_NONE, NULL, 0x00,
1567
16
                "Indicates the date that the MM has been previously sent.",
1568
16
                HFILL
1569
16
            }
1570
16
        },
1571
16
        {   &hf_mmse_prev_sent_date_fwd_count,
1572
16
            {   "Forward Count", "mmse.previously_sent_date.forward_count",
1573
16
                FT_UINT32, BASE_DEC, NULL, 0x00,
1574
16
                "Forward count of the previously sent MM.",
1575
16
                HFILL
1576
16
            }
1577
16
        },
1578
16
        {   &hf_mmse_prev_sent_date_date,
1579
16
            {   "Date", "mmse.previously_sent_date.date",
1580
16
                FT_STRING, BASE_NONE, NULL, 0x00,
1581
16
                "Time when the MM has been previously sent.",
1582
16
                HFILL
1583
16
            }
1584
16
        },
1585
16
        {   &hf_mmse_header_uint,
1586
16
            {   "Header Uint Value", "mmse.header.uint",
1587
16
                FT_UINT8, BASE_DEC, NULL, 0x00, NULL, HFILL
1588
16
            }
1589
16
        },
1590
16
        {   &hf_mmse_header_string,
1591
16
            {   "Header String Value", "mmse.header.string",
1592
16
                FT_STRING, BASE_NONE, NULL, 0x00, NULL, HFILL
1593
16
            }
1594
16
        },
1595
16
        {   &hf_mmse_header_bytes,
1596
16
            {   "Header Byte array", "mmse.header.bytes",
1597
16
                FT_BYTES, BASE_NONE, NULL, 0x00, NULL, HFILL
1598
16
            }
1599
16
        },
1600
1601
1602
16
    };
1603
    /* Setup protocol subtree array */
1604
16
    static int *ett[] = {
1605
16
        &ett_mmse,
1606
16
        &ett_mmse_hdr_details,
1607
16
    };
1608
1609
16
    static ei_register_info ei[] = {
1610
16
        { &ei_mmse_oversized_uintvar, { "mmse.oversized_uintvar", PI_MALFORMED, PI_ERROR, "Uintvar is oversized", EXPFILL }}
1611
16
    };
1612
1613
16
    expert_module_t* expert_mmse;
1614
1615
        /* Register the protocol name and description */
1616
16
    proto_mmse = proto_register_protocol("MMS Message Encapsulation",
1617
16
                                         "MMSE", "mmse");
1618
1619
    /* Required function calls to register header fields and subtrees used */
1620
16
    proto_register_field_array(proto_mmse, hf, array_length(hf));
1621
16
    proto_register_subtree_array(ett, array_length(ett));
1622
1623
16
    expert_mmse = expert_register_protocol(proto_mmse);
1624
16
    expert_register_field_array(expert_mmse, ei, array_length(ei));
1625
1626
    /* Register the dissectors */
1627
16
    mmse_standalone_handle = register_dissector("mmse", dissect_mmse_standalone, proto_mmse);
1628
16
    mmse_encapsulated_handle = register_dissector("mmse_encapsulated", dissect_mmse_encapsulated, proto_mmse);
1629
16
}
1630
1631
/* If this dissector uses sub-dissector registration add registration routine.
1632
 * This format is required because a script is used to find these routines and
1633
 * create the code that calls these routines.
1634
 */
1635
void
1636
proto_reg_handoff_mmse(void)
1637
16
{
1638
16
    heur_dissector_add("wsp", dissect_mmse_heur, "MMS Message Encapsulation over WSP", "mmse_wsp", proto_mmse, HEURISTIC_ENABLE);
1639
        /* As the media types for WSP and HTTP are the same, the WSP dissector
1640
         * uses the same string dissector table as the HTTP protocol. */
1641
16
    dissector_add_string("media_type",
1642
16
            "application/vnd.wap.mms-message", mmse_standalone_handle);
1643
16
    dissector_add_string("multipart_media_type",
1644
16
            "application/vnd.wap.mms-message", mmse_encapsulated_handle);
1645
16
}
1646
1647
/*
1648
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1649
 *
1650
 * Local variables:
1651
 * c-basic-offset: 4
1652
 * tab-width: 8
1653
 * indent-tabs-mode: nil
1654
 * End:
1655
 *
1656
 * vi: set shiftwidth=4 tabstop=8 expandtab:
1657
 * :indentSize=4:tabSize=8:noTabs=true:
1658
 */