Coverage Report

Created: 2025-02-15 06:25

/src/wireshark/epan/dissectors/packet-sccpmg.c
Line
Count
Source (jump to first uncovered line)
1
/* packet-sccpmg.c
2
 * Routines for Signalling Connection Control Part (SCCP) Management dissection
3
 *
4
 * It is hopefully compliant to:
5
 *   ANSI T1.112.3-1996
6
 *   ITU-T Q.713 7/1996
7
 *   YDN 038-1997 (Chinese ITU variant)
8
 *   JT-Q714 and NTT-Q714 (Japan)
9
 *
10
 *   Note that NTT Annex E (SCCP Management Procedure (Global Title Status
11
 *   Management)) is not implemented (yet)
12
 *
13
 * Copyright 2002, Jeff Morriss <jeff.morriss.ws [AT] gmail.com>
14
 *
15
 * Wireshark - Network traffic analyzer
16
 * By Gerald Combs <gerald@wireshark.org>
17
 * Copyright 1998 Gerald Combs
18
 *
19
 * SPDX-License-Identifier: GPL-2.0-or-later
20
 */
21
22
#include "config.h"
23
24
#include <epan/packet.h>
25
#include <epan/expert.h>
26
#include "packet-mtp3.h"
27
28
14
#define SCCPMG_SSN 1
29
30
0
#define SCCPMG_MESSAGE_TYPE_SSA 0x01
31
0
#define SCCPMG_MESSAGE_TYPE_SSP 0x02
32
0
#define SCCPMG_MESSAGE_TYPE_SST 0x03
33
0
#define SCCPMG_MESSAGE_TYPE_SOR 0x04
34
0
#define SCCPMG_MESSAGE_TYPE_SOG 0x05
35
/* SSC is ITU only */
36
0
#define SCCPMG_MESSAGE_TYPE_SSC 0x06
37
/* Below are ANSI only */
38
0
#define SCCPMG_MESSAGE_TYPE_SBR 0xfd
39
0
#define SCCPMG_MESSAGE_TYPE_SNR 0xfe
40
0
#define SCCPMG_MESSAGE_TYPE_SRT 0xff
41
42
void proto_register_sccpmg(void);
43
void proto_reg_handoff_sccpmg(void);
44
45
static dissector_handle_t sccpmg_handle;
46
47
/* Same as below but with names typed out */
48
static const value_string sccpmg_message_type_values[] = {
49
  { SCCPMG_MESSAGE_TYPE_SSA,   "SubSystem Allowed" },
50
  { SCCPMG_MESSAGE_TYPE_SSP,   "SubSystem Prohibited" },
51
  { SCCPMG_MESSAGE_TYPE_SST,   "Subsystem Status Test" },
52
  { SCCPMG_MESSAGE_TYPE_SOR,   "Subsystem Out of service Request" },
53
  { SCCPMG_MESSAGE_TYPE_SOG,   "Subsystem Out of service Grant" },
54
  { SCCPMG_MESSAGE_TYPE_SSC,   "SubSystem Congested (ITU)" },
55
  { SCCPMG_MESSAGE_TYPE_SBR,   "Subsystem Backup Routing (ANSI)" },
56
  { SCCPMG_MESSAGE_TYPE_SNR,   "Subsystem Normal Routing (ANSI)" },
57
  { SCCPMG_MESSAGE_TYPE_SRT,   "Subsystem Routing status Test (ANSI)" },
58
  { 0,                       NULL } };
59
60
/* Same as above but in acronym for (for the Info column) */
61
static const value_string sccpmg_message_type_acro_values[] = {
62
  { SCCPMG_MESSAGE_TYPE_SSA,   "SSA" },
63
  { SCCPMG_MESSAGE_TYPE_SSP,   "SSP" },
64
  { SCCPMG_MESSAGE_TYPE_SST,   "SST" },
65
  { SCCPMG_MESSAGE_TYPE_SOR,   "SOR" },
66
  { SCCPMG_MESSAGE_TYPE_SOG,   "SOG" },
67
  { SCCPMG_MESSAGE_TYPE_SSC,   "SSC" },
68
  { SCCPMG_MESSAGE_TYPE_SBR,   "SBR" },
69
  { SCCPMG_MESSAGE_TYPE_SNR,   "SNR" },
70
  { SCCPMG_MESSAGE_TYPE_SRT,   "SRT" },
71
  { 0,                       NULL } };
72
73
74
2
#define SCCPMG_MESSAGE_TYPE_OFFSET 0
75
1
#define SCCPMG_MESSAGE_TYPE_LENGTH 1
76
77
0
#define SCCPMG_AFFECTED_SSN_OFFSET SCCPMG_MESSAGE_TYPE_LENGTH
78
0
#define SCCPMG_AFFECTED_SSN_LENGTH 1
79
80
0
#define SCCPMG_AFFECTED_PC_OFFSET (SCCPMG_AFFECTED_SSN_OFFSET + SCCPMG_AFFECTED_SSN_LENGTH)
81
0
#define ITU_SCCPMG_AFFECTED_PC_LENGTH 2
82
0
#define ANSI_SCCPMG_AFFECTED_PC_LENGTH 3
83
84
0
#define ITU_SCCPMG_SMI_OFFSET (SCCPMG_AFFECTED_PC_OFFSET + ITU_SCCPMG_AFFECTED_PC_LENGTH)
85
0
#define ANSI_SCCPMG_SMI_OFFSET (SCCPMG_AFFECTED_PC_OFFSET + ANSI_SCCPMG_AFFECTED_PC_LENGTH)
86
0
#define SCCPMG_SMI_LENGTH 1
87
14
#define SCCPMG_SMI_MASK 0x3
88
89
0
#define ITU_SCCPMG_CONGESTION_OFFSET (ITU_SCCPMG_SMI_OFFSET + SCCPMG_SMI_LENGTH)
90
0
#define ITU_SCCPMG_CONGESTION_LENGTH 1
91
14
#define ITU_SCCPMG_CONGESTION_MASK 0x0f
92
0
#define CHINESE_ITU_SCCPMG_CONGESTION_OFFSET (ANSI_SCCPMG_SMI_OFFSET + SCCPMG_SMI_LENGTH)
93
94
0
#define SCCPMG_SSN_LENGTH    1
95
96
/* Initialize the protocol and registered fields */
97
static int proto_sccpmg;
98
static int hf_sccpmg_message_type;
99
static int hf_sccpmg_affected_ssn;
100
static int hf_sccpmg_affected_itu_pc;
101
static int hf_sccpmg_affected_japan_pc;
102
static int hf_sccpmg_affected_ansi_pc;
103
static int hf_sccpmg_affected_chinese_pc;
104
static int hf_sccpmg_affected_pc_member;
105
static int hf_sccpmg_affected_pc_cluster;
106
static int hf_sccpmg_affected_pc_network;
107
static int hf_sccpmg_smi;
108
static int hf_sccpmg_congestion_level;
109
110
/* Initialize the subtree pointers */
111
static int ett_sccpmg;
112
static int ett_sccpmg_affected_pc;
113
114
static expert_field ei_sccpmg_unknown_msg;
115
116
static void
117
dissect_sccpmg_affected_ssn(tvbuff_t *tvb, proto_tree *sccpmg_tree)
118
0
{
119
0
  proto_tree_add_item(sccpmg_tree, hf_sccpmg_affected_ssn, tvb,
120
0
          SCCPMG_AFFECTED_SSN_OFFSET, SCCPMG_SSN_LENGTH,
121
0
          ENC_BIG_ENDIAN);
122
0
}
123
124
static void
125
dissect_sccpmg_affected_pc(tvbuff_t *tvb, proto_tree *sccpmg_tree)
126
0
{
127
0
  int offset = SCCPMG_AFFECTED_PC_OFFSET;
128
129
0
  if (mtp3_standard == ITU_STANDARD) {
130
0
    proto_tree_add_item(sccpmg_tree, hf_sccpmg_affected_itu_pc, tvb,
131
0
            offset, ITU_PC_LENGTH, ENC_LITTLE_ENDIAN);
132
0
  } else if (mtp3_standard == JAPAN_STANDARD) {
133
0
    proto_tree_add_item(sccpmg_tree, hf_sccpmg_affected_japan_pc,
134
0
            tvb, offset, JAPAN_PC_LENGTH, ENC_LITTLE_ENDIAN);
135
0
  } else /* ANSI_STANDARD and CHINESE_ITU_STANDARD */ {
136
0
    int *hf_affected_pc;
137
138
0
    if (mtp3_standard == ANSI_STANDARD)
139
0
    {
140
0
      hf_affected_pc = &hf_sccpmg_affected_ansi_pc;
141
0
    } else /* CHINESE_ITU_STANDARD */ {
142
0
      hf_affected_pc = &hf_sccpmg_affected_chinese_pc;
143
0
    }
144
145
    /* create and fill the PC tree */
146
0
    dissect_mtp3_3byte_pc(tvb, offset, sccpmg_tree,
147
0
              ett_sccpmg_affected_pc, *hf_affected_pc,
148
0
              hf_sccpmg_affected_pc_network,
149
0
              hf_sccpmg_affected_pc_cluster,
150
0
              hf_sccpmg_affected_pc_member, 0, 0);
151
152
0
  }
153
0
}
154
155
static void
156
dissect_sccpmg_smi(tvbuff_t *tvb, proto_tree *sccpmg_tree)
157
0
{
158
0
  int offset = 0;
159
160
0
  if (mtp3_standard == ITU_STANDARD || mtp3_standard == JAPAN_STANDARD)
161
0
    offset = ITU_SCCPMG_SMI_OFFSET;
162
0
  else /* ANSI_STANDARD and CHINESE_ITU_STANDARD */
163
0
    offset = ANSI_SCCPMG_SMI_OFFSET;
164
165
0
  proto_tree_add_item(sccpmg_tree, hf_sccpmg_smi, tvb, offset,
166
0
          SCCPMG_SMI_LENGTH, ENC_BIG_ENDIAN);
167
0
}
168
169
static void
170
dissect_sccpmg_congestion_level(tvbuff_t *tvb, proto_tree *sccpmg_tree)
171
0
{
172
0
  int offset = 0;
173
174
0
  if (mtp3_standard == CHINESE_ITU_STANDARD)
175
0
    offset = CHINESE_ITU_SCCPMG_CONGESTION_OFFSET;
176
0
  else /* ITU_STANDARD or JAPAN_STANDARD */
177
0
    offset = ITU_SCCPMG_CONGESTION_OFFSET;
178
179
0
  proto_tree_add_item(sccpmg_tree, hf_sccpmg_congestion_level, tvb,
180
0
          offset, ITU_SCCPMG_CONGESTION_LENGTH, ENC_BIG_ENDIAN);
181
0
}
182
183
static void
184
dissect_sccpmg_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccpmg_tree)
185
1
{
186
1
  uint8_t message_type;
187
188
  /* Extract the message type;  all other processing is based on this */
189
1
  message_type   = tvb_get_uint8(tvb, SCCPMG_MESSAGE_TYPE_OFFSET);
190
191
1
  col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str_const(message_type, sccpmg_message_type_acro_values, "Unknown"));
192
193
1
  if (sccpmg_tree) {
194
    /* add the message type to the protocol tree */
195
1
    proto_tree_add_uint(sccpmg_tree, hf_sccpmg_message_type, tvb,
196
1
            SCCPMG_MESSAGE_TYPE_OFFSET,
197
1
            SCCPMG_MESSAGE_TYPE_LENGTH, message_type);
198
1
  }
199
200
1
  switch(message_type) {
201
0
  case SCCPMG_MESSAGE_TYPE_SBR:
202
0
  case SCCPMG_MESSAGE_TYPE_SNR:
203
0
  case SCCPMG_MESSAGE_TYPE_SRT:
204
0
    if (mtp3_standard != ANSI_STANDARD)
205
0
    {
206
0
      proto_tree_add_expert(sccpmg_tree, pinfo, &ei_sccpmg_unknown_msg, tvb, 0, -1);
207
0
      break;
208
0
    }
209
    /* else fallthrough */
210
0
  case SCCPMG_MESSAGE_TYPE_SSA:
211
0
  case SCCPMG_MESSAGE_TYPE_SSP:
212
0
  case SCCPMG_MESSAGE_TYPE_SST:
213
0
  case SCCPMG_MESSAGE_TYPE_SOR:
214
0
  case SCCPMG_MESSAGE_TYPE_SOG:
215
0
    dissect_sccpmg_affected_ssn(tvb, sccpmg_tree);
216
0
    dissect_sccpmg_affected_pc(tvb, sccpmg_tree);
217
0
    dissect_sccpmg_smi(tvb, sccpmg_tree);
218
219
0
    break;
220
0
  case SCCPMG_MESSAGE_TYPE_SSC:
221
0
    if (mtp3_standard != ANSI_STANDARD)
222
0
    {
223
0
      dissect_sccpmg_affected_ssn(tvb, sccpmg_tree);
224
0
      dissect_sccpmg_affected_pc(tvb, sccpmg_tree);
225
0
      dissect_sccpmg_smi(tvb, sccpmg_tree);
226
0
      dissect_sccpmg_congestion_level(tvb, sccpmg_tree);
227
0
    }
228
    /* else fallthrough */
229
230
1
  default:
231
1
    proto_tree_add_expert(sccpmg_tree, pinfo, &ei_sccpmg_unknown_msg, tvb, 0, -1);
232
1
  }
233
1
}
234
235
static int
236
dissect_sccpmg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
237
1
{
238
1
  proto_item *sccpmg_item;
239
1
  proto_tree *sccpmg_tree = NULL;
240
241
  /* Make entry in the Protocol column on summary display */
242
1
  switch(mtp3_standard) {
243
1
  case ITU_STANDARD:
244
1
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCPMG (Int. ITU)");
245
1
    break;
246
0
  case ANSI_STANDARD:
247
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCPMG (ANSI)");
248
0
    break;
249
0
  case CHINESE_ITU_STANDARD:
250
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "SCCPMG (Chin. ITU)");
251
0
    break;
252
1
  };
253
254
  /* In the interest of speed, if "tree" is NULL, don't do any work not
255
     necessary to generate protocol tree items. */
256
1
  if (tree) {
257
    /* create the sccpmg protocol tree */
258
1
    sccpmg_item = proto_tree_add_item(tree, proto_sccpmg, tvb, 0,
259
1
              -1, ENC_NA);
260
1
    sccpmg_tree = proto_item_add_subtree(sccpmg_item, ett_sccpmg);
261
1
  }
262
263
  /* dissect the message */
264
1
  dissect_sccpmg_message(tvb, pinfo, sccpmg_tree);
265
1
  return tvb_captured_length(tvb);
266
1
}
267
268
/* Register the protocol with Wireshark */
269
void
270
proto_register_sccpmg(void)
271
14
{
272
  /* Setup list of header fields */
273
14
  static hf_register_info hf[] = {
274
14
    { &hf_sccpmg_message_type,
275
14
      { "Message Type", "sccpmg.message_type",
276
14
        FT_UINT8, BASE_HEX, VALS(sccpmg_message_type_values), 0x0,
277
14
        NULL, HFILL}},
278
14
    { &hf_sccpmg_affected_ssn,
279
14
      { "Affected SubSystem Number", "sccpmg.ssn",
280
14
        FT_UINT8, BASE_DEC, NULL, 0x0,
281
14
        NULL, HFILL}},
282
14
    { &hf_sccpmg_affected_itu_pc,
283
14
      { "Affected Point Code", "sccpmg.pc",
284
14
        FT_UINT16, BASE_DEC, NULL, ITU_PC_MASK,
285
14
        NULL, HFILL}},
286
14
    { &hf_sccpmg_affected_japan_pc,
287
14
      { "Affected Point Code", "sccpmg.pc",
288
14
        FT_UINT16, BASE_DEC, NULL, 0x0,
289
14
        NULL, HFILL}},
290
14
    { &hf_sccpmg_affected_ansi_pc,
291
14
      { "Affected Point Code", "sccpmg.ansi_pc",
292
14
        FT_STRING, BASE_NONE, NULL, 0x0,
293
14
        NULL, HFILL}},
294
14
    { &hf_sccpmg_affected_chinese_pc,
295
14
      { "Affected Point Code", "sccpmg.chinese_pc",
296
14
        FT_STRING, BASE_NONE, NULL, 0x0,
297
14
        NULL, HFILL}},
298
14
    { &hf_sccpmg_affected_pc_network,
299
14
      { "Affected PC Network", "sccpmg.network",
300
14
        FT_UINT24, BASE_DEC, NULL, ANSI_NETWORK_MASK,
301
14
        NULL, HFILL}},
302
14
    { &hf_sccpmg_affected_pc_cluster,
303
14
      { "Affected PC Cluster", "sccpmg.cluster",
304
14
        FT_UINT24, BASE_DEC, NULL, ANSI_CLUSTER_MASK,
305
14
        NULL, HFILL}},
306
14
    { &hf_sccpmg_affected_pc_member,
307
14
      { "Affected PC Member", "sccpmg.member",
308
14
        FT_UINT24, BASE_DEC, NULL, ANSI_MEMBER_MASK,
309
14
        NULL, HFILL}},
310
14
    { &hf_sccpmg_smi,
311
14
      { "Subsystem Multiplicity Indicator", "sccpmg.smi",
312
14
        FT_UINT8, BASE_DEC, NULL, SCCPMG_SMI_MASK,
313
14
        NULL, HFILL}},
314
14
    { &hf_sccpmg_congestion_level,
315
14
      { "SCCP Congestion Level (ITU)", "sccpmg.congestion",
316
14
        FT_UINT8, BASE_DEC, NULL, ITU_SCCPMG_CONGESTION_MASK,
317
14
        NULL, HFILL}}
318
14
  };
319
320
  /* Setup protocol subtree array */
321
14
  static int *ett[] = {
322
14
    &ett_sccpmg,
323
14
    &ett_sccpmg_affected_pc
324
14
  };
325
326
14
  static ei_register_info ei[] = {
327
14
    { &ei_sccpmg_unknown_msg, { "sccpmg.unknown_msg", PI_UNDECODED, PI_WARN, "Unknown message", EXPFILL }},
328
14
  };
329
330
14
  expert_module_t* expert_sccpmg;
331
332
  /* Register the protocol name and description */
333
14
  proto_sccpmg = proto_register_protocol("Signalling Connection Control Part Management",
334
14
                 "SCCPMG", "sccpmg");
335
336
  /* Required function calls to register the header fields and subtrees
337
     used */
338
14
  proto_register_field_array(proto_sccpmg, hf, array_length(hf));
339
14
  proto_register_subtree_array(ett, array_length(ett));
340
14
  expert_sccpmg = expert_register_protocol(proto_sccpmg);
341
14
  expert_register_field_array(expert_sccpmg, ei, array_length(ei));
342
343
  /* Register the dissector handle */
344
14
  sccpmg_handle = register_dissector("sccpmg", dissect_sccpmg, proto_sccpmg);
345
14
}
346
347
void
348
proto_reg_handoff_sccpmg(void)
349
14
{
350
  /* Register for SCCP SSN=1 messages */
351
14
  dissector_add_uint("sccp.ssn", SCCPMG_SSN, sccpmg_handle);
352
14
}
353
354
/*
355
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
356
 *
357
 * Local variables:
358
 * c-basic-offset: 8
359
 * tab-width: 8
360
 * indent-tabs-mode: t
361
 * End:
362
 *
363
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
364
 * :indentSize=8:tabSize=8:noTabs=false:
365
 */