/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 | | */ |