summaryrefslogtreecommitdiffstats
path: root/print-m3ua.c
blob: ecf7db834385238019e90cfe81c1ceba2c92b085 (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
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
/* Copyright (c) 2013, The TCPDUMP project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/* \summary: Message Transfer Part 3 (MTP3) User Adaptation Layer (M3UA) printer */

/* RFC 4666 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "netdissect-stdinc.h"

#define ND_LONGJMP_FROM_TCHECK
#include "netdissect.h"
#include "extract.h"


#define M3UA_REL_1_0 1

struct m3ua_common_header {
  nd_uint8_t  v;
  nd_uint8_t  reserved;
  nd_uint8_t  msg_class;
  nd_uint8_t  msg_type;
  nd_uint32_t len;
};

struct m3ua_param_header {
  nd_uint16_t tag;
  nd_uint16_t len;
};

/* message classes */
#define M3UA_MSGC_MGMT 0
#define M3UA_MSGC_TRANSFER 1
#define M3UA_MSGC_SSNM 2
#define M3UA_MSGC_ASPSM 3
#define M3UA_MSGC_ASPTM 4
/* reserved values */
#define M3UA_MSGC_RKM 9

static const struct tok MessageClasses[] = {
	{ M3UA_MSGC_MGMT,     "Management"            },
	{ M3UA_MSGC_TRANSFER, "Transfer"              },
	{ M3UA_MSGC_SSNM,     "SS7"                   },
	{ M3UA_MSGC_ASPSM,    "ASP"                   },
	{ M3UA_MSGC_ASPTM,    "ASP"                   },
	{ M3UA_MSGC_RKM,      "Routing Key Management"},
	{ 0, NULL }
};

/* management messages */
#define M3UA_MGMT_ERROR 0
#define M3UA_MGMT_NOTIFY 1

static const struct tok MgmtMessages[] = {
  { M3UA_MGMT_ERROR, "Error" },
  { M3UA_MGMT_NOTIFY, "Notify" },
  { 0, NULL }
};

/* transfer messages */
#define M3UA_TRANSFER_DATA 1

static const struct tok TransferMessages[] = {
  { M3UA_TRANSFER_DATA, "Data" },
  { 0, NULL }
};

/* SS7 Signaling Network Management messages */
#define M3UA_SSNM_DUNA 1
#define M3UA_SSNM_DAVA 2
#define M3UA_SSNM_DAUD 3
#define M3UA_SSNM_SCON 4
#define M3UA_SSNM_DUPU 5
#define M3UA_SSNM_DRST 6

static const struct tok SS7Messages[] = {
  { M3UA_SSNM_DUNA, "Destination Unavailable" },
  { M3UA_SSNM_DAVA, "Destination Available" },
  { M3UA_SSNM_DAUD, "Destination State Audit" },
  { M3UA_SSNM_SCON, "Signalling Congestion" },
  { M3UA_SSNM_DUPU, "Destination User Part Unavailable" },
  { M3UA_SSNM_DRST, "Destination Restricted" },
  { 0, NULL }
};

/* ASP State Maintenance messages */
#define M3UA_ASP_UP 1
#define M3UA_ASP_DN 2
#define M3UA_ASP_BEAT 3
#define M3UA_ASP_UP_ACK 4
#define M3UA_ASP_DN_ACK 5
#define M3UA_ASP_BEAT_ACK 6

static const struct tok ASPStateMessages[] = {
  { M3UA_ASP_UP, "Up" },
  { M3UA_ASP_DN, "Down" },
  { M3UA_ASP_BEAT, "Heartbeat" },
  { M3UA_ASP_UP_ACK, "Up Acknowledgement" },
  { M3UA_ASP_DN_ACK, "Down Acknowledgement" },
  { M3UA_ASP_BEAT_ACK, "Heartbeat Acknowledgement" },
  { 0, NULL }
};

/* ASP Traffic Maintenance messages */
#define M3UA_ASP_AC 1
#define M3UA_ASP_IA 2
#define M3UA_ASP_AC_ACK 3
#define M3UA_ASP_IA_ACK 4

static const struct tok ASPTrafficMessages[] = {
  { M3UA_ASP_AC, "Active" },
  { M3UA_ASP_IA, "Inactive" },
  { M3UA_ASP_AC_ACK, "Active Acknowledgement" },
  { M3UA_ASP_IA_ACK, "Inactive Acknowledgement" },
  { 0, NULL }
};

/* Routing Key Management messages */
#define M3UA_RKM_REQ 1
#define M3UA_RKM_RSP 2
#define M3UA_RKM_DEREQ 3
#define M3UA_RKM_DERSP 4

static const struct tok RoutingKeyMgmtMessages[] = {
  { M3UA_RKM_REQ, "Registration Request" },
  { M3UA_RKM_RSP, "Registration Response" },
  { M3UA_RKM_DEREQ, "Deregistration Request" },
  { M3UA_RKM_DERSP, "Deregistration Response" },
  { 0, NULL }
};

static const struct uint_tokary m3ua_msgc2tokary[] = {
	{ M3UA_MSGC_MGMT,     MgmtMessages           },
	{ M3UA_MSGC_TRANSFER, TransferMessages       },
	{ M3UA_MSGC_SSNM,     SS7Messages            },
	{ M3UA_MSGC_ASPSM,    ASPStateMessages       },
	{ M3UA_MSGC_ASPTM,    ASPTrafficMessages     },
	{ M3UA_MSGC_RKM,      RoutingKeyMgmtMessages },
	/* uint2tokary() does not use array termination. */
};

/* M3UA Parameters */
#define M3UA_PARAM_INFO 0x0004
#define M3UA_PARAM_ROUTING_CTX 0x0006
#define M3UA_PARAM_DIAGNOSTIC 0x0007
#define M3UA_PARAM_HB_DATA 0x0009
#define M3UA_PARAM_TRAFFIC_MODE_TYPE 0x000b
#define M3UA_PARAM_ERROR_CODE 0x000c
#define M3UA_PARAM_STATUS 0x000d
#define M3UA_PARAM_ASP_ID 0x0011
#define M3UA_PARAM_AFFECTED_POINT_CODE 0x0012
#define M3UA_PARAM_CORR_ID 0x0013

#define M3UA_PARAM_NETWORK_APPEARANCE 0x0200
#define M3UA_PARAM_USER 0x0204
#define M3UA_PARAM_CONGESTION_INDICATION 0x0205
#define M3UA_PARAM_CONCERNED_DST 0x0206
#define M3UA_PARAM_ROUTING_KEY 0x0207
#define M3UA_PARAM_REG_RESULT 0x0208
#define M3UA_PARAM_DEREG_RESULT 0x0209
#define M3UA_PARAM_LOCAL_ROUTING_KEY_ID 0x020a
#define M3UA_PARAM_DST_POINT_CODE 0x020b
#define M3UA_PARAM_SI 0x020c
#define M3UA_PARAM_ORIGIN_POINT_CODE_LIST 0x020e
#define M3UA_PARAM_PROTO_DATA 0x0210
#define M3UA_PARAM_REG_STATUS 0x0212
#define M3UA_PARAM_DEREG_STATUS 0x0213

static const struct tok ParamName[] = {
  { M3UA_PARAM_INFO, "INFO String" },
  { M3UA_PARAM_ROUTING_CTX, "Routing Context" },
  { M3UA_PARAM_DIAGNOSTIC, "Diagnostic Info" },
  { M3UA_PARAM_HB_DATA, "Heartbeat Data" },
  { M3UA_PARAM_TRAFFIC_MODE_TYPE, "Traffic Mode Type" },
  { M3UA_PARAM_ERROR_CODE, "Error Code" },
  { M3UA_PARAM_STATUS, "Status" },
  { M3UA_PARAM_ASP_ID, "ASP Identifier" },
  { M3UA_PARAM_AFFECTED_POINT_CODE, "Affected Point Code" },
  { M3UA_PARAM_CORR_ID, "Correlation ID" },
  { M3UA_PARAM_NETWORK_APPEARANCE, "Network Appearance" },
  { M3UA_PARAM_USER, "User/Cause" },
  { M3UA_PARAM_CONGESTION_INDICATION, "Congestion Indications" },
  { M3UA_PARAM_CONCERNED_DST, "Concerned Destination" },
  { M3UA_PARAM_ROUTING_KEY, "Routing Key" },
  { M3UA_PARAM_REG_RESULT, "Registration Result" },
  { M3UA_PARAM_DEREG_RESULT, "Deregistration Result" },
  { M3UA_PARAM_LOCAL_ROUTING_KEY_ID, "Local Routing Key Identifier" },
  { M3UA_PARAM_DST_POINT_CODE, "Destination Point Code" },
  { M3UA_PARAM_SI, "Service Indicators" },
  { M3UA_PARAM_ORIGIN_POINT_CODE_LIST, "Originating Point Code List" },
  { M3UA_PARAM_PROTO_DATA, "Protocol Data" },
  { M3UA_PARAM_REG_STATUS, "Registration Status" },
  { M3UA_PARAM_DEREG_STATUS, "Deregistration Status" },
  { 0, NULL }
};

static void
tag_value_print(netdissect_options *ndo,
                const u_char *buf, const uint16_t tag, const uint16_t size)
{
  switch (tag) {
  case M3UA_PARAM_NETWORK_APPEARANCE:
  case M3UA_PARAM_ROUTING_CTX:
  case M3UA_PARAM_CORR_ID:
    /* buf and size don't include the header */
    if (size < 4)
      goto invalid;
    ND_PRINT("0x%08x", GET_BE_U_4(buf));
    break;
  /* ... */
  default:
    ND_PRINT("(length %zu)", size + sizeof(struct m3ua_param_header));
  }
  ND_TCHECK_LEN(buf, size);
  return;

invalid:
  nd_print_invalid(ndo);
  ND_TCHECK_LEN(buf, size);
}

/*
 *     0                   1                   2                   3
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *    |          Parameter Tag        |       Parameter Length        |
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *    \                                                               \
 *    /                       Parameter Value                         /
 *    \                                                               \
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 */
static void
m3ua_tags_print(netdissect_options *ndo,
                const u_char *buf, const u_int size)
{
  const u_char *p = buf;
  int align;
  uint16_t hdr_tag;
  uint16_t hdr_len;

  while (p < buf + size) {
    if (p + sizeof(struct m3ua_param_header) > buf + size)
      goto invalid;
    /* Parameter Tag */
    hdr_tag = GET_BE_U_2(p);
    ND_PRINT("\n\t\t\t%s: ", tok2str(ParamName, "Unknown Parameter (0x%04x)", hdr_tag));
    /* Parameter Length */
    hdr_len = GET_BE_U_2(p + 2);
    if (hdr_len < sizeof(struct m3ua_param_header))
      goto invalid;
    /* Parameter Value */
    align = (p + hdr_len - buf) % 4;
    align = align ? 4 - align : 0;
    ND_TCHECK_LEN(p, hdr_len + align);
    tag_value_print(ndo, p, hdr_tag, hdr_len - sizeof(struct m3ua_param_header));
    p += hdr_len + align;
  }
  return;

invalid:
  nd_print_invalid(ndo);
  ND_TCHECK_LEN(buf, size);
}

/*
 *     0                   1                   2                   3
 *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *    |    Version    |   Reserved    | Message Class | Message Type  |
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *    |                        Message Length                         |
 *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *    \                                                               \
 *    /                                                               /
 */
void
m3ua_print(netdissect_options *ndo,
           const u_char *buf, const u_int size)
{
  const struct m3ua_common_header *hdr = (const struct m3ua_common_header *) buf;
  const struct tok *dict;
  uint8_t msg_class;

  ndo->ndo_protocol = "m3ua";
  /* size includes the header */
  if (size < sizeof(struct m3ua_common_header))
    goto invalid;
  ND_TCHECK_SIZE(hdr);
  if (GET_U_1(hdr->v) != M3UA_REL_1_0)
    return;

  msg_class = GET_U_1(hdr->msg_class);
  dict = uint2tokary(m3ua_msgc2tokary, msg_class);

  ND_PRINT("\n\t\t%s", tok2str(MessageClasses, "Unknown message class %i", msg_class));
  if (dict != NULL)
    ND_PRINT(" %s Message",
             tok2str(dict, "Unknown (0x%02x)", GET_U_1(hdr->msg_type)));

  if (size != GET_BE_U_4(hdr->len))
    ND_PRINT("\n\t\t\t@@@@@@ Corrupted length %u of message @@@@@@",
             GET_BE_U_4(hdr->len));
  else
    m3ua_tags_print(ndo, buf + sizeof(struct m3ua_common_header),
                    GET_BE_U_4(hdr->len) - sizeof(struct m3ua_common_header));
  return;

invalid:
  nd_print_invalid(ndo);
  ND_TCHECK_LEN(buf, size);
}