summaryrefslogtreecommitdiffstats
path: root/src/wireshark/smscb.patch
blob: 4ac0952725acf5735ca83d9de3ea45792b1c48fa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
From 8ab33ab3f2de22f83df1cd45ae9a38254dc76400 Mon Sep 17 00:00:00 2001
From: Alex Badea <vamposdecampos@gmail.com>
Date: Sun, 21 Nov 2010 22:19:58 +0200
Subject: [RFC][PATCH wireshark] packet-lapdm: dissect CBS payloads

Hack dissection of Cell Broadcast Service into LAPDm.  First-Block payloads
are also dissected directly.
---
 packet-lapdm.c |  164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 163 insertions(+), 1 deletion(-)

diff --git a/epan/dissectors/packet-lapdm.c b/epan/dissectors/packet-lapdm.c
index dbeac85..e1d67b4 100644
--- a/epan/dissectors/packet-lapdm.c
+++ b/epan/dissectors/packet-lapdm.c
@@ -61,12 +61,25 @@
 #include <epan/xdlc.h>
 #include <epan/reassemble.h>
 
+#include <epan/asn1.h>
+#include "packet-gsm_map.h"
+#include "packet-gsm_sms.h"
+
 static int proto_lapdm = -1;
 static int hf_lapdm_address = -1;
 static int hf_lapdm_ea = -1;
 static int hf_lapdm_cr = -1;
 static int hf_lapdm_sapi = -1;
 static int hf_lapdm_lpd = -1;
+static int hf_lapdm_cb_lb = -1;
+static int hf_lapdm_cb_seq = -1;
+static int hf_lapdm_cbs_serial_gs = -1;
+static int hf_lapdm_cbs_serial_mcode = -1;
+static int hf_lapdm_cbs_serial_updnum = -1;
+static int hf_lapdm_cbs_msgid = -1;
+static int hf_lapdm_cbs_page_num = -1;
+static int hf_lapdm_cbs_page_cnt = -1;
+static int hf_lapdm_cbs_content = -1;
 
 static int hf_lapdm_control = -1;
 static int hf_lapdm_n_r = -1;
@@ -103,6 +116,8 @@ static gint ett_lapdm_control = -1;
 static gint ett_lapdm_length = -1;
 static gint ett_lapdm_fragment = -1;
 static gint ett_lapdm_fragments = -1;
+static gint ett_lapdm_cbs_serial = -1;
+static gint ett_lapdm_cbs_dcs = -1;
 
 static GHashTable *lapdm_fragment_table = NULL;
 static GHashTable *lapdm_reassembled_table = NULL;
@@ -121,6 +136,12 @@ static gboolean reassemble_lapdm = TRUE;
 #define	LAPDM_CR		0x02	/* Command/Response bit */
 #define	LAPDM_EA		0x01	/* First Address Extension bit */
 #define	LAPDM_LPD		0x60	/* Link Protocol Discriminator */
+#define	LAPDM_LPD_CB		0x20	/* Cell Broadcast LPD */
+#define	LAPDM_CB_LB		0x10	/* Cell Broadcast Last Bit */
+#define	LAPDM_CB_SEQ		0x0f	/* Cell Broadcast sequence number */
+#define LAPDM_CBS_SERIAL_GS	0xc0	/* CBS Serial Number - Geographical Scope */
+#define LAPDM_CBS_SERIAL_MCODE	0x3ffc	/* CBS Serial Number - Message Code */
+#define LAPDM_CBS_SERIAL_UPDNUM	0x03	/* CBS Serial Number - Update Number */
 
 /*
  * Bits in the length field.
@@ -132,6 +153,7 @@ static gboolean reassemble_lapdm = TRUE;
 #define	LAPDM_LEN_SHIFT		2
 
 #define LAPDM_HEADER_LEN 3
+#define LAPDM_CB_HEADER_LEN 1
 
 #define LAPDM_SAPI_RR_CC_MM	0
 #define LAPDM_SAPI_SMS		3
@@ -179,6 +201,33 @@ static const value_string lapdm_el_vals[] = {
     { 0,		NULL }
 };
 
+/* 04.12 section 3.3.1 */
+static const value_string lapdm_lb_vals[] = {
+    { 0,		"More blocks" },
+    { 1,		"Last block" },
+    { 0,		NULL }
+};
+
+/* 04.12 section 3.3.1 */
+static const value_string lapdm_seq_vals[] = {
+    { 0,		"First block" },
+    { 1,		"Second block" },
+    { 2,		"Third block" },
+    { 3,		"Fourth block" },
+    { 8,		"First schedule block" },
+    { 15,		"Null message" },
+    { 0,		NULL }
+};
+
+/* 03.41 section 9.3.2.1 */
+static const value_string lapdm_serial_gs_vals[] = {
+    { 0,		"Cell wide (immediate)" },
+    { 1,		"PLMN wide" },
+    { 2,		"Location Area wide" },
+    { 3,		"Cell wide" },
+    { 0,		NULL }
+};
+
 
 static const fragment_items lapdm_frag_items = {
     /* Fragment subtrees */
@@ -209,6 +258,79 @@ lapdm_defragment_init (void)
 
 
 static void
+dissect_lapdm_cb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+    proto_tree *lapdm_tree, *addr_tree;
+    proto_item *lapdm_ti, *addr_ti;
+    guint8 addr, seq;
+    tvbuff_t *payload;
+    int offset;
+    int length, out_len;
+    gchar msgbuf[88];
+
+    addr = tvb_get_guint8(tvb, 0);
+    if (tree) {
+        lapdm_ti = proto_tree_add_item(tree, proto_lapdm, tvb, 0, LAPDM_CB_HEADER_LEN, FALSE);
+        lapdm_tree = proto_item_add_subtree(lapdm_ti, ett_lapdm);
+
+        addr_ti = proto_tree_add_uint(lapdm_tree, hf_lapdm_address, tvb, 0, 1, addr);
+        addr_tree = proto_item_add_subtree(addr_ti, ett_lapdm_address);
+
+        proto_tree_add_uint(addr_tree, hf_lapdm_lpd, tvb, 0, 1, addr);
+        proto_tree_add_uint(addr_tree, hf_lapdm_cb_lb, tvb, 0, 1, addr);
+        proto_tree_add_uint(addr_tree, hf_lapdm_cb_seq, tvb, 0, 1, addr);
+    } else {
+        lapdm_ti = NULL;
+        lapdm_tree = NULL;
+    }
+
+    col_append_str(pinfo->cinfo, COL_INFO, "CBS ");
+
+    offset = 1;
+
+    /* TODO: reassemble blocks 1-3 */
+    seq = addr & LAPDM_CB_SEQ;
+    if (seq == 0) {
+        proto_item *ti;
+        proto_tree *subtree;
+
+        ti = proto_tree_add_text(lapdm_tree, tvb, offset, 2, "Serial Number");
+        subtree = proto_item_add_subtree(ti, ett_lapdm_cbs_serial);
+
+        proto_tree_add_item(subtree, hf_lapdm_cbs_serial_gs, tvb, offset, 1, FALSE);
+        proto_tree_add_item(subtree, hf_lapdm_cbs_serial_mcode, tvb, offset, 2, FALSE);
+        offset++;
+        proto_tree_add_item(subtree, hf_lapdm_cbs_serial_updnum, tvb, offset, 1, FALSE);
+        offset++;
+
+        proto_tree_add_item(lapdm_tree, hf_lapdm_cbs_msgid, tvb, offset, 2, FALSE);
+        offset += 2;
+
+        ti = proto_tree_add_text(lapdm_tree, tvb, offset, 1, "Data Coding Scheme");
+        subtree = proto_item_add_subtree(ti, ett_lapdm_cbs_dcs);
+        dissect_cbs_data_coding_scheme(tvb_new_subset(tvb, offset, 1, -1), pinfo, subtree);
+        offset++;
+
+        proto_tree_add_item(lapdm_tree, hf_lapdm_cbs_page_num, tvb, offset, 1, FALSE);
+        proto_tree_add_item(lapdm_tree, hf_lapdm_cbs_page_cnt, tvb, offset, 1, FALSE);
+        offset++;
+
+        length = tvb_length(tvb) - offset;
+        out_len = gsm_sms_char_7bit_unpack(0, length, sizeof(msgbuf) - 1,
+            tvb_get_ptr(tvb, offset, length), msgbuf);
+        msgbuf[out_len] = '\0';
+        proto_tree_add_string(lapdm_tree, hf_lapdm_cbs_content, tvb, offset, length,
+            gsm_sms_chars_to_utf8(msgbuf, out_len));
+
+        col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", gsm_sms_chars_to_utf8(msgbuf, out_len));
+    }
+
+    payload = tvb_new_subset_remaining(tvb, offset);
+    call_dissector(data_handle, payload, pinfo, tree);
+}
+
+
+static void
 dissect_lapdm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
     proto_tree *lapdm_tree, *addr_tree, *length_tree;
@@ -227,6 +349,11 @@ dissect_lapdm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     col_set_str(pinfo->cinfo, COL_PROTOCOL, "LAPDm");
 
     addr = tvb_get_guint8(tvb, 0);
+    if ((addr & LAPDM_LPD) == LAPDM_LPD_CB) {
+        dissect_lapdm_cb(tvb, pinfo, tree);
+        return;
+    }
+
     length = tvb_get_guint8(tvb, 2);
 
     cr = addr & LAPDM_CR;
@@ -360,6 +487,39 @@ proto_register_lapdm(void)
         { "SAPI", "lapdm.sapi", FT_UINT8, BASE_DEC, VALS(lapdm_sapi_vals), LAPDM_SAPI,
         "Service access point identifier", HFILL }},
 
+        { &hf_lapdm_cb_lb,
+        { "LB", "lapdm.cb.lb", FT_UINT8, BASE_DEC,
+        VALS(lapdm_lb_vals), LAPDM_CB_LB, "Last Block bit", HFILL }},
+
+        { &hf_lapdm_cb_seq,
+        { "SEQ", "lapdm.cb.seq", FT_UINT8, BASE_DEC,
+        VALS(lapdm_seq_vals), LAPDM_CB_SEQ, "Sequence Number", HFILL }},
+
+        { &hf_lapdm_cbs_serial_gs,
+        { "GS", "lapdm.cbs.serial.gs", FT_UINT8, BASE_DEC,
+        VALS(lapdm_serial_gs_vals), LAPDM_CBS_SERIAL_GS, "Geographic Scope", HFILL }},
+        { &hf_lapdm_cbs_serial_mcode,
+        { "Message Code", "lapdm.cbs.serial.mcode", FT_UINT16, BASE_DEC,
+        NULL, LAPDM_CBS_SERIAL_MCODE, NULL, HFILL }},
+        { &hf_lapdm_cbs_serial_updnum,
+        { "Update Number", "lapdm.cbs.serial.updnum", FT_UINT8, BASE_DEC,
+        NULL, LAPDM_CBS_SERIAL_MCODE, NULL, HFILL }},
+
+        { &hf_lapdm_cbs_msgid,
+        { "Message Identifier", "lapdm.cbs.msgid", FT_UINT16, BASE_DEC,
+        NULL, 0, NULL, HFILL }},
+
+        { &hf_lapdm_cbs_page_num,
+        { "Page number", "lapdm.cbs.page.num", FT_UINT8, BASE_DEC,
+        NULL, 0xf0, NULL, HFILL }},
+        { &hf_lapdm_cbs_page_cnt,
+        { "Total pages", "lapdm.cbs.page.cnt", FT_UINT8, BASE_DEC,
+        NULL, 0x0f, NULL, HFILL }},
+
+        { &hf_lapdm_cbs_content,
+        { "Content of Message", "lapdm.cbs.content", FT_STRING, BASE_NONE,
+        NULL, 0x00, NULL, HFILL }},
+
         { &hf_lapdm_control,
         { "Control Field", "lapdm.control_field", FT_UINT8, BASE_HEX, NULL, 0x0,
         NULL, HFILL }},
@@ -461,7 +621,9 @@ proto_register_lapdm(void)
         &ett_lapdm_control,
         &ett_lapdm_length,
         &ett_lapdm_fragment,
-        &ett_lapdm_fragments
+        &ett_lapdm_fragments,
+        &ett_lapdm_cbs_serial,
+        &ett_lapdm_cbs_dcs,
     };
 
     module_t *lapdm_module;