1 /* packet-gsm_sms_ud.c
2 * Routines for GSM SMS TP-UD (GSM 03.40) dissection
3 *
4 * Refer to the AUTHORS file or the AUTHORS section in the man page
5 * for contacting the author(s) of this file.
6 *
7 * Separated from the SMPP dissector by Chris Wilson.
8 *
9 * UDH and WSP dissection of SMS message, Short Message reassembly,
10 * "Decode Short Message with Port Number UDH as CL-WSP" preference,
11 * "Always try subdissection of 1st fragment" preference,
12 * provided by Olivier Biot.
13 *
14 * Note on SMS Message reassembly
15 * ------------------------------
16 * The current Short Message reassembly is possible thanks to the
17 * message identifier (8 or 16 bit identifier). It is able to reassemble
18 * short messages that are sent over either the same SMPP connection or
19 * distinct SMPP connections. Normally the reassembly code is able to deal
20 * with duplicate message identifiers since the fragment_add_seq_check()
21 * call is used.
22 *
23 * The SMS TP-UD preference "always try subdissection of 1st fragment" allows
24 * a subdissector to be called for the first Short Message fragment,
25 * even if reassembly is not possible. This way partial dissection
26 * is still possible. This preference is switched off by default.
27 *
28 * Note on Short Message decoding as CL-WSP
29 * ----------------------------------------
30 * The SMS TP-UD preference "port_number_udh_means_wsp" is switched off
31 * by default. If it is enabled, then any Short Message with a Port Number
32 * UDH will be decoded as CL-WSP if:
33 * - The Short Message is not segmented
34 * - The entire segmented Short Message is reassembled
35 * - It is the 1st segment of an unreassembled Short Message (if the
36 * "always try subdissection of 1st fragment" preference is enabled)
37 *
38 * Wireshark - Network traffic analyzer
39 * By Gerald Combs <gerald@wireshark.org>
40 * Copyright 1998 Gerald Combs
41 *
42 * SPDX-License-Identifier: GPL-2.0-or-later
43 */
44
45 #include "config.h"
46
47 #include <epan/packet.h>
48
49 #include <epan/prefs.h>
50 #include <epan/reassemble.h>
51
52 void proto_register_gsm_sms_ud(void);
53 void proto_reg_handoff_gsm_sms_ud(void);
54
55 static int proto_gsm_sms_ud = -1;
56
57 /*
58 * Short Message fragment handling
59 */
60 static int hf_gsm_sms_ud_fragments = -1;
61 static int hf_gsm_sms_ud_fragment = -1;
62 static int hf_gsm_sms_ud_fragment_overlap = -1;
63 static int hf_gsm_sms_ud_fragment_overlap_conflicts = -1;
64 static int hf_gsm_sms_ud_fragment_multiple_tails = -1;
65 static int hf_gsm_sms_ud_fragment_too_long_fragment = -1;
66 static int hf_gsm_sms_ud_fragment_error = -1;
67 static int hf_gsm_sms_ud_fragment_count = -1;
68 static int hf_gsm_sms_ud_reassembled_in = -1;
69 static int hf_gsm_sms_ud_reassembled_length = -1;
70 static int hf_gsm_sms_ud_short_msg = -1;
71 /*
72 * User Data Header section
73 */
74 static int hf_gsm_sms_udh_length = -1;
75 static int hf_gsm_sms_udh_iei = -1;
76 /* static int hf_gsm_sms_udh_multiple_messages = -1; */
77 static int hf_gsm_sms_udh_multiple_messages_msg_id = -1;
78 static int hf_gsm_sms_udh_multiple_messages_msg_parts = -1;
79 static int hf_gsm_sms_udh_multiple_messages_msg_part = -1;
80 /* static int hf_gsm_sms_udh_ports = -1; */
81 static int hf_gsm_sms_udh_ports_src = -1;
82 static int hf_gsm_sms_udh_ports_dst = -1;
83 static int hf_gsm_sms_udh_national_single_shift = -1;
84 static int hf_gsm_sms_udh_national_locking_shift = -1;
85
86 static gint ett_gsm_sms = -1;
87 static gint ett_udh = -1;
88 static gint ett_udh_ie = -1;
89 static gint ett_gsm_sms_ud_fragment = -1;
90 static gint ett_gsm_sms_ud_fragments = -1;
91
92 /* Subdissector declarations */
93 static dissector_table_t gsm_sms_dissector_table;
94
95 /* Short Message reassembly */
96 static reassembly_table sm_reassembly_table;
97
98 static const fragment_items sm_frag_items = {
99 /* Fragment subtrees */
100 &ett_gsm_sms_ud_fragment,
101 &ett_gsm_sms_ud_fragments,
102 /* Fragment fields */
103 &hf_gsm_sms_ud_fragments,
104 &hf_gsm_sms_ud_fragment,
105 &hf_gsm_sms_ud_fragment_overlap,
106 &hf_gsm_sms_ud_fragment_overlap_conflicts,
107 &hf_gsm_sms_ud_fragment_multiple_tails,
108 &hf_gsm_sms_ud_fragment_too_long_fragment,
109 &hf_gsm_sms_ud_fragment_error,
110 &hf_gsm_sms_ud_fragment_count,
111 /* Reassembled in field */
112 &hf_gsm_sms_ud_reassembled_in,
113 /* Reassembled length field */
114 &hf_gsm_sms_ud_reassembled_length,
115 /* Reassembled data field */
116 NULL,
117 /* Tag */
118 "Short Message fragments"
119 };
120
121 /* Dissect all SM data as WSP if the UDH contains a Port Number IE */
122 static gboolean port_number_udh_means_wsp = FALSE;
123
124 /* Always try dissecting the 1st fragment of a SM,
125 * even if it is not reassembled */
126 static gboolean try_dissect_1st_frag = FALSE;
127
128 /* Prevent subdissectors changing column data */
129 static gboolean prevent_subdissectors_changing_columns = FALSE;
130
131 static dissector_handle_t wsp_handle;
132
133 /*
134 * Value-arrays for field-contents
135 */
136 /* 3GPP TS 23.040 V12.2.0 (2014-10) */
137 static const value_string vals_udh_iei[] = {
138 { 0x00, "SMS - Concatenated short messages, 8-bit reference number" },
139 { 0x01, "SMS - Special SMS Message Indication" },
140 { 0x02, "Reserved" },
141 { 0x03, "Value not used to avoid misinterpretation as <LF> character" },
142 { 0x04, "SMS - Application port addressing scheme, 8 bit address" },
143 { 0x05, "SMS - Application port addressing scheme, 16 bit address" },
144 { 0x06, "SMS - SMSC Control Parameters" },
145 { 0x07, "SMS - UDH Source Indicator" },
146 { 0x08, "SMS - Concatenated short message, 16-bit reference number" },
147 { 0x09, "SMS - Wireless Control Message Protocol" },
148 { 0x0A, "EMS - Text Formatting" },
149 { 0x0B, "EMS - Predefined Sound" },
150 { 0x0C, "EMS - User Defined Sound (iMelody max 128 bytes)" },
151 { 0x0D, "EMS - Predefined Animation" },
152 { 0x0E, "EMS - Large Animation (16*16 times 4 = 32*4 =128 bytes)" },
153 { 0x0F, "EMS - Small Animation (8*8 times 4 = 8*4 =32 bytes)" },
154 { 0x10, "EMS - Large Picture (32*32 = 128 bytes)" },
155 { 0x11, "EMS - Small Picture (16*16 = 32 bytes)" },
156 { 0x12, "EMS - Variable Picture" },
157 { 0x13, "EMS - User prompt indicator" },
158 { 0x14, "EMS - Extended Object" },
159 { 0x15, "EMS - Reused Extended Object" },
160 { 0x16, "EMS - Compression Control" },
161 { 0x17, "EMS - Object Distribution Indicator" },
162 { 0x18, "EMS - Standard WVG object" },
163 { 0x19, "EMS - Character Size WVG object" },
164 { 0x1A, "EMS - Extended Object Data Request Command" },
165 { 0x20, "SMS - RFC 822 E-Mail Header" },
166 { 0x21, "SMS - Hyperlink format element" },
167 { 0x22, "SMS - Reply Address Element" },
168 { 0x23, "SMS - Enhanced Voice Mail Information" },
169 { 0x24, "SMS - National Language Single Shift" },
170 { 0x25, "SMS - National Language Locking Shift" },
171 { 0x00, NULL }
172 };
173
174 /* 3GPP TS 23.038 V12.0.0 (2014-10) */
175 static const value_string vals_udh_national_languages_single_shift[] = {
176 { 0x01, "Turkish" },
177 { 0x02, "Spanish" },
178 { 0x03, "Portuguese" },
179 { 0x04, "Bengali" },
180 { 0x05, "Gujarati" },
181 { 0x06, "Hindi" },
182 { 0x07, "Kannada" },
183 { 0x08, "Malayalam" },
184 { 0x09, "Oriya" },
185 { 0x0A, "Punjabi" },
186 { 0x0B, "Tamil" },
187 { 0x0C, "Telugu" },
188 { 0x0D, "Urdu" },
189 { 0x00, NULL }
190 };
191
192 static const value_string vals_udh_national_languages_locking_shift[] = {
193 { 0x01, "Turkish" },
194 { 0x03, "Portuguese" },
195 { 0x04, "Bengali" },
196 { 0x05, "Gujarati" },
197 { 0x06, "Hindi" },
198 { 0x07, "Kannada" },
199 { 0x08, "Malayalam" },
200 { 0x09, "Oriya" },
201 { 0x0A, "Punjabi" },
202 { 0x0B, "Tamil" },
203 { 0x0C, "Telugu" },
204 { 0x0D, "Urdu" },
205 { 0x00, NULL }
206 };
207
208 /* Parse Short Message, only if UDH present
209 * (otherwise this function is not called).
210 * Call WSP dissector if port matches WSP traffic.
211 */
212 static void
parse_gsm_sms_ud_message(proto_tree * sm_tree,tvbuff_t * tvb,packet_info * pinfo,proto_tree * top_tree)213 parse_gsm_sms_ud_message(proto_tree *sm_tree, tvbuff_t *tvb, packet_info *pinfo,
214 proto_tree *top_tree)
215 {
216 tvbuff_t *sm_tvb = NULL;
217 proto_item *ti;
218 proto_tree *subtree, *tree;
219 guint8 udh_len, udh, len;
220 guint sm_len = tvb_reported_length(tvb);
221 guint sm_data_len;
222 guint32 i = 0;
223 /* Multiple Messages UDH */
224 gboolean is_fragmented = FALSE;
225 fragment_head *fd_sm = NULL;
226 guint16 sm_id = 0;
227 guint16 frags = 0;
228 guint16 frag = 0;
229 gboolean save_fragmented = FALSE;
230 gboolean try_gsm_sms_ud_reassemble = FALSE;
231 /* SMS Message reassembly */
232 gboolean reassembled = FALSE;
233 guint32 reassembled_in = 0;
234 /* Port Number UDH */
235 guint16 p_src = 0;
236 guint16 p_dst = 0;
237 gboolean ports_available = FALSE;
238
239 udh_len = tvb_get_guint8(tvb, i++);
240 ti = proto_tree_add_uint(sm_tree, hf_gsm_sms_udh_length, tvb, 0, 1, udh_len);
241 tree = proto_item_add_subtree(ti, ett_udh);
242 while (i < udh_len) {
243 udh = tvb_get_guint8(tvb, i++);
244 len = tvb_get_guint8(tvb, i++);
245 subtree = proto_tree_add_uint(tree, hf_gsm_sms_udh_iei,
246 tvb, i-2, 2+len, udh);
247 switch (udh) {
248 case 0x00: /* Multiple messages - 8-bit message ID */
249 if (len == 3) {
250 sm_id = tvb_get_guint8(tvb, i++);
251 frags = tvb_get_guint8(tvb, i++);
252 frag = tvb_get_guint8(tvb, i++);
253 if (frags > 1)
254 is_fragmented = TRUE;
255 proto_item_append_text(subtree,
256 ": message %u, part %u of %u", sm_id, frag, frags);
257 subtree = proto_item_add_subtree(subtree,
258 ett_udh_ie);
259 proto_tree_add_uint(subtree,
260 hf_gsm_sms_udh_multiple_messages_msg_id,
261 tvb, i-3, 1, sm_id);
262 proto_tree_add_uint(subtree,
263 hf_gsm_sms_udh_multiple_messages_msg_parts,
264 tvb, i-2, 1, frags);
265 proto_tree_add_uint(subtree,
266 hf_gsm_sms_udh_multiple_messages_msg_part,
267 tvb, i-1, 1, frag);
268 } else {
269 proto_item_append_text(subtree, " - Invalid format!");
270 i += len;
271 }
272 break;
273
274 case 0x08: /* Multiple messages - 16-bit message ID */
275 if (len == 4) {
276 sm_id = tvb_get_ntohs(tvb, i); i += 2;
277 frags = tvb_get_guint8(tvb, i++);
278 frag = tvb_get_guint8(tvb, i++);
279 if (frags > 1)
280 is_fragmented = TRUE;
281 proto_item_append_text(subtree,
282 ": message %u, part %u of %u", sm_id, frag, frags);
283 subtree = proto_item_add_subtree(subtree,
284 ett_udh_ie);
285 proto_tree_add_uint(subtree,
286 hf_gsm_sms_udh_multiple_messages_msg_id,
287 tvb, i-4, 2, sm_id);
288 proto_tree_add_uint(subtree,
289 hf_gsm_sms_udh_multiple_messages_msg_parts,
290 tvb, i-2, 1, frags);
291 proto_tree_add_uint(subtree,
292 hf_gsm_sms_udh_multiple_messages_msg_part,
293 tvb, i-1, 1, frag);
294 } else {
295 proto_item_append_text(subtree, " - Invalid format!");
296 i += len;
297 }
298 break;
299
300 case 0x04: /* Port Number UDH - 8-bit address */
301 if (len == 2) { /* Port fields */
302 p_dst = tvb_get_guint8(tvb, i++);
303 p_src = tvb_get_guint8(tvb, i++);
304 proto_item_append_text(subtree,
305 ": source port %u, destination port %u",
306 p_src, p_dst);
307 subtree = proto_item_add_subtree(subtree, ett_udh_ie);
308 proto_tree_add_uint(subtree, hf_gsm_sms_udh_ports_dst,
309 tvb, i-2, 1, p_dst);
310 proto_tree_add_uint(subtree, hf_gsm_sms_udh_ports_src,
311 tvb, i-1, 1, p_src);
312 ports_available = TRUE;
313 } else {
314 proto_item_append_text(subtree, " - Invalid format!");
315 i += len;
316 }
317 break;
318
319 case 0x05: /* Port Number UDH - 16-bit address */
320 if (len == 4) { /* Port fields */
321 p_dst = tvb_get_ntohs(tvb, i); i += 2;
322 p_src = tvb_get_ntohs(tvb, i); i += 2;
323 proto_item_append_text(subtree,
324 ": source port %u, destination port %u",
325 p_src, p_dst);
326 subtree = proto_item_add_subtree(subtree, ett_udh_ie);
327 proto_tree_add_uint(subtree, hf_gsm_sms_udh_ports_dst,
328 tvb, i-4, 2, p_dst);
329 proto_tree_add_uint(subtree, hf_gsm_sms_udh_ports_src,
330 tvb, i-2, 2, p_src);
331 ports_available = TRUE;
332 } else {
333 proto_item_append_text(subtree, " - Invalid format!");
334 i += len;
335 }
336 break;
337
338 case 0x24: /* National Language Single Shift */
339 if (len == 1) {
340 subtree = proto_item_add_subtree(subtree, ett_udh_ie);
341 proto_tree_add_item(subtree,
342 hf_gsm_sms_udh_national_single_shift,
343 tvb, i++, 1, ENC_BIG_ENDIAN);
344 } else {
345 proto_item_append_text(subtree, " - Invalid format!");
346 i += len;
347 }
348 break;
349
350 case 0x25: /* National Language Locking Shift */
351 if (len == 1) {
352 subtree = proto_item_add_subtree(subtree, ett_udh_ie);
353 proto_tree_add_item(subtree,
354 hf_gsm_sms_udh_national_locking_shift,
355 tvb, i++, 1, ENC_BIG_ENDIAN);
356 } else {
357 proto_item_append_text(subtree, " - Invalid format!");
358 i += len;
359 }
360 break;
361
362 default:
363 i += len;
364 break;
365 }
366 }
367 if (tvb_reported_length_remaining(tvb, i) <= 0)
368 return; /* No more data */
369
370 /*
371 * XXX - where does the "1" come from? If it weren't there,
372 * "sm_data_len" would, I think, be the same as
373 * "tvb_reported_length_remaining(tvb, i)".
374 *
375 * I think that the above check ensures that "sm_len" won't
376 * be less than or equal to "udh_len", so it ensures that
377 * "sm_len" won't be less than "1 + udh_len", so we don't
378 * have to worry about "sm_data_len" being negative.
379 */
380 sm_data_len = sm_len - (1 + udh_len);
381 if (sm_data_len == 0)
382 return; /* no more data */
383
384 /*
385 * Try reassembling the packets.
386 * XXX - fragment numbers are 1-origin, but the fragment number
387 * field could be 0.
388 * Should we flag a fragmented message with a fragment number field
389 * of 0?
390 * What if the fragment count is 0? Should we flag that as well?
391 */
392 if (is_fragmented && frag != 0 && frags != 0 &&
393 tvb_bytes_exist(tvb, i, sm_data_len)) {
394 try_gsm_sms_ud_reassemble = TRUE;
395 save_fragmented = pinfo->fragmented;
396 pinfo->fragmented = TRUE;
397 fd_sm = fragment_add_seq_check(&sm_reassembly_table,
398 tvb, i,
399 pinfo,
400 sm_id, /* guint32 ID for fragments belonging together */
401 NULL,
402 frag-1, /* guint32 fragment sequence number */
403 sm_data_len, /* guint32 fragment length */
404 (frag != frags)); /* More fragments? */
405 if (fd_sm) {
406 reassembled = TRUE;
407 reassembled_in = fd_sm->reassembled_in;
408 }
409 sm_tvb = process_reassembled_data(tvb, i, pinfo,
410 "Reassembled Short Message", fd_sm, &sm_frag_items,
411 NULL, sm_tree);
412 if (reassembled) { /* Reassembled */
413 col_append_str(pinfo->cinfo, COL_INFO,
414 " (Short Message Reassembled)");
415 } else {
416 /* Not last packet of reassembled Short Message */
417 col_append_fstr(pinfo->cinfo, COL_INFO,
418 " (Short Message fragment %u of %u)", frag, frags);
419 }
420 } /* Else: not fragmented */
421
422 if (! sm_tvb) /* One single Short Message, or not reassembled */
423 sm_tvb = tvb_new_subset_remaining(tvb, i);
424 /* Try calling a subdissector */
425 if (sm_tvb) {
426 if ((reassembled && pinfo->num == reassembled_in)
427 || frag==0 || (frag==1 && try_dissect_1st_frag)) {
428 /* Try calling a subdissector only if:
429 * - the Short Message is reassembled in this very packet,
430 * - the Short Message consists of only one "fragment",
431 * - the preference "Always Try Dissection for 1st SM fragment"
432 * is switched on, and this is the SM's 1st fragment. */
433 if (ports_available) {
434 gboolean disallow_write = FALSE; /* TRUE if we changed writability
435 of the columns of the summary */
436 if (prevent_subdissectors_changing_columns && col_get_writable(pinfo->cinfo, -1)) {
437 disallow_write = TRUE;
438 col_set_writable(pinfo->cinfo, -1, FALSE);
439 }
440
441 if (port_number_udh_means_wsp) {
442 call_dissector(wsp_handle, sm_tvb, pinfo, top_tree);
443 } else {
444 if (! dissector_try_uint(gsm_sms_dissector_table, p_src,
445 sm_tvb, pinfo, top_tree)) {
446 if (! dissector_try_uint(gsm_sms_dissector_table, p_dst,
447 sm_tvb, pinfo, top_tree)) {
448 if (sm_tree) { /* Only display if needed */
449 proto_tree_add_item(sm_tree, hf_gsm_sms_ud_short_msg, sm_tvb, 0, -1, ENC_NA);
450 }
451 }
452 }
453 }
454
455 if (disallow_write)
456 col_set_writable(pinfo->cinfo, -1, TRUE);
457 } else { /* No ports IE */
458 proto_tree_add_item(sm_tree, hf_gsm_sms_ud_short_msg, sm_tvb, 0, -1, ENC_NA);
459 }
460 } else {
461 /* The packet is not reassembled,
462 * or it is reassembled in another packet */
463 proto_tree_add_bytes_format(sm_tree, hf_gsm_sms_ud_short_msg, sm_tvb, 0, -1,
464 NULL, "Unreassembled Short Message fragment %u of %u",
465 frag, frags);
466 }
467 }
468
469 if (try_gsm_sms_ud_reassemble) /* Clean up defragmentation */
470 pinfo->fragmented = save_fragmented;
471 return;
472 }
473
474 static int
dissect_gsm_sms_ud(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)475 dissect_gsm_sms_ud(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
476 {
477 proto_item *ti;
478 proto_tree *subtree;
479
480 ti = proto_tree_add_item(tree, proto_gsm_sms_ud, tvb, 0, -1, ENC_NA);
481 subtree = proto_item_add_subtree(ti, ett_gsm_sms);
482 parse_gsm_sms_ud_message(subtree, tvb, pinfo, tree);
483 return tvb_captured_length(tvb);
484 }
485
486 /* Register the protocol with Wireshark */
487 void
proto_register_gsm_sms_ud(void)488 proto_register_gsm_sms_ud(void)
489 {
490 module_t *gsm_sms_ud_module; /* Preferences for GSM SMS UD */
491
492 /* Setup list of header fields */
493 static hf_register_info hf[] = {
494 /*
495 * User Data Header
496 */
497 { &hf_gsm_sms_udh_iei,
498 { "IE Id", "gsm_sms_ud.udh.iei",
499 FT_UINT8, BASE_HEX, VALS(vals_udh_iei), 0x00,
500 "Name of the User Data Header Information Element.",
501 HFILL
502 }
503 },
504 { &hf_gsm_sms_udh_length,
505 { "UDH Length", "gsm_sms_ud.udh.len",
506 FT_UINT8, BASE_DEC, NULL, 0x00,
507 "Length of the User Data Header (bytes)",
508 HFILL
509 }
510 },
511 #if 0
512 { &hf_gsm_sms_udh_multiple_messages,
513 { "Multiple messages UDH", "gsm_sms_ud.udh.mm",
514 FT_NONE, BASE_NONE, NULL, 0x00,
515 "Multiple messages User Data Header",
516 HFILL
517 }
518 },
519 #endif
520 { &hf_gsm_sms_udh_multiple_messages_msg_id,
521 { "Message identifier", "gsm_sms_ud.udh.mm.msg_id",
522 FT_UINT16, BASE_DEC, NULL, 0x00,
523 "Identification of the message",
524 HFILL
525 }
526 },
527 { &hf_gsm_sms_udh_multiple_messages_msg_parts,
528 { "Message parts", "gsm_sms_ud.udh.mm.msg_parts",
529 FT_UINT8, BASE_DEC, NULL, 0x00,
530 "Total number of message parts (fragments)",
531 HFILL
532 }
533 },
534 { &hf_gsm_sms_udh_multiple_messages_msg_part,
535 { "Message part number", "gsm_sms_ud.udh.mm.msg_part",
536 FT_UINT8, BASE_DEC, NULL, 0x00,
537 "Message part (fragment) sequence number",
538 HFILL
539 }
540 },
541 #if 0
542 { &hf_gsm_sms_udh_ports,
543 { "Port number UDH", "gsm_sms_ud.udh.ports",
544 FT_NONE, BASE_NONE, NULL, 0x00,
545 "Port number User Data Header",
546 HFILL
547 }
548 },
549 #endif
550 { &hf_gsm_sms_udh_ports_src,
551 { "Source port", "gsm_sms_ud.udh.ports.src",
552 FT_UINT8, BASE_DEC, NULL, 0x00,
553 NULL,
554 HFILL
555 }
556 },
557 { &hf_gsm_sms_udh_ports_dst,
558 { "Destination port", "gsm_sms_ud.udh.ports.dst",
559 FT_UINT8, BASE_DEC, NULL, 0x00,
560 NULL,
561 HFILL
562 }
563 },
564 { &hf_gsm_sms_udh_national_single_shift,
565 { "Language", "gsm_sms_ud.udh.national.single_shift",
566 FT_UINT8, BASE_DEC,
567 VALS(vals_udh_national_languages_single_shift), 0x00,
568 NULL,
569 HFILL
570 }
571 },
572 { &hf_gsm_sms_udh_national_locking_shift,
573 { "Language", "gsm_sms_ud.udh.national.locking_shift",
574 FT_UINT8, BASE_DEC,
575 VALS(vals_udh_national_languages_locking_shift), 0x00,
576 NULL,
577 HFILL
578 }
579 },
580 /*
581 * Short Message fragment reassembly
582 */
583 { &hf_gsm_sms_ud_fragments,
584 { "Short Message fragments", "gsm_sms_ud.fragments",
585 FT_NONE, BASE_NONE, NULL, 0x00,
586 "GSM Short Message fragments",
587 HFILL
588 }
589 },
590 { &hf_gsm_sms_ud_fragment,
591 { "Short Message fragment", "gsm_sms_ud.fragment",
592 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
593 "GSM Short Message fragment",
594 HFILL
595 }
596 },
597 { &hf_gsm_sms_ud_fragment_overlap,
598 { "Short Message fragment overlap", "gsm_sms_ud.fragment.overlap",
599 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
600 "GSM Short Message fragment overlaps with other fragment(s)",
601 HFILL
602 }
603 },
604 { &hf_gsm_sms_ud_fragment_overlap_conflicts,
605 { "Short Message fragment overlapping with conflicting data",
606 "gsm_sms_ud.fragment.overlap.conflicts",
607 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
608 "GSM Short Message fragment overlaps with conflicting data",
609 HFILL
610 }
611 },
612 { &hf_gsm_sms_ud_fragment_multiple_tails,
613 { "Short Message has multiple tail fragments",
614 "gsm_sms_ud.fragment.multiple_tails",
615 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
616 "GSM Short Message fragment has multiple tail fragments",
617 HFILL
618 }
619 },
620 { &hf_gsm_sms_ud_fragment_too_long_fragment,
621 { "Short Message fragment too long",
622 "gsm_sms_ud.fragment.too_long_fragment",
623 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
624 "GSM Short Message fragment data goes beyond the packet end",
625 HFILL
626 }
627 },
628 { &hf_gsm_sms_ud_fragment_error,
629 { "Short Message defragmentation error", "gsm_sms_ud.fragment.error",
630 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
631 "GSM Short Message defragmentation error due to illegal fragments",
632 HFILL
633 }
634 },
635 { &hf_gsm_sms_ud_fragment_count,
636 { "Short Message fragment count", "gsm_sms_ud.fragment.count",
637 FT_UINT32, BASE_DEC, NULL, 0x00,
638 NULL,
639 HFILL
640 }
641 },
642 { &hf_gsm_sms_ud_reassembled_in,
643 { "Reassembled in",
644 "gsm_sms_ud.reassembled.in",
645 FT_FRAMENUM, BASE_NONE, NULL, 0x00,
646 "GSM Short Message has been reassembled in this packet.",
647 HFILL
648 }
649 },
650 { &hf_gsm_sms_ud_reassembled_length,
651 { "Reassembled Short Message length",
652 "gsm_sms_ud.reassembled.length",
653 FT_UINT32, BASE_DEC, NULL, 0x00,
654 "The total length of the reassembled payload",
655 HFILL
656 }
657 },
658 { &hf_gsm_sms_ud_short_msg,
659 { "Short Message body",
660 "gsm_sms_ud.short_msg",
661 FT_BYTES, BASE_NONE, NULL, 0x00, NULL, HFILL
662 }
663 },
664 };
665
666 static gint *ett[] = {
667 &ett_gsm_sms,
668 &ett_udh,
669 &ett_udh_ie,
670 &ett_gsm_sms_ud_fragment,
671 &ett_gsm_sms_ud_fragments,
672 };
673 /* Register the protocol name and description */
674 proto_gsm_sms_ud = proto_register_protocol(
675 "GSM Short Message Service User Data", /* Name */
676 "GSM SMS UD", /* Short name */
677 "gsm_sms_ud"); /* Filter name */
678
679 /* Required function calls to register header fields and subtrees used */
680 proto_register_field_array(proto_gsm_sms_ud, hf, array_length(hf));
681 proto_register_subtree_array(ett, array_length(ett));
682
683 /* Subdissector code */
684 gsm_sms_dissector_table = register_dissector_table("gsm_sms_ud.udh.port",
685 "GSM SMS port IE in UDH", proto_gsm_sms_ud, FT_UINT16, BASE_DEC);
686
687 /* Preferences for GSM SMS UD */
688 gsm_sms_ud_module = prefs_register_protocol(proto_gsm_sms_ud, NULL);
689 /* For reading older preference files with "smpp-gsm-sms." preferences */
690 prefs_register_module_alias("smpp-gsm-sms", gsm_sms_ud_module);
691 prefs_register_bool_preference(gsm_sms_ud_module,
692 "port_number_udh_means_wsp",
693 "Port Number IE in UDH always triggers CL-WSP dissection",
694 "Always decode a GSM Short Message as Connectionless WSP "
695 "if a Port Number Information Element is present "
696 "in the SMS User Data Header.",
697 &port_number_udh_means_wsp);
698 prefs_register_bool_preference(gsm_sms_ud_module, "try_dissect_1st_fragment",
699 "Always try subdissection of 1st Short Message fragment",
700 "Always try subdissection of the 1st fragment of a fragmented "
701 "GSM Short Message. If reassembly is possible, the Short Message "
702 "may be dissected twice (once as a short frame, once in its "
703 "entirety).",
704 &try_dissect_1st_frag);
705 prefs_register_bool_preference(gsm_sms_ud_module, "prevent_dissectors_chg_cols",
706 "Prevent sub-dissectors from changing column data",
707 "Prevent sub-dissectors from replacing column data with their "
708 "own. Eg. Prevent WSP dissector overwriting SMPP information.",
709 &prevent_subdissectors_changing_columns);
710
711 register_dissector("gsm_sms_ud", dissect_gsm_sms_ud, proto_gsm_sms_ud);
712
713 reassembly_table_register(&sm_reassembly_table,
714 &addresses_reassembly_table_functions);
715 }
716
717 void
proto_reg_handoff_gsm_sms_ud(void)718 proto_reg_handoff_gsm_sms_ud(void)
719 {
720 wsp_handle = find_dissector_add_dependency("wsp-cl", proto_gsm_sms_ud);
721 DISSECTOR_ASSERT(wsp_handle);
722 }
723
724 /*
725 * Editor modelines - https://www.wireshark.org/tools/modelines.html
726 *
727 * Local variables:
728 * c-basic-offset: 4
729 * tab-width: 8
730 * indent-tabs-mode: nil
731 * End:
732 *
733 * vi: set shiftwidth=4 tabstop=8 expandtab:
734 * :indentSize=4:tabSize=8:noTabs=true:
735 */
736