epan/dissectors/pidl/ C99 drsuapi
[wireshark-sm.git] / epan / dissectors / asn1 / sabp / packet-sabp-template.c
blob2add95c9c734213ccfcd1c738796c8e284768a59
1 /* packet-sabp-template.c
2 * Routines for UTRAN Iu-BC Interface: Service Area Broadcast Protocol (SABP) packet dissection
3 * Copyright 2007, Tomas Kukosa <tomas.kukosa@siemens.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
11 * Ref: 3GPP TS 25.419 version V9.0.0 (2009-12)
14 #include "config.h"
16 #include <epan/packet.h>
18 #include <epan/asn1.h>
19 #include <wsutil/array.h>
21 #include "packet-tcp.h"
22 #include "packet-per.h"
23 #include "packet-e212.h"
24 #include "packet-gsm_map.h"
25 #include "packet-gsm_sms.h"
26 #include <epan/sctpppids.h>
27 #include "packet-cell_broadcast.h"
29 #define PNAME "UTRAN IuBC interface SABP signaling"
30 #define PSNAME "SABP"
31 #define PFNAME "sabp"
33 #include "packet-sabp-val.h"
35 void proto_register_sabp(void);
36 void proto_reg_handoff_sabp(void);
38 /* Initialize the protocol and registered fields */
39 static int proto_sabp;
41 static int hf_sabp_no_of_pages;
42 static int hf_sabp_cb_inf_len;
43 static int hf_sabp_cb_msg_inf_page;
44 static int hf_sabp_cbs_page_content;
45 #include "packet-sabp-hf.c"
47 /* Initialize the subtree pointers */
48 static int ett_sabp;
49 static int ett_sabp_e212;
50 static int ett_sabp_cbs_data_coding;
51 static int ett_sabp_bcast_msg;
52 static int ett_sabp_cbs_serial_number;
53 static int ett_sabp_cbs_new_serial_number;
54 static int ett_sabp_cbs_page;
55 static int ett_sabp_cbs_page_content;
57 #include "packet-sabp-ett.c"
59 /* Global variables */
60 static uint32_t ProcedureCode;
61 static uint32_t ProtocolIE_ID;
62 static uint32_t ProtocolExtensionID;
63 static uint8_t sms_encoding;
65 #define SABP_PORT 3452
67 /* Dissector tables */
68 static dissector_table_t sabp_ies_dissector_table;
69 static dissector_table_t sabp_extension_dissector_table;
70 static dissector_table_t sabp_proc_imsg_dissector_table;
71 static dissector_table_t sabp_proc_sout_dissector_table;
72 static dissector_table_t sabp_proc_uout_dissector_table;
74 static dissector_handle_t sabp_handle;
75 static dissector_handle_t sabp_tcp_handle;
77 static int dissect_ProtocolIEFieldValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *);
78 static int dissect_ProtocolExtensionFieldExtensionValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *);
79 static int dissect_InitiatingMessageValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *);
80 static int dissect_SuccessfulOutcomeValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *);
81 static int dissect_UnsuccessfulOutcomeValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *);
82 static void dissect_sabp_cb_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
84 #include "packet-sabp-fn.c"
86 static int dissect_ProtocolIEFieldValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
88 return (dissector_try_uint(sabp_ies_dissector_table, ProtocolIE_ID, tvb, pinfo, tree)) ? tvb_captured_length(tvb) : 0;
91 static int dissect_ProtocolExtensionFieldExtensionValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
93 return (dissector_try_uint(sabp_extension_dissector_table, ProtocolExtensionID, tvb, pinfo, tree)) ? tvb_captured_length(tvb) : 0;
96 static int dissect_InitiatingMessageValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
98 return (dissector_try_uint(sabp_proc_imsg_dissector_table, ProcedureCode, tvb, pinfo, tree)) ? tvb_captured_length(tvb) : 0;
101 static int dissect_SuccessfulOutcomeValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
103 return (dissector_try_uint(sabp_proc_sout_dissector_table, ProcedureCode, tvb, pinfo, tree)) ? tvb_captured_length(tvb) : 0;
106 static int dissect_UnsuccessfulOutcomeValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
108 return (dissector_try_uint(sabp_proc_uout_dissector_table, ProcedureCode, tvb, pinfo, tree)) ? tvb_captured_length(tvb) : 0;
112 /* 3GPP TS 23.041 version 11.4.0
113 * 9.4.2.2.5 CB Data
115 static void
116 dissect_sabp_cb_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
118 proto_item *cbs_page_item;
119 proto_tree *subtree;
120 tvbuff_t *page_tvb, *unpacked_tvb;
121 int offset = 0;
122 int n;
123 uint8_t nr_pages, len, cb_inf_msg_len;
126 /* Octet 1 Number-of-Pages */
127 nr_pages = tvb_get_uint8(tvb, offset);
128 proto_tree_add_item(tree, hf_sabp_no_of_pages, tvb, offset, 1, ENC_BIG_ENDIAN);
129 offset++;
131 * NOTE: n equal to or less than 15
133 if(nr_pages > 15){
134 /* Error */
135 return;
137 for (n = 0; n < nr_pages; n++) {
138 subtree = proto_tree_add_subtree_format(tree, tvb, offset, 83, ett_sabp_cbs_page, NULL,
139 "CB page %u data", n+1);
140 /* octet 2 - 83 CBS-Message-Information-Page 1 */
141 cbs_page_item = proto_tree_add_item(subtree, hf_sabp_cb_msg_inf_page, tvb, offset, 82, ENC_NA);
142 cb_inf_msg_len = tvb_get_uint8(tvb,offset+82);
143 page_tvb = tvb_new_subset_length(tvb, offset, cb_inf_msg_len);
144 unpacked_tvb = dissect_cbs_data(sms_encoding, page_tvb, subtree, pinfo, 0);
145 len = tvb_captured_length(unpacked_tvb);
146 if (unpacked_tvb != NULL){
147 if (tree != NULL){
148 proto_tree *cbs_page_subtree = proto_item_add_subtree(cbs_page_item, ett_sabp_cbs_page_content);
149 proto_tree_add_item(cbs_page_subtree, hf_sabp_cbs_page_content, unpacked_tvb, 0, len, ENC_UTF_8);
153 offset = offset+82;
154 /* 84 CBS-Message-Information-Length 1 */
155 proto_tree_add_item(subtree, hf_sabp_cb_inf_len, tvb, offset, 1, ENC_BIG_ENDIAN);
156 offset++;
160 static int
161 dissect_sabp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
163 proto_item *sabp_item = NULL;
164 proto_tree *sabp_tree = NULL;
166 /* make entry in the Protocol column on summary display */
167 col_set_str(pinfo->cinfo, COL_PROTOCOL, PSNAME);
169 /* create the sabp protocol tree */
170 sabp_item = proto_tree_add_item(tree, proto_sabp, tvb, 0, -1, ENC_NA);
171 sabp_tree = proto_item_add_subtree(sabp_item, ett_sabp);
173 return dissect_SABP_PDU_PDU(tvb, pinfo, sabp_tree, NULL);
176 /* Note a little bit of a hack assumes length max takes two bytes and that the length starts at byte 4 */
177 static int
178 dissect_sabp_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
180 uint32_t type_length, msg_len;
181 unsigned tvb_length;
182 int bit_offset;
183 bool is_fragmented;
184 asn1_ctx_t asn1_ctx;
185 asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, true, pinfo);
187 tvb_length = tvb_reported_length(tvb);
189 if (tvb_length < 5) {
190 pinfo->desegment_offset = 0;
191 pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
192 return tvb_captured_length(tvb);
195 /* Length should be in the 3:d octet */
196 bit_offset = 24;
197 /* Get the length of the sabp packet. Offset in bits */
198 do {
199 bit_offset = dissect_per_length_determinant(tvb, bit_offset, &asn1_ctx, NULL, -1, &type_length, &is_fragmented);
200 bit_offset += 8*type_length;
201 msg_len = (bit_offset + 7) >> 3;
202 if (is_fragmented) {
203 /* Next length field will take 1 or 2 bytes; let's ask for the maximum */
204 msg_len += 2;
206 if (msg_len > tvb_length) {
207 pinfo->desegment_offset = 0;
208 pinfo->desegment_len = msg_len - tvb_length;
209 return tvb_captured_length(tvb);
211 } while (is_fragmented);
213 return dissect_sabp(tvb, pinfo, tree, data);
216 /*--- proto_register_sabp -------------------------------------------*/
217 void proto_register_sabp(void) {
219 /* List of fields */
221 static hf_register_info hf[] = {
222 { &hf_sabp_no_of_pages,
223 { "Number-of-Pages", "sabp.no_of_pages",
224 FT_UINT8, BASE_DEC, NULL, 0,
225 NULL, HFILL }},
226 { &hf_sabp_cb_msg_inf_page,
227 { "CBS-Message-Information-Page", "sabp.cb_msg_inf_page",
228 FT_BYTES, BASE_NONE, NULL, 0,
229 NULL, HFILL }},
230 { &hf_sabp_cbs_page_content,
231 { "CBS Page Content", "sabp.cb_page_content",
232 FT_STRING, BASE_NONE, NULL, 0,
233 NULL, HFILL }},
234 { &hf_sabp_cb_inf_len,
235 { "CBS-Message-Information-Length", "sabp.cb_inf_len",
236 FT_UINT8, BASE_DEC, NULL, 0,
237 NULL, HFILL }},
239 #include "packet-sabp-hfarr.c"
242 /* List of subtrees */
243 static int *ett[] = {
244 &ett_sabp,
245 &ett_sabp_e212,
246 &ett_sabp_cbs_data_coding,
247 &ett_sabp_bcast_msg,
248 &ett_sabp_cbs_serial_number,
249 &ett_sabp_cbs_new_serial_number,
250 &ett_sabp_cbs_page,
251 &ett_sabp_cbs_page_content,
252 #include "packet-sabp-ettarr.c"
256 /* Register protocol */
257 proto_sabp = proto_register_protocol(PNAME, PSNAME, PFNAME);
258 /* Register fields and subtrees */
259 proto_register_field_array(proto_sabp, hf, array_length(hf));
260 proto_register_subtree_array(ett, array_length(ett));
262 /* Register dissector */
263 sabp_handle = register_dissector("sabp", dissect_sabp, proto_sabp);
264 sabp_tcp_handle = register_dissector("sabp.tcp", dissect_sabp_tcp, proto_sabp);
266 /* Register dissector tables */
267 sabp_ies_dissector_table = register_dissector_table("sabp.ies", "SABP-PROTOCOL-IES", proto_sabp, FT_UINT32, BASE_DEC);
268 sabp_extension_dissector_table = register_dissector_table("sabp.extension", "SABP-PROTOCOL-EXTENSION", proto_sabp, FT_UINT32, BASE_DEC);
269 sabp_proc_imsg_dissector_table = register_dissector_table("sabp.proc.imsg", "SABP-ELEMENTARY-PROCEDURE InitiatingMessage", proto_sabp, FT_UINT32, BASE_DEC);
270 sabp_proc_sout_dissector_table = register_dissector_table("sabp.proc.sout", "SABP-ELEMENTARY-PROCEDURE SuccessfulOutcome", proto_sabp, FT_UINT32, BASE_DEC);
271 sabp_proc_uout_dissector_table = register_dissector_table("sabp.proc.uout", "SABP-ELEMENTARY-PROCEDURE UnsuccessfulOutcome", proto_sabp, FT_UINT32, BASE_DEC);
275 /*--- proto_reg_handoff_sabp ---------------------------------------*/
276 void
277 proto_reg_handoff_sabp(void)
279 dissector_add_uint_with_preference("udp.port", SABP_PORT, sabp_handle);
280 dissector_add_uint_with_preference("tcp.port", SABP_PORT, sabp_tcp_handle);
281 dissector_add_uint("sctp.ppi", SABP_PAYLOAD_PROTOCOL_ID, sabp_handle);
283 #include "packet-sabp-dis-tab.c"