wireshark: update SMSCB dissector patch
[osmocom-bb.git] / src / wireshark / smscb.patch
1 Wireshark patch for SMSCB dissection support in LAPDm
2
3 Create a new gsm_smscb dissector module for SMSCB as defined in GSM TS
4 04.12.  Call it from packet-lapdm when the Link Protocol Discriminator
5 has the value "0 1".
6
7 The dissector supports reassembly of SMSCB Message blocks.  Schedule
8 block reassmebly or dissection is not yet implemented.
9
10 Signed-off-by: Alex Badea <vamposdecampos@gmail.com>
11
12  Makefile.common    |    1 
13  packet-gsm_smscb.c |  404 +++++++++++++++++++++++++++++++++++++++++++++++++++++
14  packet-lapdm.c     |   18 +-
15  3 files changed, 420 insertions(+), 3 deletions(-)
16
17 diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common
18 index 1c1e60b..86bc856 100644
19 --- a/epan/dissectors/Makefile.common
20 +++ b/epan/dissectors/Makefile.common
21 @@ -500,6 +500,7 @@ DISSECTOR_SRC = \
22         packet-gsm_bssmap_le.c  \
23         packet-gsm_sms.c        \
24         packet-gsm_sms_ud.c     \
25 +       packet-gsm_smscb.c      \
26         packet-gsm_um.c         \
27         packet-gsmtap.c         \
28         packet-gssapi.c         \
29 diff --git a/epan/dissectors/packet-gsm_smscb.c b/epan/dissectors/packet-gsm_smscb.c
30 new file mode 100644
31 index 0000000..12b98f9
32 --- /dev/null
33 +++ b/epan/dissectors/packet-gsm_smscb.c
34 @@ -0,0 +1,404 @@
35 +/* packet-gsm_smscb.c
36 + * Routines for GSM SMSCB (GSM 04.12) dissection
37 + * Copyright 2010, Alex Badea <vamposdecampos@gmail.com>
38 + *
39 + * $Id$
40 + *
41 + * Wireshark - Network traffic analyzer
42 + * By Gerald Combs <gerald@wireshark.org>
43 + * Copyright 1998 Gerald Combs
44 + *
45 + * Copied from WHATEVER_FILE_YOU_USED (where "WHATEVER_FILE_YOU_USED"
46 + * is a dissector file; if you just copied this from README.developer,
47 + * don't bother with the "Copied from" - you don't even need to put
48 + * in a "Copied from" if you copied an existing dissector, especially
49 + * if the bulk of the code in the new dissector is your code)
50 + *
51 + * This program is free software; you can redistribute it and/or modify
52 + * it under the terms of the GNU General Public License as published by
53 + * the Free Software Foundation; either version 2 of the License, or
54 + * (at your option) any later version.
55 + *
56 + * This program is distributed in the hope that it will be useful,
57 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
58 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
59 + * GNU General Public License for more details.
60 + *
61 + * You should have received a copy of the GNU General Public License along
62 + * with this program; if not, write to the Free Software Foundation, Inc.,
63 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
64 + */
65 +
66 +#ifdef HAVE_CONFIG_H
67 +# include "config.h"
68 +#endif
69 +
70 +#include <glib.h>
71 +
72 +#include <epan/packet.h>
73 +#include <epan/prefs.h>
74 +#include <epan/reassemble.h>
75 +#include <epan/asn1.h>
76 +#include "packet-gsm_map.h"
77 +#include "packet-gsm_sms.h"
78 +
79 +static gint proto_gsm_smscb = -1;
80 +static gint hf_smscb_addr = -1;
81 +static gint hf_smscb_addr_lb = -1;
82 +static gint hf_smscb_addr_seq = -1;
83 +static gint hf_smscb_serial_gs = -1;
84 +static gint hf_smscb_serial_mcode = -1;
85 +static gint hf_smscb_serial_updnum = -1;
86 +static gint hf_smscb_page_num = -1;
87 +static gint hf_smscb_page_cnt = -1;
88 +static gint hf_smscb_msgid = -1;
89 +static gint hf_smscb_content = -1;
90 +static gint hf_smscb_fragments = -1;
91 +static gint hf_smscb_fragment = -1;
92 +static gint hf_smscb_fragment_overlap = -1;
93 +static gint hf_smscb_fragment_overlap_conflicts = -1;
94 +static gint hf_smscb_fragment_multiple_tails = -1;
95 +static gint hf_smscb_fragment_too_long_fragment = -1;
96 +static gint hf_smscb_fragment_error = -1;
97 +static gint hf_smscb_reassembled_in = -1;
98 +static gint hf_smscb_reassembled_length = -1;
99 +
100 +static gint ett_smscb = -1;
101 +static gint ett_smscb_addr = -1;
102 +static gint ett_smscb_dcs = -1;
103 +static gint ett_smscb_fragment = -1;
104 +static gint ett_smscb_fragments = -1;
105 +
106 +static GHashTable *smscb_fragment_table = NULL;
107 +static GHashTable *smscb_reassembled_table = NULL;
108 +
109 +static gboolean reassemble_smscb = TRUE;
110 +
111 +static dissector_handle_t data_handle;
112 +
113 +#define SMSCB_HDR_MINLEN       1
114 +
115 +/*
116 + * Bits in the address field.
117 + */
118 +#define        SMSCB_ADDR_LB           0x10    /* Address Last Bit */
119 +#define        SMSCB_ADDR_SEQ          0x0f    /* Address sequence number */
120 +#define        SMSCB_SERIAL_GS         0xc0    /* CBS Serial Number - Geographical Scope */
121 +#define        SMSCB_SERIAL_MCODE      0x3ffc  /* CBS Serial Number - Message Code */
122 +#define        SMSCB_SERIAL_UPDNUM     0x03    /* CBS Serial Number - Update Number */
123 +#define        SMSCB_PAGE_NUM          0xf0    /* Page number */
124 +#define        SMSCB_PAGE_CNT          0x0f    /* Page total count */
125 +
126 +#define SMSCB_SEQ_LAST         3
127 +
128 +/* 04.12 section 3.3.1 */
129 +static const value_string smscb_addr_lb_vals[] = {
130 +       { 0,            "More blocks" },
131 +       { 1,            "Last block" },
132 +       { 0,            NULL }
133 +};
134 +
135 +/* 04.12 section 3.3.1 */
136 +static const value_string smscb_addr_seq_vals[] = {
137 +       { 0,            "First block" },
138 +       { 1,            "Second block" },
139 +       { 2,            "Third block" },
140 +       { 3,            "Fourth block" },
141 +       { 8,            "First schedule block" },
142 +       { 15,           "Null message" },
143 +       { 0,            NULL }
144 +};
145 +
146 +/* 03.41 section 9.3.2.1 */
147 +static const value_string smscb_serial_gs_vals[] = {
148 +       { 0,            "Cell wide (immediate)" },
149 +       { 1,            "PLMN wide" },
150 +       { 2,            "Location Area wide" },
151 +       { 3,            "Cell wide" },
152 +       { 0,            NULL }
153 +};
154 +
155 +
156 +static const fragment_items smscb_frag_items = {
157 +       /* Fragment subtrees */
158 +       &ett_smscb_fragment,
159 +       &ett_smscb_fragments,
160 +       /* Fragment fields */
161 +       &hf_smscb_fragments,
162 +       &hf_smscb_fragment,
163 +       &hf_smscb_fragment_overlap,
164 +       &hf_smscb_fragment_overlap_conflicts,
165 +       &hf_smscb_fragment_multiple_tails,
166 +       &hf_smscb_fragment_too_long_fragment,
167 +       &hf_smscb_fragment_error,
168 +       /* Reassembled in field */
169 +       &hf_smscb_reassembled_in,
170 +       /* Reassembled length field */
171 +       &hf_smscb_reassembled_length,
172 +       /* Tag */
173 +       "fragments"
174 +};
175 +
176 +static void smscb_defragment_init(void)
177 +{
178 +       fragment_table_init(&smscb_fragment_table);
179 +       reassembled_table_init(&smscb_reassembled_table);
180 +}
181 +
182 +/* [3GPP TS 03.41 section 9.3] */
183 +static int dissect_smscb_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
184 +{
185 +       proto_item *ti;
186 +       gint offset = 0;
187 +       gint length, out_len, textlen;
188 +       guint8 encoding;
189 +       gchar msgbuf[88 + 1];
190 +       gchar *utf8_text, *p;
191 +
192 +       proto_tree_add_item(tree, hf_smscb_serial_gs, tvb, offset, 1, ENC_NA);
193 +       proto_tree_add_item(tree, hf_smscb_serial_mcode, tvb, offset, 2, ENC_NA);
194 +       offset++;
195 +       proto_tree_add_item(tree, hf_smscb_serial_updnum, tvb, offset, 1, ENC_NA);
196 +       offset++;
197 +       proto_tree_add_item(tree, hf_smscb_msgid, tvb, offset, 1, ENC_BIG_ENDIAN);
198 +       offset += 2;
199 +       ti = proto_tree_add_text(tree, tvb, offset, 1, "Data Coding Scheme");
200 +       encoding = dissect_cbs_data_coding_scheme(
201 +               tvb_new_subset(tvb, offset, 1, -1), pinfo,
202 +               proto_item_add_subtree(ti, ett_smscb_dcs));
203 +       offset++;
204 +       proto_tree_add_item(tree, hf_smscb_page_num, tvb, offset, 1, ENC_NA);
205 +       proto_tree_add_item(tree, hf_smscb_page_cnt, tvb, offset, 1, ENC_NA);
206 +       offset++;
207 +
208 +       length = tvb_length(tvb) - offset;
209 +       switch (encoding) {
210 +       case SMS_ENCODING_7BIT:
211 +       case SMS_ENCODING_7BIT_LANG:
212 +               out_len = gsm_sms_char_7bit_unpack(0, length, sizeof(msgbuf) - 1,
213 +                               tvb_get_ptr(tvb, offset, length), msgbuf);
214 +               msgbuf[out_len] = '\0';
215 +               utf8_text = gsm_sms_chars_to_utf8(msgbuf, out_len);
216 +               textlen = strlen(utf8_text);
217 +               break;
218 +       /* TODO: UCS2? */
219 +       case SMS_ENCODING_8BIT:
220 +       default:
221 +               utf8_text = tvb_get_ephemeral_string(tvb, offset, length);
222 +               textlen = length;
223 +               break;
224 +       }
225 +
226 +       proto_tree_add_string(tree, hf_smscb_content, tvb, offset, length, utf8_text);
227 +
228 +       /* strip padding */
229 +       if ((p = strchr( utf8_text, '\r')))
230 +               *p = 0;
231 +       col_append_fstr(pinfo->cinfo, COL_INFO, " \"%s\"", utf8_text);
232 +
233 +       return tvb_length(tvb);
234 +}
235 +
236 +static int dissect_gsm_smscb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
237 +{
238 +       proto_item *ti;
239 +       proto_tree *gsm_smscb_tree = NULL;
240 +       proto_tree *subtree = NULL;
241 +       guint8 addr, seq, more;
242 +       tvbuff_t *payload;
243 +
244 +       if (tvb_length(tvb) < SMSCB_HDR_MINLEN)
245 +               return 0;
246 +
247 +       addr = tvb_get_guint8(tvb, 0);
248 +       seq = addr & SMSCB_ADDR_SEQ;
249 +       more = !(addr & SMSCB_ADDR_LB) && seq < SMSCB_SEQ_LAST;
250 +
251 +       col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMSCB");
252 +
253 +       col_clear(pinfo->cinfo, COL_INFO);
254 +       col_append_fstr(pinfo->cinfo, COL_INFO, "seq=%d", seq);
255 +
256 +       if (tree) {
257 +               ti = proto_tree_add_item(tree, proto_gsm_smscb, tvb, 0, -1, ENC_NA);
258 +               gsm_smscb_tree = proto_item_add_subtree(ti, ett_smscb);
259 +
260 +               ti = proto_tree_add_item(gsm_smscb_tree, hf_smscb_addr, tvb, 0, 1, ENC_NA);
261 +               subtree = proto_item_add_subtree(ti, ett_smscb_addr);
262 +               proto_tree_add_item(subtree, hf_smscb_addr_lb, tvb, 0, 1, ENC_NA);
263 +               proto_tree_add_item(subtree, hf_smscb_addr_seq, tvb, 0, 1, ENC_NA);
264 +       }
265 +
266 +       payload = tvb_new_subset(tvb, 1, -1, -1);
267 +
268 +       if (reassemble_smscb && seq <= SMSCB_SEQ_LAST) {
269 +               fragment_data *frag;
270 +               guint32 frag_id = 0x42;
271 +               guchar expected_seq = 0;
272 +               tvbuff_t *reassembled = NULL;
273 +               gboolean save_fragmented = pinfo->fragmented;
274 +
275 +               frag = fragment_get(pinfo, frag_id, smscb_fragment_table);
276 +               if (frag) {
277 +                       while (frag->next)
278 +                               frag = frag->next;
279 +                       expected_seq = frag->offset + 1;
280 +               }
281 +
282 +               /*
283 +                * TS 03.41 section 8 says we should discard sequences
284 +                * which do not consist of consecutive blocks
285 +                */
286 +               if (seq != expected_seq)
287 +                       g_free(fragment_delete(pinfo, frag_id, smscb_fragment_table));
288 +
289 +               pinfo->fragmented = more;
290 +               frag = fragment_add_seq_check(payload, 0, pinfo, frag_id,
291 +                       smscb_fragment_table,
292 +                       smscb_reassembled_table, seq,
293 +                       tvb_length(payload),
294 +                       more);
295 +
296 +               reassembled = process_reassembled_data(payload, 0, pinfo,
297 +                       "Reassembled SMSCB", frag, &smscb_frag_items, NULL,
298 +                       gsm_smscb_tree);
299 +
300 +               if (frag && pinfo->fd->num == frag->reassembled_in) {
301 +                       dissect_smscb_message(reassembled, pinfo, gsm_smscb_tree);
302 +               } else {
303 +                       col_append_str(pinfo->cinfo, COL_INFO, " (Fragment)");
304 +                       proto_tree_add_text(gsm_smscb_tree, payload, 0, -1, "Fragment Data");
305 +               }
306 +
307 +               pinfo->fragmented = save_fragmented;
308 +       } else if (seq == 0) {
309 +               dissect_smscb_message(payload, pinfo, gsm_smscb_tree);
310 +       } else {
311 +               /* TODO: reassemble & dissect Schedule messages */
312 +               call_dissector(data_handle, payload, pinfo, tree);
313 +       }
314 +
315 +       return tvb_length(tvb);
316 +}
317 +
318 +static hf_register_info hf[] = {
319 +       { &hf_smscb_addr, {
320 +               "Address Field", "smscb.addr", FT_UINT8, BASE_HEX,
321 +               NULL, 0x0,
322 +               "Address", HFILL,
323 +       }},
324 +       { &hf_smscb_addr_lb, {
325 +               "LB", "smscb.addr.lb", FT_UINT8, BASE_DEC,
326 +               VALS(smscb_addr_lb_vals), SMSCB_ADDR_LB,
327 +               "Last Block bit", HFILL,
328 +       }},
329 +       { &hf_smscb_addr_seq, {
330 +               "SEQ", "smscb.addr.seq", FT_UINT8, BASE_DEC,
331 +               VALS(smscb_addr_seq_vals), SMSCB_ADDR_SEQ,
332 +               "Sequence Number", HFILL,
333 +       }},
334 +
335 +       { &hf_smscb_serial_gs, {
336 +               "Geographic Scope", "smscb.serial.gs", FT_UINT8, BASE_DEC,
337 +               VALS(smscb_serial_gs_vals), SMSCB_SERIAL_GS, NULL, HFILL,
338 +       }},
339 +       { &hf_smscb_serial_mcode, {
340 +               "Message Code", "smscb.serial.mcode", FT_UINT16, BASE_DEC,
341 +               NULL, SMSCB_SERIAL_MCODE, NULL, HFILL,
342 +       }},
343 +       { &hf_smscb_serial_updnum, {
344 +               "Update Number", "smscb.serial.updnum", FT_UINT8, BASE_DEC,
345 +               NULL, SMSCB_SERIAL_MCODE, NULL, HFILL,
346 +       }},
347 +
348 +       { &hf_smscb_msgid, {
349 +               "Message Identifier", "smscb.msgid", FT_UINT16, BASE_DEC,
350 +               NULL, 0, NULL, HFILL,
351 +       }},
352 +
353 +       { &hf_smscb_page_num, {
354 +               "Page number", "smscb.page.num", FT_UINT8, BASE_DEC,
355 +               NULL, SMSCB_PAGE_NUM, NULL, HFILL,
356 +       }},
357 +       { &hf_smscb_page_cnt, {
358 +               "Total pages", "smscb.page.cnt", FT_UINT8, BASE_DEC,
359 +               NULL, SMSCB_PAGE_CNT, NULL, HFILL,
360 +       }},
361 +       { &hf_smscb_content, {
362 +               "Content of Message", "smscb.content", FT_STRING, BASE_NONE,
363 +               NULL, 0x00, NULL, HFILL,
364 +       }},
365 +
366 +       /* Fragment reassembly */
367 +       { &hf_smscb_fragments, {
368 +               "Message fragments", "smscb.fragments",
369 +               FT_NONE, BASE_NONE, NULL, 0x00,
370 +               "SMSCB Message fragments", HFILL,
371 +       }},
372 +       { &hf_smscb_fragment, {
373 +               "Message fragment", "smscb.fragment",
374 +               FT_FRAMENUM, BASE_NONE, NULL, 0x00,
375 +               "SMSCB Message fragment", HFILL,
376 +       }},
377 +       { &hf_smscb_fragment_overlap, {
378 +               "Message fragment overlap", "smscb.fragment.overlap",
379 +               FT_BOOLEAN, BASE_NONE, NULL, 0x0,
380 +               "SMSCB Message fragment overlaps with other fragment(s)", HFILL,
381 +       }},
382 +       { &hf_smscb_fragment_overlap_conflicts, {
383 +               "Message fragment overlapping with conflicting data", "smscb.fragment.overlap.conflicts",
384 +               FT_BOOLEAN, BASE_NONE, NULL, 0x0,
385 +               "SMSCB Message fragment overlaps with conflicting data", HFILL,
386 +       }},
387 +       { &hf_smscb_fragment_multiple_tails, {
388 +               "Message has multiple tail fragments", "smscb.fragment.multiple_tails",
389 +               FT_BOOLEAN, BASE_NONE, NULL, 0x0,
390 +               "SMSCB Message fragment has multiple tail fragments", HFILL,
391 +       }},
392 +       { &hf_smscb_fragment_too_long_fragment, {
393 +               "Message fragment too long", "smscb.fragment.too_long_fragment",
394 +               FT_BOOLEAN, BASE_NONE, NULL, 0x0,
395 +               "SMSCB Message fragment data goes beyond the packet end", HFILL,
396 +       }},
397 +       { &hf_smscb_fragment_error, {
398 +               "Message defragmentation error", "smscb.fragment.error",
399 +               FT_FRAMENUM, BASE_NONE, NULL, 0x00,
400 +               "SMSCB Message defragmentation error due to illegal fragments", HFILL,
401 +       }},
402 +       { &hf_smscb_reassembled_in, {
403 +               "Reassembled in", "smscb.reassembled.in",
404 +               FT_FRAMENUM, BASE_NONE, NULL, 0x00,
405 +               "SMSCB Message has been reassembled in this packet.", HFILL,
406 +       }},
407 +       { &hf_smscb_reassembled_length, {
408 +               "Reassembled SMSCB length", "smscb.reassembled.length",
409 +               FT_UINT32, BASE_DEC, NULL, 0x00,
410 +               "The total length of the reassembled payload", HFILL,
411 +       }},
412 +};
413 +
414 +static gint *ett[] = {
415 +       &ett_smscb,
416 +       &ett_smscb_addr,
417 +       &ett_smscb_dcs,
418 +       &ett_smscb_fragment,
419 +       &ett_smscb_fragments,
420 +};
421 +
422 +void proto_reg_handoff_gsm_smscb(void)
423 +{
424 +       data_handle = find_dissector("data");
425 +}
426 +
427 +void proto_register_gsm_smscb(void)
428 +{
429 +       proto_gsm_smscb = proto_register_protocol(
430 +               "Short Message Service Cell Broadcast",
431 +               "SMSCB", "gsm_smscb");
432 +
433 +       proto_register_field_array(proto_gsm_smscb, hf, array_length(hf));
434 +       proto_register_subtree_array(ett, array_length(ett));
435 +
436 +       new_register_dissector("gsm_smscb", dissect_gsm_smscb, proto_gsm_smscb);
437 +       register_init_routine(smscb_defragment_init);
438 +}
439 diff --git a/epan/dissectors/packet-lapdm.c b/epan/dissectors/packet-lapdm.c
440 index dbeac85..add859d 100644
441 --- a/epan/dissectors/packet-lapdm.c
442 +++ b/epan/dissectors/packet-lapdm.c
443 @@ -110,6 +110,7 @@ static GHashTable *lapdm_reassembled_table = NULL;
444  static dissector_table_t lapdm_sapi_dissector_table;
445  
446  static dissector_handle_t data_handle;
447 +static dissector_handle_t smscb_handle;
448  
449  static gboolean reassemble_lapdm = TRUE;
450  
451 @@ -121,6 +122,7 @@ static gboolean reassemble_lapdm = TRUE;
452  #define        LAPDM_CR                0x02    /* Command/Response bit */
453  #define        LAPDM_EA                0x01    /* First Address Extension bit */
454  #define        LAPDM_LPD               0x60    /* Link Protocol Discriminator */
455 +#define        LAPDM_LPD_CB            0x20    /* Cell Broadcast LPD */
456  
457  /*
458   * Bits in the length field.
459 @@ -219,6 +221,7 @@ dissect_lapdm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
460      tvbuff_t *payload;
461      int available_length;
462      gboolean is_response = FALSE;
463 +    gboolean is_cbs = FALSE;
464  
465      /* Check that there's enough data */
466      if (tvb_length(tvb) < LAPDM_HEADER_LEN)
467 @@ -229,6 +232,7 @@ dissect_lapdm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
468      addr = tvb_get_guint8(tvb, 0);
469      length = tvb_get_guint8(tvb, 2);
470  
471 +    is_cbs = (addr & LAPDM_LPD) == LAPDM_LPD_CB;
472      cr = addr & LAPDM_CR;
473      if (pinfo->p2p_dir == P2P_DIR_RECV) {
474          is_response = cr ? FALSE : TRUE;
475 @@ -245,15 +249,22 @@ dissect_lapdm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
476          addr_tree = proto_item_add_subtree(addr_ti, ett_lapdm_address);
477  
478          proto_tree_add_uint(addr_tree, hf_lapdm_lpd, tvb, 0, 1, addr);
479 -        proto_tree_add_uint(addr_tree, hf_lapdm_sapi, tvb, 0, 1, addr);
480 -        proto_tree_add_uint(addr_tree, hf_lapdm_cr, tvb, 0, 1, addr);
481 -        proto_tree_add_uint(addr_tree, hf_lapdm_ea, tvb, 0, 1, addr);
482 +        if (!is_cbs) {
483 +            proto_tree_add_uint(addr_tree, hf_lapdm_sapi, tvb, 0, 1, addr);
484 +            proto_tree_add_uint(addr_tree, hf_lapdm_cr, tvb, 0, 1, addr);
485 +            proto_tree_add_uint(addr_tree, hf_lapdm_ea, tvb, 0, 1, addr);
486 +        }
487      }
488      else {
489          lapdm_ti = NULL;
490          lapdm_tree = NULL;
491      }
492  
493 +    if (is_cbs) {
494 +        call_dissector(smscb_handle, tvb, pinfo, tree);
495 +        return;
496 +    }
497 +
498      control = dissect_xdlc_control(tvb, 1, pinfo, lapdm_tree, hf_lapdm_control,
499                ett_lapdm_control, &lapdm_cf_items, NULL /* LAPDm doesnt support extended */, NULL, NULL,
500                is_response, FALSE, FALSE);
501 @@ -486,5 +497,6 @@ void
502  proto_reg_handoff_lapdm(void)
503  {
504      data_handle = find_dissector("data");
505 +    smscb_handle = find_dissector("gsm_smscb");
506  }
507