Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-gsm_um.c
blob3af81edc6c2e56549596af84772fb5f3b49c2e3d
1 /* packet-gsm_um.c
2 * Routines for GSM Um packet disassembly
3 * Duncan Salerno <duncan.salerno@googlemail.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
13 #include "config.h"
15 #include <epan/packet.h>
16 #include <epan/prefs.h>
17 #include <wiretap/wtap.h>
19 void proto_register_gsm_um(void);
20 void proto_reg_handoff_gsm_um(void);
22 static int proto_gsm_um;
23 static int hf_gsm_um_direction;
24 static int hf_gsm_um_channel;
25 static int hf_gsm_um_bsic;
26 static int hf_gsm_um_arfcn;
27 static int hf_gsm_um_band;
28 static int hf_gsm_um_frequency;
29 static int hf_gsm_um_frame;
30 static int hf_gsm_um_error;
31 static int hf_gsm_um_timeshift;
32 static int hf_gsm_um_l2_pseudo_len;
34 static int ett_gsm_um;
36 static dissector_handle_t gsm_um_handle;
38 static dissector_handle_t lapdm_handle;
39 static dissector_handle_t dtap_handle;
41 static bool dcs1800_gsm = true;
43 #define GSM_UM_L2_PSEUDO_LEN 0xfc
46 static void
47 decode_arfcn(uint16_t arfcn, const char **band, unsigned *uplink, unsigned *downlink)
49 /* Decode ARFCN to frequency using GSM 05.05 */
50 if( arfcn >= 1 && arfcn <= 124 ) {
51 *band = "P-GSM 900";
52 *uplink = 890000 + 200 * arfcn;
53 *downlink = *uplink + 45000;
55 else if( arfcn == 0 ) {
56 *band = "E-GSM 900";
57 *uplink = 890000 + 200 * arfcn;
58 *downlink = *uplink + 45000;
60 else if( arfcn >= 975 && arfcn <= 1023 ) {
61 *band = "E-GSM 900";
62 *uplink = 890000 + 200 * (arfcn - 1024);
63 *downlink = *uplink + 45000;
65 else if( arfcn >= 955 && arfcn <= 974 ) {
66 *band = "R-GSM 900";
67 *uplink = 890000 + 200 * (arfcn - 1024);
68 *downlink = *uplink + 45000;
70 else if( arfcn >= 512 && arfcn <= 885 && dcs1800_gsm) {
71 *band = "DCS 1800";
72 *uplink = 1710200 + 200 * (arfcn - 512);
73 *downlink = *uplink + 95000;
75 else if( arfcn >= 512 && arfcn <= 810 && !dcs1800_gsm) {
76 *band = "PCS 1900";
77 *uplink = 1850200 + 200 * (arfcn - 512);
78 *downlink = *uplink + 80000;
80 else if( arfcn >= 259 && arfcn <= 293 ) {
81 *band = "GSM 450";
82 *uplink = 450600 + 200 * (arfcn - 259);
83 *downlink = *uplink + 10000;
85 else if( arfcn >= 306 && arfcn <= 340 ) {
86 *band = "GSM 480";
87 *uplink = 479000 + 200 * (arfcn - 306);
88 *downlink = *uplink + 10000;
90 else if( arfcn >= 128 && arfcn <= 251 ) {
91 *band = "GSM 850";
92 *uplink = 824200 + 200 * (arfcn - 128);
93 *downlink = *uplink + 45000;
95 else {
96 *band = "Unknown";
97 *uplink = *downlink = 0;
102 static int
103 dissect_gsm_um(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
105 proto_tree *gsm_um_tree = NULL;
106 proto_item *ti;
108 col_set_str(pinfo->cinfo, COL_PROTOCOL, "GSM Um");
110 if (pinfo->pseudo_header->gsm_um.uplink) {
111 col_set_str(pinfo->cinfo, COL_RES_DL_DST, "BTS");
112 col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "MS");
114 else {
115 switch (pinfo->pseudo_header->gsm_um.channel) {
116 case GSM_UM_CHANNEL_BCCH:
117 case GSM_UM_CHANNEL_CCCH:
118 case GSM_UM_CHANNEL_PCH:
119 case GSM_UM_CHANNEL_AGCH:
120 col_set_str(pinfo->cinfo, COL_RES_DL_DST, "Broadcast");
121 break;
122 default:
123 col_set_str(pinfo->cinfo, COL_RES_DL_DST, "MS");
124 break;
126 col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "BTS");
129 if (tree) {
130 const char *channel;
132 ti = proto_tree_add_item(tree, proto_gsm_um, tvb, 0, 0, ENC_NA);
133 gsm_um_tree = proto_item_add_subtree(ti, ett_gsm_um);
135 switch( pinfo->pseudo_header->gsm_um.channel ) {
136 case GSM_UM_CHANNEL_BCCH: channel = "BCCH"; break;
137 case GSM_UM_CHANNEL_CCCH: channel = "CCCH"; break;
138 case GSM_UM_CHANNEL_PCH: channel = "PCH"; break;
139 case GSM_UM_CHANNEL_AGCH: channel = "AGCH"; break;
140 case GSM_UM_CHANNEL_SACCH: channel = "SACCH"; break;
141 case GSM_UM_CHANNEL_FACCH: channel = "FACCH"; break;
142 case GSM_UM_CHANNEL_SDCCH: channel = "SDCCH"; break;
143 default: channel = "Unknown"; break;
146 if( pinfo->pseudo_header->gsm_um.uplink ) {
147 proto_tree_add_string(gsm_um_tree, hf_gsm_um_direction, tvb, 0, 0, "Uplink");
149 else {
150 proto_tree_add_string(gsm_um_tree, hf_gsm_um_direction, tvb, 0, 0, "Downlink");
153 proto_tree_add_string(gsm_um_tree, hf_gsm_um_channel, tvb, 0, 0, channel);
155 /* Show the other fields, if we have them (ie. downlink, BTS->MS) */
156 if( !pinfo->pseudo_header->gsm_um.uplink ) {
157 const char *band;
158 unsigned downlink, uplink;
160 decode_arfcn(pinfo->pseudo_header->gsm_um.arfcn, &band, &uplink, &downlink);
162 proto_tree_add_uint(gsm_um_tree, hf_gsm_um_arfcn, tvb, 0, 0,
163 pinfo->pseudo_header->gsm_um.arfcn);
164 proto_tree_add_string(gsm_um_tree, hf_gsm_um_band, tvb, 0, 0,
165 band);
166 proto_tree_add_uint_format_value(gsm_um_tree, hf_gsm_um_frequency, tvb, 0, 0,
167 downlink, "%u.%03uMHz", downlink / 1000, downlink % 1000);
168 proto_tree_add_uint(gsm_um_tree, hf_gsm_um_bsic, tvb, 0, 0,
169 pinfo->pseudo_header->gsm_um.bsic);
170 proto_tree_add_uint(gsm_um_tree, hf_gsm_um_frame, tvb, 0, 0,
171 pinfo->pseudo_header->gsm_um.tdma_frame);
172 proto_tree_add_uint(gsm_um_tree, hf_gsm_um_error, tvb, 0, 0,
173 pinfo->pseudo_header->gsm_um.error);
174 proto_tree_add_uint(gsm_um_tree, hf_gsm_um_timeshift, tvb, 0, 0,
175 pinfo->pseudo_header->gsm_um.timeshift);
179 /* TODO: If CCCH downlink could work out of PCH or AGCH by peeking at next bytes, uplink is RACH */
181 switch( pinfo->pseudo_header->gsm_um.channel ) {
182 case GSM_UM_CHANNEL_BCCH:
183 case GSM_UM_CHANNEL_CCCH:
184 case GSM_UM_CHANNEL_PCH:
185 case GSM_UM_CHANNEL_AGCH:
186 if( !pinfo->pseudo_header->gsm_um.uplink ) {
187 tvbuff_t *next_tvb;
188 uint8_t pseudo_len, len_left, len_byte;
190 len_left = tvb_reported_length(tvb);
191 len_byte = tvb_get_uint8(tvb, 0);
192 pseudo_len = len_byte >> 2;
193 next_tvb = tvb_new_subset_length_caplen(tvb, 1, MIN(len_left, pseudo_len), -1);
195 if (tree) {
196 proto_tree_add_uint(gsm_um_tree, hf_gsm_um_l2_pseudo_len, tvb, 0, 1,
197 len_byte);
200 /* Only dissect non-empty frames */
201 if( tvb_reported_length(next_tvb) ) {
202 call_dissector(dtap_handle, next_tvb, pinfo, tree);
205 else {
206 /* Either RACH, or something invalid */
207 call_data_dissector(tvb, pinfo, tree);
209 break;
210 case GSM_UM_CHANNEL_SACCH:
211 case GSM_UM_CHANNEL_FACCH:
212 case GSM_UM_CHANNEL_SDCCH:
213 call_dissector(lapdm_handle, tvb, pinfo, tree);
214 break;
215 default:
216 call_data_dissector(tvb, pinfo, tree);
217 break;
219 return tvb_captured_length(tvb);
222 void
223 proto_register_gsm_um(void)
225 static hf_register_info hf[] = {
226 { &hf_gsm_um_direction,
227 { "Direction", "gsm_um.direction", FT_STRINGZ, BASE_NONE,
228 NULL, 0x0, NULL, HFILL }},
230 { &hf_gsm_um_channel,
231 { "Channel", "gsm_um.channel", FT_STRINGZ, BASE_NONE,
232 NULL, 0x0, NULL, HFILL }},
234 { &hf_gsm_um_bsic,
235 { "BSIC", "gsm_um.bsic", FT_UINT8, BASE_DEC,
236 NULL, 0x0, "Base station identity code", HFILL }},
238 { &hf_gsm_um_arfcn,
239 { "ARFCN", "gsm_um.arfcn", FT_UINT16, BASE_DEC,
240 NULL, 0x0, "Absolute radio frequency channel number", HFILL }},
242 { &hf_gsm_um_band,
243 { "Band", "gsm_um.band", FT_STRING, BASE_NONE,
244 NULL, 0x0, NULL, HFILL }},
246 { &hf_gsm_um_frequency,
247 { "Frequency", "gsm_um.frequency", FT_UINT32, BASE_DEC,
248 NULL, 0x0, NULL, HFILL }},
250 { &hf_gsm_um_frame,
251 { "TDMA Frame", "gsm_um.frame", FT_UINT32, BASE_DEC,
252 NULL, 0x0, NULL, HFILL }},
254 { &hf_gsm_um_error,
255 { "Error", "gsm_um.error", FT_UINT8, BASE_DEC,
256 NULL, 0x0, NULL, HFILL }},
258 { &hf_gsm_um_timeshift,
259 { "Timeshift", "gsm_um.timeshift", FT_UINT16, BASE_DEC,
260 NULL, 0x0, NULL, HFILL }},
262 { &hf_gsm_um_l2_pseudo_len,
263 { "L2 Pseudo Length", "gsm_um.l2_pseudo_len", FT_UINT8, BASE_DEC,
264 NULL, GSM_UM_L2_PSEUDO_LEN, NULL, HFILL }}
267 static int *ett[] = {
268 &ett_gsm_um
270 module_t *gsm_um_module;
272 proto_gsm_um = proto_register_protocol("GSM Um Interface", "GSM Um", "gsm_um");
273 proto_register_field_array(proto_gsm_um, hf, array_length(hf));
274 proto_register_subtree_array(ett, array_length(ett));
276 gsm_um_module = prefs_register_protocol(proto_gsm_um, NULL);
277 prefs_register_bool_preference(gsm_um_module, "dcs1800",
278 "Treat ARFCN 512-810 as DCS 1800 rather than PCS 1900",
279 "Treat ARFCN 512-810 as DCS 1800 rather than PCS 1900",
280 &dcs1800_gsm);
282 gsm_um_handle = register_dissector("gsm_um", dissect_gsm_um, proto_gsm_um);
285 void
286 proto_reg_handoff_gsm_um(void)
288 lapdm_handle = find_dissector_add_dependency("lapdm", proto_gsm_um);
289 dtap_handle = find_dissector_add_dependency("gsm_a_dtap", proto_gsm_um);
291 dissector_add_uint("wtap_encap", WTAP_ENCAP_GSM_UM, gsm_um_handle);
295 * Editor modelines - https://www.wireshark.org/tools/modelines.html
297 * Local variables:
298 * c-basic-offset: 8
299 * tab-width: 8
300 * indent-tabs-mode: t
301 * End:
303 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
304 * :indentSize=8:tabSize=8:noTabs=false: