1 Wireshark patch for SMSCB dissection support in LAPDm
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
7 Signed-off-by: Alex Badea <vamposdecampos@gmail.com>
9 epan/dissectors/Makefile.common | 1 +
10 epan/dissectors/packet-gsm_smscb.c | 642 ++++++++++++++++++++++++++++++++++++
11 epan/dissectors/packet-lapdm.c | 18 +-
12 3 files changed, 658 insertions(+), 3 deletions(-)
14 diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common
15 index 9f9a602..5684579 100644
16 --- a/epan/dissectors/Makefile.common
17 +++ b/epan/dissectors/Makefile.common
18 @@ -500,6 +500,7 @@ DISSECTOR_SRC = \
19 packet-gsm_bssmap_le.c \
22 + packet-gsm_smscb.c \
26 diff --git a/epan/dissectors/packet-gsm_smscb.c b/epan/dissectors/packet-gsm_smscb.c
28 index 0000000..a2f8bee
30 +++ b/epan/dissectors/packet-gsm_smscb.c
32 +/* packet-gsm_smscb.c
33 + * Routines for GSM SMSCB (GSM 04.12) dissection
34 + * Copyright 2010, Alex Badea <vamposdecampos@gmail.com>
38 + * Wireshark - Network traffic analyzer
39 + * By Gerald Combs <gerald@wireshark.org>
40 + * Copyright 1998 Gerald Combs
42 + * This program is free software; you can redistribute it and/or modify
43 + * it under the terms of the GNU General Public License as published by
44 + * the Free Software Foundation; either version 2 of the License, or
45 + * (at your option) any later version.
47 + * This program is distributed in the hope that it will be useful,
48 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
49 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
50 + * GNU General Public License for more details.
52 + * You should have received a copy of the GNU General Public License along
53 + * with this program; if not, write to the Free Software Foundation, Inc.,
54 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
63 +#include <epan/packet.h>
64 +#include <epan/prefs.h>
65 +#include <epan/reassemble.h>
66 +#include <epan/asn1.h>
67 +#include "packet-gsm_map.h"
68 +#include "packet-gsm_sms.h"
70 +static gint proto_gsm_smscb = -1;
71 +static gint hf_smscb_addr = -1;
72 +static gint hf_smscb_addr_lb = -1;
73 +static gint hf_smscb_addr_seq = -1;
74 +static gint hf_smscb_serial_gs = -1;
75 +static gint hf_smscb_serial_mcode = -1;
76 +static gint hf_smscb_serial_updnum = -1;
77 +static gint hf_smscb_page_num = -1;
78 +static gint hf_smscb_page_cnt = -1;
79 +static gint hf_smscb_msgid = -1;
80 +static gint hf_smscb_content = -1;
81 +static gint hf_smscb_fragments = -1;
82 +static gint hf_smscb_fragment = -1;
83 +static gint hf_smscb_fragment_overlap = -1;
84 +static gint hf_smscb_fragment_overlap_conflicts = -1;
85 +static gint hf_smscb_fragment_multiple_tails = -1;
86 +static gint hf_smscb_fragment_too_long_fragment = -1;
87 +static gint hf_smscb_fragment_error = -1;
88 +static gint hf_smscb_reassembled_in = -1;
89 +static gint hf_smscb_reassembled_length = -1;
90 +static gint hf_smscb_sched_type = -1;
91 +static gint hf_smscb_sched_spare = -1;
92 +static gint hf_smscb_sched_begin_slot = -1;
93 +static gint hf_smscb_sched_end_slot = -1;
94 +static gint hf_smscb_sched_mdt1 = -1;
95 +static gint hf_smscb_sched_mdt2 = -1;
96 +static gint hf_smscb_sched_mdt8 = -1;
97 +static gint hf_smscb_sched_msgid = -1;
98 +static gint hf_smscb_sched_repslot = -1;
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 +static gint ett_smscb_sched_new = -1;
106 +static gint ett_smscb_sched_other = -1;
107 +static gint ett_smscb_sched_slot = -1;
109 +static GHashTable *smscb_fragment_table = NULL;
110 +static GHashTable *smscb_reassembled_table = NULL;
112 +static gboolean reassemble_smscb = TRUE;
114 +static dissector_handle_t data_handle;
116 +#define SMSCB_HDR_MINLEN 1
119 + * Bits in the address field.
121 +#define SMSCB_ADDR_LB 0x10 /* Address Last Bit */
122 +#define SMSCB_ADDR_SEQ 0x0f /* Address sequence number */
123 +#define SMSCB_SERIAL_GS 0xc000 /* CBS Serial Number - Geographical Scope */
124 +#define SMSCB_SERIAL_MCODE 0x3ff0 /* CBS Serial Number - Message Code */
125 +#define SMSCB_SERIAL_UPDNUM 0x000f /* CBS Serial Number - Update Number */
126 +#define SMSCB_PAGE_NUM 0xf0 /* Page number */
127 +#define SMSCB_PAGE_CNT 0x0f /* Page total count */
130 + * Bits in the Schedule message
132 +#define SMSCB_SCHED_TYPE 0xc0 /* Type */
133 +#define SMSCB_SCHED_SLOT 0x3f /* Begin/End Slot Number */
134 +#define SMSCB_SCHED_SPARE 0xc0 /* Spare */
135 +#define SMSCB_SCHED_MDT1 0x8000 /* MDT (1 bit)*/
136 +#define SMSCB_SCHED_MSGID 0x7fff /* Message ID */
137 +#define SMSCB_SCHED_MDT2 0xc0 /* MDT (2 bits) */
138 +#define SMSCB_SCHED_REPSLOT 0x3f /* Repeated Slot Number */
140 +#define SMSCB_SEQ_LAST 3
141 +#define SMSCB_SEQ_1ST 0
142 +#define SMSCB_SEQ_1ST_SCHED 8
144 +#define SMSCB_SCHED_SLOT_MAX 48
146 +/* 04.12 section 3.3.1 */
147 +static const value_string smscb_addr_lb_vals[] = {
148 + { 0, "More blocks" },
149 + { 1, "Last block" },
153 +/* 04.12 section 3.3.1 */
154 +static const value_string smscb_addr_seq_vals[] = {
155 + { 0, "First block" },
156 + { 1, "Second block" },
157 + { 2, "Third block" },
158 + { 3, "Fourth block" },
159 + { 8, "First schedule block" },
160 + { 15, "Null message" },
164 +/* 03.41 section 9.3.2.1 */
165 +static const value_string smscb_serial_gs_vals[] = {
166 + { 0, "Cell wide (immediate)" },
167 + { 1, "PLMN wide" },
168 + { 2, "Location Area wide" },
169 + { 3, "Cell wide" },
173 +/* 04.14 section 3.5.5 */
174 +static const value_string smscb_sched_mdt8_vals[] = {
175 + { 0x00, "Retransmission indication" },
176 + { 0x80, "First transmission of an SMSCB within the Schedule Period" },
177 + { 0x40, "Free Message Slot, optional reading" },
178 + { 0x41, "Free Message Slot, reading advised" },
182 +static const fragment_items smscb_frag_items = {
183 + /* Fragment subtrees */
184 + &ett_smscb_fragment,
185 + &ett_smscb_fragments,
186 + /* Fragment fields */
187 + &hf_smscb_fragments,
188 + &hf_smscb_fragment,
189 + &hf_smscb_fragment_overlap,
190 + &hf_smscb_fragment_overlap_conflicts,
191 + &hf_smscb_fragment_multiple_tails,
192 + &hf_smscb_fragment_too_long_fragment,
193 + &hf_smscb_fragment_error,
194 + /* Reassembled in field */
195 + &hf_smscb_reassembled_in,
196 + /* Reassembled length field */
197 + &hf_smscb_reassembled_length,
202 +static void smscb_defragment_init(void)
204 + fragment_table_init(&smscb_fragment_table);
205 + reassembled_table_init(&smscb_reassembled_table);
208 +/* [3GPP TS 03.41 section 9.3] */
209 +static int dissect_smscb_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
213 + gint length, out_len, textlen;
215 + gchar msgbuf[88 + 1];
216 + gchar *utf8_text, *p;
218 + proto_tree_add_item(tree, hf_smscb_serial_gs, tvb, offset, 1, ENC_NA);
219 + proto_tree_add_item(tree, hf_smscb_serial_mcode, tvb, offset, 2, ENC_NA);
221 + proto_tree_add_item(tree, hf_smscb_serial_updnum, tvb, offset, 1, ENC_NA);
223 + proto_tree_add_item(tree, hf_smscb_msgid, tvb, offset, 2, ENC_BIG_ENDIAN);
224 + col_append_fstr(pinfo->cinfo, COL_INFO, " - Message ID %d", tvb_get_ntohs(tvb, offset));
226 + ti = proto_tree_add_text(tree, tvb, offset, 1, "Data Coding Scheme");
227 + encoding = dissect_cbs_data_coding_scheme(
228 + tvb_new_subset(tvb, offset, 1, -1), pinfo,
229 + proto_item_add_subtree(ti, ett_smscb_dcs));
231 + proto_tree_add_item(tree, hf_smscb_page_num, tvb, offset, 1, ENC_NA);
232 + proto_tree_add_item(tree, hf_smscb_page_cnt, tvb, offset, 1, ENC_NA);
235 + length = tvb_length(tvb) - offset;
236 + switch (encoding) {
237 + case SMS_ENCODING_7BIT:
238 + case SMS_ENCODING_7BIT_LANG:
239 + out_len = gsm_sms_char_7bit_unpack(0, length, sizeof(msgbuf) - 1,
240 + tvb_get_ptr(tvb, offset, length), msgbuf);
241 + msgbuf[out_len] = '\0';
242 + utf8_text = gsm_sms_chars_to_utf8(msgbuf, out_len);
243 + textlen = strlen(utf8_text);
246 + case SMS_ENCODING_8BIT:
248 + utf8_text = tvb_get_ephemeral_string(tvb, offset, length);
253 + proto_tree_add_string(tree, hf_smscb_content, tvb, offset, length, utf8_text);
255 + /* strip padding */
256 + if ((p = strchr( utf8_text, '\r')))
258 + col_append_fstr(pinfo->cinfo, COL_INFO, " \"%s\"", utf8_text);
260 + return tvb_length(tvb);
263 +/* [3GPP TS 04.14 section 3.5.5] */
264 +static int dissect_sched_msg_desc(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
265 + gint *slot_list, gint slot_count)
270 + proto_tree *subtree;
273 + for (k = 0; k < slot_count; k++) {
274 + mdt = tvb_get_guint8(tvb, offset);
278 + else if (!(mdt & 0x40))
281 + ti = proto_tree_add_text(tree, tvb, offset, 1, "Slot %d - %s",
283 + val_to_str(mdt, smscb_sched_mdt8_vals, "Unknown (0x%02x)"));
284 + subtree = proto_item_add_subtree(ti, ett_smscb_sched_slot);
287 + guint16 msgid = tvb_get_ntohs(tvb, offset) & SMSCB_SCHED_MSGID;
288 + proto_item_append_text(ti, " (message ID %d)", msgid);
289 + proto_item_set_len(ti, 2);
290 + proto_tree_add_item(subtree, hf_smscb_sched_mdt1, tvb, offset, 2, ENC_BIG_ENDIAN);
291 + proto_tree_add_item(subtree, hf_smscb_sched_msgid, tvb, offset, 2, ENC_BIG_ENDIAN);
293 + } else if (!(mdt & 0xc0)) {
294 + guint8 slot = tvb_get_guint8(tvb, offset) & SMSCB_SCHED_SLOT;
295 + proto_item_append_text(ti, " (slot %d)", slot);
296 + proto_tree_add_item(subtree, hf_smscb_sched_mdt2, tvb, offset, 1, ENC_NA);
297 + proto_tree_add_item(subtree, hf_smscb_sched_repslot, tvb, offset, 1, ENC_NA);
300 + proto_tree_add_item(subtree, hf_smscb_sched_mdt8, tvb, offset, 1, ENC_NA);
307 +/* [3GPP TS 04.14 section 3.5] */
308 +static int dissect_sched_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
312 + gint first, last, nm, len;
313 + gint new_count = 0;
314 + gint other_count = 0;
315 + gint new_list[SMSCB_SCHED_SLOT_MAX];
316 + gint other_list[SMSCB_SCHED_SLOT_MAX];
318 + col_append_str(pinfo->cinfo, COL_INFO, " - Schedule message");
320 + proto_tree_add_item(tree, hf_smscb_sched_type, tvb, offset, 1, ENC_NA);
321 + proto_tree_add_item(tree, hf_smscb_sched_begin_slot, tvb, offset, 1, ENC_NA);
323 + proto_tree_add_item(tree, hf_smscb_sched_spare, tvb, offset, 1, ENC_NA);
324 + proto_tree_add_item(tree, hf_smscb_sched_end_slot, tvb, offset, 1, ENC_NA);
327 + first = tvb_get_guint8(tvb, 0) & SMSCB_SCHED_SLOT;
328 + last = tvb_get_guint8(tvb, 1) & SMSCB_SCHED_SLOT;
329 + last = MIN(last, SMSCB_SCHED_SLOT_MAX);
331 + ti = proto_tree_add_text(tree, tvb, offset, 6, "List of new message slots =");
332 + for (nm = first; nm <= last; nm++) {
333 + if (tvb_get_bits8(tvb, offset * 8 + nm - first, 1)) {
334 + proto_item_append_text(ti, " %d", nm);
335 + new_list[new_count++] = nm;
337 + other_list[other_count++] = nm;
342 + ti = proto_tree_add_text(tree, tvb, offset, 0, "New Message Descriptions");
343 + len = dissect_sched_msg_desc(tvb_new_subset(tvb, offset, -1, -1), pinfo,
344 + proto_item_add_subtree(ti, ett_smscb_sched_new),
345 + new_list, new_count);
347 + proto_item_set_len(ti, len);
349 + ti = proto_tree_add_text(tree, tvb, offset, 0, "Other Message Descriptions");
350 + len = dissect_sched_msg_desc(tvb_new_subset(tvb, offset, -1, -1), pinfo,
351 + proto_item_add_subtree(ti, ett_smscb_sched_other),
352 + other_list, other_count);
354 + proto_item_set_len(ti, len);
359 +static inline int seq_any_frags(guint8 seq)
361 + return seq <= SMSCB_SEQ_LAST || seq == SMSCB_SEQ_1ST_SCHED;
364 +static inline int seq_more_frags(guint8 seq)
366 + return seq < SMSCB_SEQ_LAST || seq == SMSCB_SEQ_1ST_SCHED;
369 +static inline int seq_first(guint8 seq)
371 + return seq == SMSCB_SEQ_1ST || seq == SMSCB_SEQ_1ST_SCHED;
374 +static inline int seq_bits(guint8 seq)
380 + * Do the reassembly thing.
382 + * SMSCB fragmentation doesn't really fit in with the wireshark
383 + * reassembler. There are only two valid fragment sequences:
384 + * i) 0,1,2,3 for a SMSCB message
385 + * ii) 8,1,2,3 for a schedule message
387 + * We can't use different fragment-IDs for each content type,
388 + * since the last 3 blocks have identical sequence numbers.
390 + * We can't just mask the lower 2 bits, because when reassembly
391 + * completes (which is on the last block, sequence #3) we won't
392 + * know which content type we've reassembled.
394 + * We also can't munge e.g. the schedule sequence to 8,9,10,11,
395 + * since the reassembler will think we're missing the first 8
396 + * blocks and not do anything.
398 + * Also, according to TS 03.41 section 8 we must discard
399 + * non-consecutive sequences.
401 + * So the approach here is to include the address header byte
402 + * in the first fragment. This way after reassembly we can peek
403 + * at it and dissect accordingly.
405 + * A clean implementation would likely be to add a FD_* reassembler
406 + * flag to special-case this behaviour.
408 +static tvbuff_t *smscb_try_reassembly(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
409 + guint8 *seq_p, guint8 more)
411 + guint8 seq = *seq_p;
412 + fragment_data *frag;
413 + guint32 frag_id = 0x42;
414 + guchar expected_seq = 0;
415 + tvbuff_t *reassembled = NULL;
416 + gboolean save_fragmented = pinfo->fragmented;
418 + if (!reassemble_smscb || !seq_any_frags(seq))
421 + frag = fragment_get(pinfo, frag_id, smscb_fragment_table);
425 + expected_seq = frag->offset + 1;
428 + if (seq != expected_seq)
429 + g_free(fragment_delete(pinfo, frag_id, smscb_fragment_table));
431 + if (!seq_first(seq))
432 + tvb = tvb_new_subset(tvb, 1, -1, -1);
434 + pinfo->fragmented = more;
435 + frag = fragment_add_seq_check(tvb, 0, pinfo, frag_id,
436 + smscb_fragment_table,
437 + smscb_reassembled_table, seq_bits(seq),
441 + reassembled = process_reassembled_data(tvb, 0, pinfo,
442 + "Reassembled SMSCB", frag, &smscb_frag_items, NULL, tree);
444 + if (frag && pinfo->fd->num == frag->reassembled_in) {
445 + *seq_p = tvb_get_guint8(reassembled, 0) & SMSCB_ADDR_SEQ;
446 + reassembled = tvb_new_subset(reassembled, 1, -1, -1);
448 + col_append_str(pinfo->cinfo, COL_INFO, " (Fragment)");
449 + proto_tree_add_text(tree, tvb, 0, -1, "Fragment Data");
450 + reassembled = NULL;
453 + pinfo->fragmented = save_fragmented;
454 + return reassembled;
457 +static int dissect_gsm_smscb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
460 + proto_tree *gsm_smscb_tree = NULL;
461 + proto_tree *subtree = NULL;
462 + guint8 addr, seq, more;
465 + if (tvb_length(tvb) < SMSCB_HDR_MINLEN)
468 + addr = tvb_get_guint8(tvb, 0);
469 + seq = addr & SMSCB_ADDR_SEQ;
470 + more = !(addr & SMSCB_ADDR_LB) && seq_more_frags(seq);
472 + col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMSCB");
474 + col_clear(pinfo->cinfo, COL_INFO);
475 + col_append_str(pinfo->cinfo, COL_INFO,
476 + val_to_str(seq, smscb_addr_seq_vals, "Unknown block #%d"));
479 + ti = proto_tree_add_item(tree, proto_gsm_smscb, tvb, 0, -1, ENC_NA);
480 + gsm_smscb_tree = proto_item_add_subtree(ti, ett_smscb);
482 + ti = proto_tree_add_item(gsm_smscb_tree, hf_smscb_addr, tvb, 0, 1, ENC_NA);
483 + subtree = proto_item_add_subtree(ti, ett_smscb_addr);
484 + proto_tree_add_item(subtree, hf_smscb_addr_lb, tvb, 0, 1, ENC_NA);
485 + proto_tree_add_item(subtree, hf_smscb_addr_seq, tvb, 0, 1, ENC_NA);
488 + payload = smscb_try_reassembly(tvb, pinfo, gsm_smscb_tree, &seq, more);
491 + case SMSCB_SEQ_1ST:
492 + dissect_smscb_message(payload, pinfo, gsm_smscb_tree);
494 + case SMSCB_SEQ_1ST_SCHED:
495 + dissect_sched_message(payload, pinfo, gsm_smscb_tree);
500 + return tvb_length(tvb);
503 +static hf_register_info hf[] = {
504 + { &hf_smscb_addr, {
505 + "Address Field", "smscb.addr", FT_UINT8, BASE_HEX,
509 + { &hf_smscb_addr_lb, {
510 + "LB", "smscb.addr.lb", FT_UINT8, BASE_DEC,
511 + VALS(smscb_addr_lb_vals), SMSCB_ADDR_LB,
512 + "Last Block bit", HFILL,
514 + { &hf_smscb_addr_seq, {
515 + "SEQ", "smscb.addr.seq", FT_UINT8, BASE_DEC,
516 + VALS(smscb_addr_seq_vals), SMSCB_ADDR_SEQ,
517 + "Sequence Number", HFILL,
520 + { &hf_smscb_serial_gs, {
521 + "Geographic Scope", "smscb.serial.gs", FT_UINT16, BASE_DEC,
522 + VALS(smscb_serial_gs_vals), SMSCB_SERIAL_GS, NULL, HFILL,
524 + { &hf_smscb_serial_mcode, {
525 + "Message Code", "smscb.serial.mcode", FT_UINT16, BASE_DEC,
526 + NULL, SMSCB_SERIAL_MCODE, NULL, HFILL,
528 + { &hf_smscb_serial_updnum, {
529 + "Update Number", "smscb.serial.updnum", FT_UINT16, BASE_DEC,
530 + NULL, SMSCB_SERIAL_UPDNUM, NULL, HFILL,
533 + { &hf_smscb_msgid, {
534 + "Message Identifier", "smscb.msgid", FT_UINT16, BASE_DEC,
535 + NULL, 0, NULL, HFILL,
538 + { &hf_smscb_page_num, {
539 + "Page number", "smscb.page.num", FT_UINT8, BASE_DEC,
540 + NULL, SMSCB_PAGE_NUM, NULL, HFILL,
542 + { &hf_smscb_page_cnt, {
543 + "Total pages", "smscb.page.cnt", FT_UINT8, BASE_DEC,
544 + NULL, SMSCB_PAGE_CNT, NULL, HFILL,
546 + { &hf_smscb_content, {
547 + "Content of Message", "smscb.content", FT_STRING, BASE_NONE,
548 + NULL, 0x00, NULL, HFILL,
551 + /* Schedule message */
552 + { &hf_smscb_sched_type, {
553 + "Type", "smscb.sched.type", FT_UINT8, BASE_HEX,
554 + NULL, SMSCB_SCHED_TYPE,
557 + { &hf_smscb_sched_spare, {
558 + "Spare", "smscb.sched.spare", FT_UINT8, BASE_DEC,
559 + NULL, SMSCB_SCHED_TYPE,
562 + { &hf_smscb_sched_begin_slot, {
563 + "Begin slot", "smscb.sched.begin_slot", FT_UINT8, BASE_DEC,
564 + NULL, SMSCB_SCHED_SLOT,
565 + "Begin slot", HFILL,
567 + { &hf_smscb_sched_end_slot, {
568 + "End slot", "smscb.sched.end_slot", FT_UINT8, BASE_DEC,
569 + NULL, SMSCB_SCHED_SLOT,
572 + { &hf_smscb_sched_mdt1, {
573 + "MDT", "smscb.sched.mdt1", FT_UINT16, BASE_DEC,
574 + NULL, SMSCB_SCHED_MDT1,
575 + "Message Description Type", HFILL,
577 + { &hf_smscb_sched_msgid, {
578 + "Message ID", "smscb.sched.msg_id", FT_UINT16, BASE_DEC,
579 + NULL, SMSCB_SCHED_MSGID,
580 + "Message ID", HFILL,
582 + { &hf_smscb_sched_mdt2, {
583 + "MDT", "smscb.sched.mdt2", FT_UINT8, BASE_DEC,
584 + NULL, SMSCB_SCHED_MDT2,
585 + "Message Description Type", HFILL,
587 + { &hf_smscb_sched_repslot, {
588 + "Repeated Slot Number", "smscb.sched.repslot", FT_UINT8, BASE_DEC,
589 + NULL, SMSCB_SCHED_REPSLOT,
590 + "Repeated Slot Number", HFILL,
592 + { &hf_smscb_sched_mdt8, {
593 + "MDT", "smscb.sched.mdt8", FT_UINT8, BASE_HEX,
594 + VALS(smscb_sched_mdt8_vals), 0x00,
595 + "Message Description Type", HFILL,
598 + /* Fragment reassembly */
599 + { &hf_smscb_fragments, {
600 + "Message fragments", "smscb.fragments",
601 + FT_NONE, BASE_NONE, NULL, 0x00,
602 + "SMSCB Message fragments", HFILL,
604 + { &hf_smscb_fragment, {
605 + "Message fragment", "smscb.fragment",
606 + FT_FRAMENUM, BASE_NONE, NULL, 0x00,
607 + "SMSCB Message fragment", HFILL,
609 + { &hf_smscb_fragment_overlap, {
610 + "Message fragment overlap", "smscb.fragment.overlap",
611 + FT_BOOLEAN, BASE_NONE, NULL, 0x0,
612 + "SMSCB Message fragment overlaps with other fragment(s)", HFILL,
614 + { &hf_smscb_fragment_overlap_conflicts, {
615 + "Message fragment overlapping with conflicting data", "smscb.fragment.overlap.conflicts",
616 + FT_BOOLEAN, BASE_NONE, NULL, 0x0,
617 + "SMSCB Message fragment overlaps with conflicting data", HFILL,
619 + { &hf_smscb_fragment_multiple_tails, {
620 + "Message has multiple tail fragments", "smscb.fragment.multiple_tails",
621 + FT_BOOLEAN, BASE_NONE, NULL, 0x0,
622 + "SMSCB Message fragment has multiple tail fragments", HFILL,
624 + { &hf_smscb_fragment_too_long_fragment, {
625 + "Message fragment too long", "smscb.fragment.too_long_fragment",
626 + FT_BOOLEAN, BASE_NONE, NULL, 0x0,
627 + "SMSCB Message fragment data goes beyond the packet end", HFILL,
629 + { &hf_smscb_fragment_error, {
630 + "Message defragmentation error", "smscb.fragment.error",
631 + FT_FRAMENUM, BASE_NONE, NULL, 0x00,
632 + "SMSCB Message defragmentation error due to illegal fragments", HFILL,
634 + { &hf_smscb_reassembled_in, {
635 + "Reassembled in", "smscb.reassembled.in",
636 + FT_FRAMENUM, BASE_NONE, NULL, 0x00,
637 + "SMSCB Message has been reassembled in this packet.", HFILL,
639 + { &hf_smscb_reassembled_length, {
640 + "Reassembled SMSCB length", "smscb.reassembled.length",
641 + FT_UINT32, BASE_DEC, NULL, 0x00,
642 + "The total length of the reassembled payload", HFILL,
646 +static gint *ett[] = {
650 + &ett_smscb_fragment,
651 + &ett_smscb_fragments,
652 + &ett_smscb_sched_new,
653 + &ett_smscb_sched_other,
654 + &ett_smscb_sched_slot,
657 +void proto_reg_handoff_gsm_smscb(void)
659 + data_handle = find_dissector("data");
662 +void proto_register_gsm_smscb(void)
664 + proto_gsm_smscb = proto_register_protocol(
665 + "Short Message Service Cell Broadcast",
666 + "SMSCB", "gsm_smscb");
668 + proto_register_field_array(proto_gsm_smscb, hf, array_length(hf));
669 + proto_register_subtree_array(ett, array_length(ett));
671 + new_register_dissector("gsm_smscb", dissect_gsm_smscb, proto_gsm_smscb);
672 + register_init_routine(smscb_defragment_init);
674 diff --git a/epan/dissectors/packet-lapdm.c b/epan/dissectors/packet-lapdm.c
675 index dbeac85..add859d 100644
676 --- a/epan/dissectors/packet-lapdm.c
677 +++ b/epan/dissectors/packet-lapdm.c
678 @@ -110,6 +110,7 @@ static GHashTable *lapdm_reassembled_table = NULL;
679 static dissector_table_t lapdm_sapi_dissector_table;
681 static dissector_handle_t data_handle;
682 +static dissector_handle_t smscb_handle;
684 static gboolean reassemble_lapdm = TRUE;
686 @@ -121,6 +122,7 @@ static gboolean reassemble_lapdm = TRUE;
687 #define LAPDM_CR 0x02 /* Command/Response bit */
688 #define LAPDM_EA 0x01 /* First Address Extension bit */
689 #define LAPDM_LPD 0x60 /* Link Protocol Discriminator */
690 +#define LAPDM_LPD_CB 0x20 /* Cell Broadcast LPD */
693 * Bits in the length field.
694 @@ -219,6 +221,7 @@ dissect_lapdm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
696 int available_length;
697 gboolean is_response = FALSE;
698 + gboolean is_cbs = FALSE;
700 /* Check that there's enough data */
701 if (tvb_length(tvb) < LAPDM_HEADER_LEN)
702 @@ -229,6 +232,7 @@ dissect_lapdm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
703 addr = tvb_get_guint8(tvb, 0);
704 length = tvb_get_guint8(tvb, 2);
706 + is_cbs = (addr & LAPDM_LPD) == LAPDM_LPD_CB;
707 cr = addr & LAPDM_CR;
708 if (pinfo->p2p_dir == P2P_DIR_RECV) {
709 is_response = cr ? FALSE : TRUE;
710 @@ -245,15 +249,22 @@ dissect_lapdm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
711 addr_tree = proto_item_add_subtree(addr_ti, ett_lapdm_address);
713 proto_tree_add_uint(addr_tree, hf_lapdm_lpd, tvb, 0, 1, addr);
714 - proto_tree_add_uint(addr_tree, hf_lapdm_sapi, tvb, 0, 1, addr);
715 - proto_tree_add_uint(addr_tree, hf_lapdm_cr, tvb, 0, 1, addr);
716 - proto_tree_add_uint(addr_tree, hf_lapdm_ea, tvb, 0, 1, addr);
718 + proto_tree_add_uint(addr_tree, hf_lapdm_sapi, tvb, 0, 1, addr);
719 + proto_tree_add_uint(addr_tree, hf_lapdm_cr, tvb, 0, 1, addr);
720 + proto_tree_add_uint(addr_tree, hf_lapdm_ea, tvb, 0, 1, addr);
729 + call_dissector(smscb_handle, tvb, pinfo, tree);
733 control = dissect_xdlc_control(tvb, 1, pinfo, lapdm_tree, hf_lapdm_control,
734 ett_lapdm_control, &lapdm_cf_items, NULL /* LAPDm doesnt support extended */, NULL, NULL,
735 is_response, FALSE, FALSE);
736 @@ -486,5 +497,6 @@ void
737 proto_reg_handoff_lapdm(void)
739 data_handle = find_dissector("data");
740 + smscb_handle = find_dissector("gsm_smscb");