Coverage Report

Created: 2025-02-15 06:25

/src/wireshark/epan/dissectors/packet-tcap.c
Line
Count
Source (jump to first uncovered line)
1
/* Do not modify this file. Changes will be overwritten.                      */
2
/* Generated automatically by the ASN.1 to Wireshark dissector compiler       */
3
/* packet-tcap.c                                                              */
4
/* asn2wrs.py -b -q -L -p tcap -c ./tcap.cnf -s ./packet-tcap-template -D . -O ../.. tcap.asn UnidialoguePDUs.asn DialoguePDUs.asn */
5
6
/* packet-tcap-template.c
7
 * Routines for  TCAP
8
 * Copyright 2004 - 2005, Tim Endean <endeant@hotmail.com>
9
 * Built from the gsm-map dissector Copyright 2004 - 2005, Anders Broman <anders.broman@ericsson.com>
10
 *
11
 * Wireshark - Network traffic analyzer
12
 * By Gerald Combs <gerald@wireshark.org>
13
 * Copyright 1998 Gerald Combs
14
 *
15
 * SPDX-License-Identifier: GPL-2.0-or-later
16
 * References: ETSI 300 374
17
 */
18
19
#include "config.h"
20
21
#include <epan/packet.h>
22
#include <epan/exceptions.h>
23
#include <epan/prefs.h>
24
#include <epan/oids.h>
25
#include <epan/asn1.h>
26
#include <epan/address_types.h>
27
#include <epan/strutil.h>
28
#include <epan/show_exception.h>
29
#include <wsutil/array.h>
30
31
#include "packet-ber.h"
32
#include "packet-tcap.h"
33
#include "packet-mtp3.h"
34
35
36
14
#define PNAME  "Transaction Capabilities Application Part"
37
14
#define PSNAME "TCAP"
38
14
#define PFNAME "tcap"
39
40
/* Initialize the protocol and registered fields */
41
static int proto_tcap;
42
static int hf_tcap_tag;
43
static int hf_tcap_length;
44
static int hf_tcap_data;
45
static int hf_tcap_tid;
46
static int hf_tcap_constructor_eoc;
47
48
int hf_tcapsrt_SessionId;
49
int hf_tcapsrt_Duplicate;
50
int hf_tcapsrt_BeginSession;
51
int hf_tcapsrt_EndSession;
52
int hf_tcapsrt_SessionTime;
53
54
static int hf_tcap_UniDialoguePDU_PDU;            /* UniDialoguePDU */
55
static int hf_tcap_DialoguePDU_PDU;               /* DialoguePDU */
56
static int hf_tcap_oid;                           /* OBJECT_IDENTIFIER */
57
static int hf_tcap_dialog;                        /* Dialog1 */
58
static int hf_tcap_unidirectional;                /* Unidirectional */
59
static int hf_tcap_begin;                         /* Begin */
60
static int hf_tcap_end;                           /* End */
61
static int hf_tcap_continue;                      /* Continue */
62
static int hf_tcap_abort;                         /* Abort */
63
static int hf_tcap_dialoguePortion;               /* DialoguePortion */
64
static int hf_tcap_components;                    /* ComponentPortion */
65
static int hf_tcap_otid;                          /* OrigTransactionID */
66
static int hf_tcap_dtid;                          /* DestTransactionID */
67
static int hf_tcap_reason;                        /* Reason */
68
static int hf_tcap_p_abortCause;                  /* P_AbortCause */
69
static int hf_tcap_u_abortCause;                  /* DialoguePortion */
70
static int hf_tcap__untag_item;                   /* Component */
71
static int hf_tcap_invoke;                        /* Invoke */
72
static int hf_tcap_returnResultLast;              /* ReturnResult */
73
static int hf_tcap_returnError;                   /* ReturnError */
74
static int hf_tcap_reject;                        /* Reject */
75
static int hf_tcap_returnResultNotLast;           /* ReturnResult */
76
static int hf_tcap_invokeID;                      /* InvokeIdType */
77
static int hf_tcap_linkedID;                      /* InvokeIdType */
78
static int hf_tcap_opCode;                        /* OPERATION */
79
static int hf_tcap_parameter;                     /* Parameter */
80
static int hf_tcap_resultretres;                  /* T_resultretres */
81
static int hf_tcap_errorCode;                     /* ErrorCode */
82
static int hf_tcap_invokeIDRej;                   /* T_invokeIDRej */
83
static int hf_tcap_derivable;                     /* InvokeIdType */
84
static int hf_tcap_not_derivable;                 /* NULL */
85
static int hf_tcap_problem;                       /* T_problem */
86
static int hf_tcap_generalProblem;                /* GeneralProblem */
87
static int hf_tcap_invokeProblem;                 /* InvokeProblem */
88
static int hf_tcap_returnResultProblem;           /* ReturnResultProblem */
89
static int hf_tcap_returnErrorProblem;            /* ReturnErrorProblem */
90
static int hf_tcap_localValue;                    /* INTEGER */
91
static int hf_tcap_globalValue;                   /* OBJECT_IDENTIFIER */
92
static int hf_tcap_nationaler;                    /* INTEGER_M32768_32767 */
93
static int hf_tcap_privateer;                     /* INTEGER */
94
static int hf_tcap_unidialoguePDU;                /* AUDT_apdu */
95
static int hf_tcap_audt_protocol_version;         /* AUDT_protocol_version */
96
static int hf_tcap_audt_application_context_name;  /* AUDT_application_context_name */
97
static int hf_tcap_audt_user_information;         /* AUDT_user_information */
98
static int hf_tcap_audt_user_information_item;    /* EXTERNAL */
99
static int hf_tcap_dialogueRequest;               /* AARQ_apdu */
100
static int hf_tcap_dialogueResponse;              /* AARE_apdu */
101
static int hf_tcap_dialogueAbort;                 /* ABRT_apdu */
102
static int hf_tcap_aarq_protocol_version;         /* AARQ_protocol_version */
103
static int hf_tcap_aarq_application_context_name;  /* AARQ_application_context_name */
104
static int hf_tcap_aarq_user_information;         /* AARQ_user_information */
105
static int hf_tcap_aarq_user_information_item;    /* EXTERNAL */
106
static int hf_tcap_aare_protocol_version;         /* AARE_protocol_version */
107
static int hf_tcap_aare_application_context_name;  /* AARE_application_context_name */
108
static int hf_tcap_result;                        /* Associate_result */
109
static int hf_tcap_result_source_diagnostic;      /* Associate_source_diagnostic */
110
static int hf_tcap_aare_user_information;         /* AARE_user_information */
111
static int hf_tcap_aare_user_information_item;    /* EXTERNAL */
112
static int hf_tcap_abort_source;                  /* ABRT_source */
113
static int hf_tcap_abrt_user_information;         /* ABRT_user_information */
114
static int hf_tcap_abrt_user_information_item;    /* EXTERNAL */
115
static int hf_tcap_dialogue_service_user;         /* T_dialogue_service_user */
116
static int hf_tcap_dialogue_service_provider;     /* T_dialogue_service_provider */
117
/* named bits */
118
static int hf_tcap_AUDT_protocol_version_version1;
119
static int hf_tcap_AARQ_protocol_version_version1;
120
static int hf_tcap_AARE_protocol_version_version1;
121
122
/* Initialize the subtree pointers */
123
static int ett_tcap;
124
static int ett_param;
125
126
static int ett_otid;
127
static int ett_dtid;
128
int ett_tcap_stat;
129
130
static struct tcapsrt_info_t * gp_tcapsrt_info;
131
static bool tcap_subdissector_used=false;
132
static dissector_handle_t requested_subdissector_handle;
133
134
static int ss7pc_address_type = -1;
135
136
static struct tcaphash_context_t * gp_tcap_context;
137
138
static int ett_tcap_ExternalPDU_U;
139
static int ett_tcap_TCMessage;
140
static int ett_tcap_Unidirectional;
141
static int ett_tcap_Begin;
142
static int ett_tcap_End;
143
static int ett_tcap_Continue;
144
static int ett_tcap_Abort;
145
static int ett_tcap_Reason;
146
static int ett_tcap_SEQUENCE_SIZE_1_MAX_OF_Component;
147
static int ett_tcap_Component;
148
static int ett_tcap_Invoke;
149
static int ett_tcap_ReturnResult;
150
static int ett_tcap_T_resultretres;
151
static int ett_tcap_ReturnError;
152
static int ett_tcap_Reject;
153
static int ett_tcap_T_invokeIDRej;
154
static int ett_tcap_T_problem;
155
static int ett_tcap_OPERATION;
156
static int ett_tcap_ErrorCode;
157
static int ett_tcap_UniDialoguePDU;
158
static int ett_tcap_AUDT_apdu_U;
159
static int ett_tcap_AUDT_protocol_version;
160
static int ett_tcap_AUDT_user_information;
161
static int ett_tcap_DialoguePDU;
162
static int ett_tcap_AARQ_apdu_U;
163
static int ett_tcap_AARQ_protocol_version;
164
static int ett_tcap_AARQ_user_information;
165
static int ett_tcap_AARE_apdu_U;
166
static int ett_tcap_AARE_protocol_version;
167
static int ett_tcap_AARE_user_information;
168
static int ett_tcap_ABRT_apdu_U;
169
static int ett_tcap_ABRT_user_information;
170
static int ett_tcap_Associate_source_diagnostic;
171
172
/* When several Tcap components are received in a single TCAP message,
173
   we have to use several buffers for the stored parameters
174
   because else this data are erased during TAP dissector call */
175
27
#define MAX_TCAP_INSTANCE 10
176
static int tcapsrt_global_current=0;
177
static struct tcapsrt_info_t tcapsrt_global_info[MAX_TCAP_INSTANCE];
178
179
28
#define MAX_SSN 254
180
static range_t *global_ssn_range;
181
static range_t *ssn_range;
182
183
/* These two timeout (in second) are used when some message are lost,
184
   or when the same TCAP transcation identifier is reused */
185
static unsigned gtcap_RepetitionTimeout = 10;
186
static unsigned gtcap_LostTimeout = 30;
187
static bool gtcap_PersistentSRT=false;
188
bool gtcap_DisplaySRT=false;
189
bool gtcap_StatSRT=false;
190
191
/* Global hash tables*/
192
static wmem_map_t *tcaphash_context;
193
static wmem_map_t *tcaphash_begin;
194
static wmem_map_t *tcaphash_cont;
195
static wmem_map_t *tcaphash_end;
196
static wmem_map_t *tcaphash_ansi;
197
198
static uint32_t tcapsrt_global_SessionId=1;
199
200
static dissector_handle_t tcap_handle;
201
static dissector_table_t ber_oid_dissector_table;
202
static const char * cur_oid;
203
static const char * tcapext_oid;
204
static proto_tree * tcap_top_tree;
205
static proto_tree * tcap_stat_tree;
206
207
static dissector_handle_t data_handle;
208
static dissector_handle_t ansi_tcap_handle;
209
210
static int dissect_tcap_param(asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset);
211
static bool dissect_tcap_ITU_ComponentPDU(bool implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_);
212
213
static dissector_table_t ansi_sub_dissectors;
214
static dissector_table_t itu_sub_dissectors;
215
216
140
extern void add_ansi_tcap_subdissector(uint32_t ssn, dissector_handle_t dissector) {
217
140
  dissector_add_uint("ansi_tcap.ssn",ssn,dissector);
218
140
  dissector_add_uint("sccp.ssn",ssn,tcap_handle);
219
140
}
220
221
154
extern void add_itu_tcap_subdissector(uint32_t ssn, dissector_handle_t dissector) {
222
154
  dissector_add_uint("itu_tcap.ssn",ssn,dissector);
223
154
  dissector_add_uint("sccp.ssn",ssn,tcap_handle);
224
154
}
225
226
0
extern void delete_ansi_tcap_subdissector(uint32_t ssn, dissector_handle_t dissector) {
227
0
  dissector_delete_uint("ansi_tcap.ssn",ssn,dissector);
228
0
  if (!get_itu_tcap_subdissector(ssn))
229
0
      dissector_delete_uint("sccp.ssn",ssn,tcap_handle);
230
0
}
231
0
extern void delete_itu_tcap_subdissector(uint32_t ssn, dissector_handle_t dissector _U_) {
232
0
  dissector_delete_uint("itu_tcap.ssn",ssn,dissector);
233
0
  if (!get_ansi_tcap_subdissector(ssn))
234
0
    dissector_delete_uint("sccp.ssn", ssn,tcap_handle);
235
0
}
236
237
0
dissector_handle_t get_ansi_tcap_subdissector(uint32_t ssn) {
238
0
  return dissector_get_uint_handle(ansi_sub_dissectors, ssn);
239
0
}
240
241
16
dissector_handle_t get_itu_tcap_subdissector(uint32_t ssn) {
242
16
  return dissector_get_uint_handle(itu_sub_dissectors, ssn);
243
16
}
244
245
246
247
static int
248
0
dissect_tcap_OBJECT_IDENTIFIER(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
249
0
  offset = dissect_ber_object_identifier(implicit_tag, actx, tree, tvb, offset, hf_index, NULL);
250
251
0
  return offset;
252
0
}
253
254
255
256
static int
257
0
dissect_tcap_Dialog1(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
258
259
0
  offset = dissect_tcap_DialoguePDU(true, tvb, offset, actx, tree, -1);
260
261
262
0
  return offset;
263
0
}
264
265
266
static const ber_sequence_t ExternalPDU_U_sequence[] = {
267
  { &hf_tcap_oid            , BER_CLASS_UNI, BER_UNI_TAG_OID, BER_FLAGS_NOOWNTAG, dissect_tcap_OBJECT_IDENTIFIER },
268
  { &hf_tcap_dialog         , BER_CLASS_CON, 0, BER_FLAGS_IMPLTAG, dissect_tcap_Dialog1 },
269
  { NULL, 0, 0, 0, NULL }
270
};
271
272
static int
273
0
dissect_tcap_ExternalPDU_U(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
274
0
  offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
275
0
                                   ExternalPDU_U_sequence, hf_index, ett_tcap_ExternalPDU_U);
276
277
0
  return offset;
278
0
}
279
280
281
282
static int
283
0
dissect_tcap_ExternalPDU(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
284
285
0
  offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
286
0
                                      hf_index, BER_CLASS_UNI, 8, true, dissect_tcap_ExternalPDU_U);
287
288
289
290
0
  return offset;
291
0
}
292
293
294
295
static int
296
0
dissect_tcap_DialogueOC(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
297
298
0
  offset = dissect_tcap_ExternalPDU(false /*implicit_tag*/, tvb, offset, actx, tree, -1);
299
300
301
0
  return offset;
302
0
}
303
304
305
306
static int
307
0
dissect_tcap_DialoguePortion(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
308
0
  offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
309
0
                                      hf_index, BER_CLASS_APP, 11, true, dissect_tcap_DialogueOC);
310
311
0
  return offset;
312
0
}
313
314
315
316
static int
317
0
dissect_tcap_InvokeIdType(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
318
0
  offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
319
0
                                                NULL);
320
321
0
  return offset;
322
0
}
323
324
325
326
static int
327
0
dissect_tcap_INTEGER(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
328
0
  offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
329
0
                                                NULL);
330
331
0
  return offset;
332
0
}
333
334
335
static const value_string tcap_OPERATION_vals[] = {
336
  {   0, "localValue" },
337
  {   1, "globalValue" },
338
  { 0, NULL }
339
};
340
341
static const ber_choice_t OPERATION_choice[] = {
342
  {   0, &hf_tcap_localValue     , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_tcap_INTEGER },
343
  {   1, &hf_tcap_globalValue    , BER_CLASS_UNI, BER_UNI_TAG_OID, BER_FLAGS_NOOWNTAG, dissect_tcap_OBJECT_IDENTIFIER },
344
  { 0, NULL, 0, 0, 0, NULL }
345
};
346
347
static int
348
0
dissect_tcap_OPERATION(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
349
0
  offset = dissect_ber_choice(actx, tree, tvb, offset,
350
0
                                 OPERATION_choice, hf_index, ett_tcap_OPERATION,
351
0
                                 NULL);
352
353
0
  return offset;
354
0
}
355
356
357
358
static int
359
0
dissect_tcap_Parameter(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
360
361
0
  offset = dissect_tcap_param(actx,tree,tvb,offset);
362
363
364
0
  return offset;
365
0
}
366
367
368
static const ber_sequence_t Invoke_sequence[] = {
369
  { &hf_tcap_invokeID       , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_tcap_InvokeIdType },
370
  { &hf_tcap_linkedID       , BER_CLASS_CON, 0, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_tcap_InvokeIdType },
371
  { &hf_tcap_opCode         , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_tcap_OPERATION },
372
  { &hf_tcap_parameter      , BER_CLASS_ANY, 0, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_tcap_Parameter },
373
  { NULL, 0, 0, 0, NULL }
374
};
375
376
static int
377
0
dissect_tcap_Invoke(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
378
0
  offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
379
0
                                   Invoke_sequence, hf_index, ett_tcap_Invoke);
380
381
0
  return offset;
382
0
}
383
384
385
static const ber_sequence_t T_resultretres_sequence[] = {
386
  { &hf_tcap_opCode         , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_tcap_OPERATION },
387
  { &hf_tcap_parameter      , BER_CLASS_ANY, 0, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_tcap_Parameter },
388
  { NULL, 0, 0, 0, NULL }
389
};
390
391
static int
392
0
dissect_tcap_T_resultretres(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
393
0
  offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
394
0
                                   T_resultretres_sequence, hf_index, ett_tcap_T_resultretres);
395
396
0
  return offset;
397
0
}
398
399
400
static const ber_sequence_t ReturnResult_sequence[] = {
401
  { &hf_tcap_invokeID       , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_tcap_InvokeIdType },
402
  { &hf_tcap_resultretres   , BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_tcap_T_resultretres },
403
  { NULL, 0, 0, 0, NULL }
404
};
405
406
static int
407
0
dissect_tcap_ReturnResult(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
408
0
  offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
409
0
                                   ReturnResult_sequence, hf_index, ett_tcap_ReturnResult);
410
411
0
  return offset;
412
0
}
413
414
415
416
static int
417
0
dissect_tcap_INTEGER_M32768_32767(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
418
0
  offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
419
0
                                                NULL);
420
421
0
  return offset;
422
0
}
423
424
425
static const value_string tcap_ErrorCode_vals[] = {
426
  {  19, "nationaler" },
427
  {  20, "privateer" },
428
  { 0, NULL }
429
};
430
431
static const ber_choice_t ErrorCode_choice[] = {
432
  {  19, &hf_tcap_nationaler     , BER_CLASS_PRI, 19, BER_FLAGS_IMPLTAG, dissect_tcap_INTEGER_M32768_32767 },
433
  {  20, &hf_tcap_privateer      , BER_CLASS_PRI, 20, BER_FLAGS_IMPLTAG, dissect_tcap_INTEGER },
434
  { 0, NULL, 0, 0, 0, NULL }
435
};
436
437
static int
438
0
dissect_tcap_ErrorCode(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
439
0
  offset = dissect_ber_choice(actx, tree, tvb, offset,
440
0
                                 ErrorCode_choice, hf_index, ett_tcap_ErrorCode,
441
0
                                 NULL);
442
443
0
  return offset;
444
0
}
445
446
447
static const ber_sequence_t ReturnError_sequence[] = {
448
  { &hf_tcap_invokeID       , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_tcap_InvokeIdType },
449
  { &hf_tcap_errorCode      , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_tcap_ErrorCode },
450
  { &hf_tcap_parameter      , BER_CLASS_ANY, 0, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_tcap_Parameter },
451
  { NULL, 0, 0, 0, NULL }
452
};
453
454
static int
455
0
dissect_tcap_ReturnError(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
456
0
  offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
457
0
                                   ReturnError_sequence, hf_index, ett_tcap_ReturnError);
458
459
0
  return offset;
460
0
}
461
462
463
464
static int
465
0
dissect_tcap_NULL(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
466
0
  offset = dissect_ber_null(implicit_tag, actx, tree, tvb, offset, hf_index);
467
468
0
  return offset;
469
0
}
470
471
472
static const value_string tcap_T_invokeIDRej_vals[] = {
473
  {   0, "derivable" },
474
  {   1, "not-derivable" },
475
  { 0, NULL }
476
};
477
478
static const ber_choice_t T_invokeIDRej_choice[] = {
479
  {   0, &hf_tcap_derivable      , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_tcap_InvokeIdType },
480
  {   1, &hf_tcap_not_derivable  , BER_CLASS_UNI, BER_UNI_TAG_NULL, BER_FLAGS_NOOWNTAG, dissect_tcap_NULL },
481
  { 0, NULL, 0, 0, 0, NULL }
482
};
483
484
static int
485
0
dissect_tcap_T_invokeIDRej(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
486
0
  offset = dissect_ber_choice(actx, tree, tvb, offset,
487
0
                                 T_invokeIDRej_choice, hf_index, ett_tcap_T_invokeIDRej,
488
0
                                 NULL);
489
490
0
  return offset;
491
0
}
492
493
494
static const value_string tcap_GeneralProblem_vals[] = {
495
  {   0, "unrecognizedComponent" },
496
  {   1, "mistypedComponent" },
497
  {   2, "badlyStructuredComponent" },
498
  { 0, NULL }
499
};
500
501
502
static int
503
0
dissect_tcap_GeneralProblem(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
504
0
  offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
505
0
                                                NULL);
506
507
0
  return offset;
508
0
}
509
510
511
static const value_string tcap_InvokeProblem_vals[] = {
512
  {   0, "duplicateInvokeID" },
513
  {   1, "unrecognizedOperation" },
514
  {   2, "mistypedParameter" },
515
  {   3, "resourceLimitation" },
516
  {   4, "initiatingRelease" },
517
  {   5, "unrecognizedLinkedID" },
518
  {   6, "linkedResponseUnexpected" },
519
  {   7, "unexpectedLinkedOperation" },
520
  { 0, NULL }
521
};
522
523
524
static int
525
0
dissect_tcap_InvokeProblem(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
526
0
  offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
527
0
                                                NULL);
528
529
0
  return offset;
530
0
}
531
532
533
static const value_string tcap_ReturnResultProblem_vals[] = {
534
  {   0, "unrecognizedInvokeID" },
535
  {   1, "returnResultUnexpected" },
536
  {   2, "mistypedParameter" },
537
  { 0, NULL }
538
};
539
540
541
static int
542
0
dissect_tcap_ReturnResultProblem(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
543
0
  offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
544
0
                                                NULL);
545
546
0
  return offset;
547
0
}
548
549
550
static const value_string tcap_ReturnErrorProblem_vals[] = {
551
  {   0, "unrecognizedInvokeID" },
552
  {   1, "returnErrorUnexpected" },
553
  {   2, "unrecognizedError" },
554
  {   3, "unexpectedError" },
555
  {   4, "mistypedParameter" },
556
  { 0, NULL }
557
};
558
559
560
static int
561
0
dissect_tcap_ReturnErrorProblem(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
562
0
  offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
563
0
                                                NULL);
564
565
0
  return offset;
566
0
}
567
568
569
static const value_string tcap_T_problem_vals[] = {
570
  {   0, "generalProblem" },
571
  {   1, "invokeProblem" },
572
  {   2, "returnResultProblem" },
573
  {   3, "returnErrorProblem" },
574
  { 0, NULL }
575
};
576
577
static const ber_choice_t T_problem_choice[] = {
578
  {   0, &hf_tcap_generalProblem , BER_CLASS_CON, 0, BER_FLAGS_IMPLTAG, dissect_tcap_GeneralProblem },
579
  {   1, &hf_tcap_invokeProblem  , BER_CLASS_CON, 1, BER_FLAGS_IMPLTAG, dissect_tcap_InvokeProblem },
580
  {   2, &hf_tcap_returnResultProblem, BER_CLASS_CON, 2, BER_FLAGS_IMPLTAG, dissect_tcap_ReturnResultProblem },
581
  {   3, &hf_tcap_returnErrorProblem, BER_CLASS_CON, 3, BER_FLAGS_IMPLTAG, dissect_tcap_ReturnErrorProblem },
582
  { 0, NULL, 0, 0, 0, NULL }
583
};
584
585
static int
586
0
dissect_tcap_T_problem(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
587
0
  offset = dissect_ber_choice(actx, tree, tvb, offset,
588
0
                                 T_problem_choice, hf_index, ett_tcap_T_problem,
589
0
                                 NULL);
590
591
0
  return offset;
592
0
}
593
594
595
static const ber_sequence_t Reject_sequence[] = {
596
  { &hf_tcap_invokeIDRej    , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_tcap_T_invokeIDRej },
597
  { &hf_tcap_problem        , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_tcap_T_problem },
598
  { NULL, 0, 0, 0, NULL }
599
};
600
601
static int
602
0
dissect_tcap_Reject(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
603
0
  offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
604
0
                                   Reject_sequence, hf_index, ett_tcap_Reject);
605
606
0
  return offset;
607
0
}
608
609
610
static const value_string tcap_Component_vals[] = {
611
  {   1, "invoke" },
612
  {   2, "returnResultLast" },
613
  {   3, "returnError" },
614
  {   4, "reject" },
615
  {   7, "returnResultNotLast" },
616
  { 0, NULL }
617
};
618
619
static const ber_choice_t Component_choice[] = {
620
  {   1, &hf_tcap_invoke         , BER_CLASS_CON, 1, BER_FLAGS_IMPLTAG, dissect_tcap_Invoke },
621
  {   2, &hf_tcap_returnResultLast, BER_CLASS_CON, 2, BER_FLAGS_IMPLTAG, dissect_tcap_ReturnResult },
622
  {   3, &hf_tcap_returnError    , BER_CLASS_CON, 3, BER_FLAGS_IMPLTAG, dissect_tcap_ReturnError },
623
  {   4, &hf_tcap_reject         , BER_CLASS_CON, 4, BER_FLAGS_IMPLTAG, dissect_tcap_Reject },
624
  {   7, &hf_tcap_returnResultNotLast, BER_CLASS_CON, 7, BER_FLAGS_IMPLTAG, dissect_tcap_ReturnResult },
625
  { 0, NULL, 0, 0, 0, NULL }
626
};
627
628
static int
629
0
dissect_tcap_Component(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
630
0
  tvbuff_t *next_tvb;
631
0
  int8_t ber_class;
632
0
  bool pc;
633
0
  int tag;
634
0
  uint32_t len, comp_offset;
635
0
  volatile uint32_t _offset;
636
0
  bool ind_field;
637
638
0
  comp_offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag);
639
0
  comp_offset = dissect_ber_length(actx->pinfo, tree, tvb, comp_offset, &len, &ind_field);
640
  /* we can believe the length now */
641
0
  next_tvb = tvb_new_subset_length(tvb, offset, len+comp_offset-offset);
642
643
0
  if (!next_tvb)
644
0
    return comp_offset;
645
0
  if(dissect_tcap_ITU_ComponentPDU(implicit_tag, next_tvb, 0, actx, tcap_top_tree, hf_index)){
646
0
    return comp_offset;
647
0
  }
648
649
0
  _offset = offset;
650
0
  TRY {
651
0
    _offset = dissect_ber_choice(actx, tree, tvb, _offset,
652
0
                                 Component_choice, hf_index, ett_tcap_Component,
653
0
                                 NULL);
654
0
  }
655
0
  CATCH_NONFATAL_ERRORS {
656
0
    show_exception(tvb, actx->pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
657
0
  }
658
0
  ENDTRY;
659
0
  offset = _offset;
660
661
/* return comp_offset+len; or return offset (will be automatically added) */
662
663
664
0
  return offset;
665
0
}
666
667
668
static const ber_sequence_t SEQUENCE_SIZE_1_MAX_OF_Component_sequence_of[1] = {
669
  { &hf_tcap__untag_item    , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_tcap_Component },
670
};
671
672
static int
673
0
dissect_tcap_SEQUENCE_SIZE_1_MAX_OF_Component(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
674
0
  offset = dissect_ber_sequence_of(implicit_tag, actx, tree, tvb, offset,
675
0
                                      SEQUENCE_SIZE_1_MAX_OF_Component_sequence_of, hf_index, ett_tcap_SEQUENCE_SIZE_1_MAX_OF_Component);
676
677
0
  return offset;
678
0
}
679
680
681
682
static int
683
0
dissect_tcap_ComponentPortion(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
684
0
  offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
685
0
                                      hf_index, BER_CLASS_APP, 12, true, dissect_tcap_SEQUENCE_SIZE_1_MAX_OF_Component);
686
687
0
  return offset;
688
0
}
689
690
691
static const ber_sequence_t Unidirectional_sequence[] = {
692
  { &hf_tcap_dialoguePortion, BER_CLASS_APP, 11, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_tcap_DialoguePortion },
693
  { &hf_tcap_components     , BER_CLASS_APP, 12, BER_FLAGS_NOOWNTAG, dissect_tcap_ComponentPortion },
694
  { NULL, 0, 0, 0, NULL }
695
};
696
697
static int
698
0
dissect_tcap_Unidirectional(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
699
0
  offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
700
0
                                   Unidirectional_sequence, hf_index, ett_tcap_Unidirectional);
701
702
0
  return offset;
703
0
}
704
705
706
707
static int
708
0
dissect_tcap_OCTET_STRING_SIZE_1_4(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
709
0
  offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
710
0
                                       NULL);
711
712
0
  return offset;
713
0
}
714
715
716
717
static int
718
0
dissect_tcap_OrigTransactionID(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
719
0
  tvbuff_t *parameter_tvb;
720
0
  uint8_t len, i;
721
0
  proto_tree *subtree;
722
0
  int saved_offset;
723
0
  struct tcap_private_t *p_tcap_private = (struct tcap_private_t*)actx->value_ptr;
724
725
0
  hf_index = hf_tcap_tid;
726
0
  saved_offset = offset;
727
0
  offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
728
0
                                      hf_index, BER_CLASS_APP, 8, true, dissect_tcap_OCTET_STRING_SIZE_1_4);
729
730
0
  proto_item_set_generated(actx->created_item);
731
0
  offset = saved_offset;
732
733
0
  subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_otid, NULL, "Source Transaction ID");
734
0
  offset = dissect_ber_octet_string(implicit_tag, actx, subtree, tvb, offset, hf_tcap_otid,
735
0
                                    &parameter_tvb);
736
737
0
  if (parameter_tvb) {
738
0
    len = tvb_reported_length_remaining(parameter_tvb, 0);
739
0
    switch(len) {
740
0
    case 1:
741
0
      gp_tcapsrt_info->src_tid=tvb_get_uint8(parameter_tvb, 0);
742
0
      break;
743
0
    case 2:
744
0
      gp_tcapsrt_info->src_tid=tvb_get_ntohs(parameter_tvb, 0);
745
0
      break;
746
0
    case 3:
747
0
      gp_tcapsrt_info->src_tid=tvb_get_ntoh24(parameter_tvb, 0);
748
0
      break;
749
0
    case 4:
750
0
      gp_tcapsrt_info->src_tid=tvb_get_ntohl(parameter_tvb, 0);
751
0
      break;
752
0
    default:
753
0
      gp_tcapsrt_info->src_tid=0;
754
0
      break;
755
0
    }
756
0
    if (p_tcap_private)
757
0
      p_tcap_private->src_tid = gp_tcapsrt_info->src_tid;
758
759
0
    if (len) {
760
0
      col_append_str(actx->pinfo->cinfo, COL_INFO, "otid(");
761
0
      for (i = 0; i < len; i++) {
762
0
        col_append_fstr(actx->pinfo->cinfo, COL_INFO, "%02x",tvb_get_uint8(parameter_tvb,i));
763
0
      }
764
0
      col_append_str(actx->pinfo->cinfo, COL_INFO, ") ");
765
0
    }
766
0
  }
767
768
769
0
  return offset;
770
0
}
771
772
773
static const ber_sequence_t Begin_sequence[] = {
774
  { &hf_tcap_otid           , BER_CLASS_APP, 8, BER_FLAGS_NOOWNTAG, dissect_tcap_OrigTransactionID },
775
  { &hf_tcap_dialoguePortion, BER_CLASS_APP, 11, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_tcap_DialoguePortion },
776
  { &hf_tcap_components     , BER_CLASS_APP, 12, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_tcap_ComponentPortion },
777
  { NULL, 0, 0, 0, NULL }
778
};
779
780
static int
781
0
dissect_tcap_Begin(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
782
0
gp_tcapsrt_info->ope=TC_BEGIN;
783
784
/*  Do not change col_add_str() to col_append_str() here: we _want_ this call
785
 *  to overwrite whatever's currently in the INFO column (e.g., "UDT" from
786
 *  the SCCP dissector).
787
 *
788
 *  If there's something there that should not be overwritten, whoever
789
 *  put that info there should call col_set_fence() to protect it.
790
 */
791
0
  col_set_str(actx->pinfo->cinfo, COL_INFO, "Begin ");
792
0
  offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
793
0
                                   Begin_sequence, hf_index, ett_tcap_Begin);
794
795
0
  return offset;
796
0
}
797
798
799
800
static int
801
0
dissect_tcap_DestTransactionID(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
802
0
  tvbuff_t *parameter_tvb;
803
0
  uint8_t len , i;
804
0
  proto_tree *subtree;
805
0
  int saved_offset;
806
0
  struct tcap_private_t *p_tcap_private = (struct tcap_private_t*)actx->value_ptr;
807
808
0
  hf_index = hf_tcap_tid;
809
0
  saved_offset = offset;
810
0
  offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
811
0
                                      hf_index, BER_CLASS_APP, 9, true, dissect_tcap_OCTET_STRING_SIZE_1_4);
812
813
0
  proto_item_set_generated(actx->created_item);
814
0
  offset = saved_offset;
815
816
0
  subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_dtid, NULL, "Destination Transaction ID");
817
0
  offset = dissect_ber_octet_string(implicit_tag, actx, subtree, tvb, offset, hf_tcap_dtid,
818
0
                                    &parameter_tvb);
819
820
0
  if (parameter_tvb) {
821
0
    len = tvb_reported_length_remaining(parameter_tvb, 0);
822
0
    switch(len) {
823
0
    case 1:
824
0
      gp_tcapsrt_info->dst_tid=tvb_get_uint8(parameter_tvb, 0);
825
0
      break;
826
0
    case 2:
827
0
      gp_tcapsrt_info->dst_tid=tvb_get_ntohs(parameter_tvb, 0);
828
0
      break;
829
0
    case 3:
830
0
      gp_tcapsrt_info->dst_tid=tvb_get_ntoh24(parameter_tvb, 0);
831
0
      break;
832
0
    case 4:
833
0
      gp_tcapsrt_info->dst_tid=tvb_get_ntohl(parameter_tvb, 0);
834
0
      break;
835
0
    default:
836
0
      gp_tcapsrt_info->dst_tid=0;
837
0
      break;
838
0
    }
839
0
    if (p_tcap_private)
840
0
      p_tcap_private->dst_tid = gp_tcapsrt_info->dst_tid;
841
842
0
    if (len) {
843
0
      col_append_str(actx->pinfo->cinfo, COL_INFO, "dtid(");
844
0
      for(i = 0; i < len; i++) {
845
0
        col_append_fstr(actx->pinfo->cinfo, COL_INFO, "%02x",tvb_get_uint8(parameter_tvb,i));
846
0
      }
847
0
      col_append_str(actx->pinfo->cinfo, COL_INFO, ") ");
848
0
    }
849
0
  }
850
851
0
  return offset;
852
0
}
853
854
855
static const ber_sequence_t End_sequence[] = {
856
  { &hf_tcap_dtid           , BER_CLASS_APP, 9, BER_FLAGS_NOOWNTAG, dissect_tcap_DestTransactionID },
857
  { &hf_tcap_dialoguePortion, BER_CLASS_APP, 11, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_tcap_DialoguePortion },
858
  { &hf_tcap_components     , BER_CLASS_APP, 12, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_tcap_ComponentPortion },
859
  { NULL, 0, 0, 0, NULL }
860
};
861
862
static int
863
0
dissect_tcap_End(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
864
0
gp_tcapsrt_info->ope=TC_END;
865
866
0
  col_set_str(actx->pinfo->cinfo, COL_INFO, "End ");
867
0
  offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
868
0
                                   End_sequence, hf_index, ett_tcap_End);
869
870
0
  return offset;
871
0
}
872
873
874
static const ber_sequence_t Continue_sequence[] = {
875
  { &hf_tcap_otid           , BER_CLASS_APP, 8, BER_FLAGS_NOOWNTAG, dissect_tcap_OrigTransactionID },
876
  { &hf_tcap_dtid           , BER_CLASS_APP, 9, BER_FLAGS_NOOWNTAG, dissect_tcap_DestTransactionID },
877
  { &hf_tcap_dialoguePortion, BER_CLASS_APP, 11, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_tcap_DialoguePortion },
878
  { &hf_tcap_components     , BER_CLASS_APP, 12, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_tcap_ComponentPortion },
879
  { NULL, 0, 0, 0, NULL }
880
};
881
882
static int
883
0
dissect_tcap_Continue(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
884
0
gp_tcapsrt_info->ope=TC_CONT;
885
886
0
  col_set_str(actx->pinfo->cinfo, COL_INFO, "Continue ");
887
0
  offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
888
0
                                   Continue_sequence, hf_index, ett_tcap_Continue);
889
890
0
  return offset;
891
0
}
892
893
894
static const value_string tcap_P_AbortCause_U_vals[] = {
895
  {   0, "unrecognizedMessageType" },
896
  {   1, "unrecognizedTransactionID" },
897
  {   2, "badlyFormattedTransactionPortion" },
898
  {   3, "incorrectTransactionPortion" },
899
  {   4, "resourceLimitation" },
900
  { 0, NULL }
901
};
902
903
904
static int
905
0
dissect_tcap_P_AbortCause_U(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
906
0
  offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
907
0
                                                NULL);
908
909
0
  return offset;
910
0
}
911
912
913
914
static int
915
0
dissect_tcap_P_AbortCause(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
916
0
  offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
917
0
                                      hf_index, BER_CLASS_APP, 10, true, dissect_tcap_P_AbortCause_U);
918
919
0
  return offset;
920
0
}
921
922
923
static const value_string tcap_Reason_vals[] = {
924
  {  10, "p-abortCause" },
925
  {  11, "u-abortCause" },
926
  { 0, NULL }
927
};
928
929
static const ber_choice_t Reason_choice[] = {
930
  {  10, &hf_tcap_p_abortCause   , BER_CLASS_APP, 10, BER_FLAGS_NOOWNTAG, dissect_tcap_P_AbortCause },
931
  {  11, &hf_tcap_u_abortCause   , BER_CLASS_APP, 11, BER_FLAGS_NOOWNTAG, dissect_tcap_DialoguePortion },
932
  { 0, NULL, 0, 0, 0, NULL }
933
};
934
935
static int
936
0
dissect_tcap_Reason(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
937
0
  offset = dissect_ber_choice(actx, tree, tvb, offset,
938
0
                                 Reason_choice, hf_index, ett_tcap_Reason,
939
0
                                 NULL);
940
941
0
  return offset;
942
0
}
943
944
945
static const ber_sequence_t Abort_sequence[] = {
946
  { &hf_tcap_dtid           , BER_CLASS_APP, 9, BER_FLAGS_NOOWNTAG, dissect_tcap_DestTransactionID },
947
  { &hf_tcap_reason         , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_tcap_Reason },
948
  { NULL, 0, 0, 0, NULL }
949
};
950
951
static int
952
0
dissect_tcap_Abort(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
953
0
gp_tcapsrt_info->ope=TC_ABORT;
954
955
0
  col_set_str(actx->pinfo->cinfo, COL_INFO, "Abort ");
956
0
  offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
957
0
                                   Abort_sequence, hf_index, ett_tcap_Abort);
958
959
0
  return offset;
960
0
}
961
962
963
static const ber_choice_t TCMessage_choice[] = {
964
  {   1, &hf_tcap_unidirectional , BER_CLASS_APP, 1, BER_FLAGS_IMPLTAG, dissect_tcap_Unidirectional },
965
  {   2, &hf_tcap_begin          , BER_CLASS_APP, 2, BER_FLAGS_IMPLTAG, dissect_tcap_Begin },
966
  {   4, &hf_tcap_end            , BER_CLASS_APP, 4, BER_FLAGS_IMPLTAG, dissect_tcap_End },
967
  {   5, &hf_tcap_continue       , BER_CLASS_APP, 5, BER_FLAGS_IMPLTAG, dissect_tcap_Continue },
968
  {   7, &hf_tcap_abort          , BER_CLASS_APP, 7, BER_FLAGS_IMPLTAG, dissect_tcap_Abort },
969
  { 0, NULL, 0, 0, 0, NULL }
970
};
971
972
static int
973
27
dissect_tcap_TCMessage(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
974
27
  offset = dissect_ber_choice(actx, tree, tvb, offset,
975
27
                                 TCMessage_choice, hf_index, ett_tcap_TCMessage,
976
27
                                 NULL);
977
978
27
  return offset;
979
27
}
980
981
982
static int * const AUDT_protocol_version_bits[] = {
983
  &hf_tcap_AUDT_protocol_version_version1,
984
  NULL
985
};
986
987
static int
988
0
dissect_tcap_AUDT_protocol_version(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
989
0
  offset = dissect_ber_bitstring(implicit_tag, actx, tree, tvb, offset,
990
0
                                    AUDT_protocol_version_bits, 1, hf_index, ett_tcap_AUDT_protocol_version,
991
0
                                    NULL);
992
993
0
  return offset;
994
0
}
995
996
997
998
static int
999
0
dissect_tcap_AUDT_application_context_name(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1000
0
  struct tcap_private_t *p_tcap_private = (struct tcap_private_t*)actx->value_ptr;
1001
0
  offset = dissect_ber_object_identifier_str(implicit_tag, actx, tree, tvb, offset, hf_index, &cur_oid);
1002
1003
0
  if (p_tcap_private) {
1004
0
    p_tcap_private->oid= (const void*) cur_oid;
1005
0
    p_tcap_private->acv=true;
1006
0
  }
1007
1008
0
  return offset;
1009
0
}
1010
1011
1012
1013
static int
1014
0
dissect_tcap_EXTERNAL(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1015
0
  offset = dissect_ber_external_type(implicit_tag, tree, tvb, offset, actx, hf_index, NULL);
1016
1017
0
  return offset;
1018
0
}
1019
1020
1021
static const ber_sequence_t AUDT_user_information_sequence_of[1] = {
1022
  { &hf_tcap_audt_user_information_item, BER_CLASS_UNI, BER_UNI_TAG_EXTERNAL, BER_FLAGS_NOOWNTAG, dissect_tcap_EXTERNAL },
1023
};
1024
1025
static int
1026
0
dissect_tcap_AUDT_user_information(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1027
0
  offset = dissect_ber_sequence_of(implicit_tag, actx, tree, tvb, offset,
1028
0
                                      AUDT_user_information_sequence_of, hf_index, ett_tcap_AUDT_user_information);
1029
1030
0
  return offset;
1031
0
}
1032
1033
1034
static const ber_sequence_t AUDT_apdu_U_sequence[] = {
1035
  { &hf_tcap_audt_protocol_version, BER_CLASS_CON, 0, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_tcap_AUDT_protocol_version },
1036
  { &hf_tcap_audt_application_context_name, BER_CLASS_CON, 1, 0, dissect_tcap_AUDT_application_context_name },
1037
  { &hf_tcap_audt_user_information, BER_CLASS_CON, 30, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_tcap_AUDT_user_information },
1038
  { NULL, 0, 0, 0, NULL }
1039
};
1040
1041
static int
1042
0
dissect_tcap_AUDT_apdu_U(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1043
0
  offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
1044
0
                                   AUDT_apdu_U_sequence, hf_index, ett_tcap_AUDT_apdu_U);
1045
1046
0
  return offset;
1047
0
}
1048
1049
1050
1051
static int
1052
0
dissect_tcap_AUDT_apdu(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1053
0
  offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
1054
0
                                      hf_index, BER_CLASS_APP, 0, true, dissect_tcap_AUDT_apdu_U);
1055
1056
0
  return offset;
1057
0
}
1058
1059
1060
const value_string tcap_UniDialoguePDU_vals[] = {
1061
  {   0, "unidialoguePDU" },
1062
  { 0, NULL }
1063
};
1064
1065
static const ber_choice_t UniDialoguePDU_choice[] = {
1066
  {   0, &hf_tcap_unidialoguePDU , BER_CLASS_APP, 0, BER_FLAGS_NOOWNTAG, dissect_tcap_AUDT_apdu },
1067
  { 0, NULL, 0, 0, 0, NULL }
1068
};
1069
1070
int
1071
0
dissect_tcap_UniDialoguePDU(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1072
0
  offset = dissect_ber_choice(actx, tree, tvb, offset,
1073
0
                                 UniDialoguePDU_choice, hf_index, ett_tcap_UniDialoguePDU,
1074
0
                                 NULL);
1075
1076
0
  return offset;
1077
0
}
1078
1079
1080
static int * const AARQ_protocol_version_bits[] = {
1081
  &hf_tcap_AARQ_protocol_version_version1,
1082
  NULL
1083
};
1084
1085
static int
1086
0
dissect_tcap_AARQ_protocol_version(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1087
0
  offset = dissect_ber_bitstring(implicit_tag, actx, tree, tvb, offset,
1088
0
                                    AARQ_protocol_version_bits, 1, hf_index, ett_tcap_AARQ_protocol_version,
1089
0
                                    NULL);
1090
1091
0
  return offset;
1092
0
}
1093
1094
1095
1096
static int
1097
0
dissect_tcap_AARQ_application_context_name(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1098
0
  struct tcap_private_t *p_tcap_private = (struct tcap_private_t*)actx->value_ptr;
1099
0
  offset = dissect_ber_object_identifier_str(implicit_tag, actx, tree, tvb, offset, hf_index, &cur_oid);
1100
1101
0
  if (p_tcap_private) {
1102
0
    p_tcap_private->oid= (const void*) cur_oid;
1103
0
    p_tcap_private->acv=true;
1104
0
  }
1105
1106
0
  return offset;
1107
0
}
1108
1109
1110
static const ber_sequence_t AARQ_user_information_sequence_of[1] = {
1111
  { &hf_tcap_aarq_user_information_item, BER_CLASS_UNI, BER_UNI_TAG_EXTERNAL, BER_FLAGS_NOOWNTAG, dissect_tcap_EXTERNAL },
1112
};
1113
1114
static int
1115
0
dissect_tcap_AARQ_user_information(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1116
0
  offset = dissect_ber_sequence_of(implicit_tag, actx, tree, tvb, offset,
1117
0
                                      AARQ_user_information_sequence_of, hf_index, ett_tcap_AARQ_user_information);
1118
1119
0
  return offset;
1120
0
}
1121
1122
1123
static const ber_sequence_t AARQ_apdu_U_sequence[] = {
1124
  { &hf_tcap_aarq_protocol_version, BER_CLASS_CON, 0, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_tcap_AARQ_protocol_version },
1125
  { &hf_tcap_aarq_application_context_name, BER_CLASS_CON, 1, 0, dissect_tcap_AARQ_application_context_name },
1126
  { &hf_tcap_aarq_user_information, BER_CLASS_CON, 30, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_tcap_AARQ_user_information },
1127
  { NULL, 0, 0, 0, NULL }
1128
};
1129
1130
static int
1131
0
dissect_tcap_AARQ_apdu_U(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1132
0
  offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
1133
0
                                   AARQ_apdu_U_sequence, hf_index, ett_tcap_AARQ_apdu_U);
1134
1135
0
  return offset;
1136
0
}
1137
1138
1139
1140
static int
1141
0
dissect_tcap_AARQ_apdu(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1142
0
  offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
1143
0
                                      hf_index, BER_CLASS_APP, 0, true, dissect_tcap_AARQ_apdu_U);
1144
1145
0
  return offset;
1146
0
}
1147
1148
1149
static int * const AARE_protocol_version_bits[] = {
1150
  &hf_tcap_AARE_protocol_version_version1,
1151
  NULL
1152
};
1153
1154
static int
1155
0
dissect_tcap_AARE_protocol_version(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1156
0
  offset = dissect_ber_bitstring(implicit_tag, actx, tree, tvb, offset,
1157
0
                                    AARE_protocol_version_bits, 1, hf_index, ett_tcap_AARE_protocol_version,
1158
0
                                    NULL);
1159
1160
0
  return offset;
1161
0
}
1162
1163
1164
1165
static int
1166
0
dissect_tcap_AARE_application_context_name(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1167
0
  struct tcap_private_t *p_tcap_private = (struct tcap_private_t*)actx->value_ptr;
1168
0
  offset = dissect_ber_object_identifier_str(implicit_tag, actx, tree, tvb, offset, hf_index, &cur_oid);
1169
1170
0
  if (p_tcap_private) {
1171
0
    p_tcap_private->oid= (const void*) cur_oid;
1172
0
    p_tcap_private->acv=true;
1173
0
  }
1174
1175
0
  return offset;
1176
0
}
1177
1178
1179
static const value_string tcap_Associate_result_vals[] = {
1180
  {   0, "accepted" },
1181
  {   1, "reject-permanent" },
1182
  { 0, NULL }
1183
};
1184
1185
1186
static int
1187
0
dissect_tcap_Associate_result(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1188
0
  offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
1189
0
                                                NULL);
1190
1191
0
  return offset;
1192
0
}
1193
1194
1195
static const value_string tcap_T_dialogue_service_user_vals[] = {
1196
  {   0, "null" },
1197
  {   1, "no-reason-given" },
1198
  {   2, "application-context-name-not-supported" },
1199
  { 0, NULL }
1200
};
1201
1202
1203
static int
1204
0
dissect_tcap_T_dialogue_service_user(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1205
0
  offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
1206
0
                                                NULL);
1207
1208
0
  return offset;
1209
0
}
1210
1211
1212
static const value_string tcap_T_dialogue_service_provider_vals[] = {
1213
  {   0, "null" },
1214
  {   1, "no-reason-given" },
1215
  {   2, "no-common-dialogue-portion" },
1216
  { 0, NULL }
1217
};
1218
1219
1220
static int
1221
0
dissect_tcap_T_dialogue_service_provider(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1222
0
  offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
1223
0
                                                NULL);
1224
1225
0
  return offset;
1226
0
}
1227
1228
1229
static const value_string tcap_Associate_source_diagnostic_vals[] = {
1230
  {   1, "dialogue-service-user" },
1231
  {   2, "dialogue-service-provider" },
1232
  { 0, NULL }
1233
};
1234
1235
static const ber_choice_t Associate_source_diagnostic_choice[] = {
1236
  {   1, &hf_tcap_dialogue_service_user, BER_CLASS_CON, 1, 0, dissect_tcap_T_dialogue_service_user },
1237
  {   2, &hf_tcap_dialogue_service_provider, BER_CLASS_CON, 2, 0, dissect_tcap_T_dialogue_service_provider },
1238
  { 0, NULL, 0, 0, 0, NULL }
1239
};
1240
1241
static int
1242
0
dissect_tcap_Associate_source_diagnostic(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1243
0
  offset = dissect_ber_choice(actx, tree, tvb, offset,
1244
0
                                 Associate_source_diagnostic_choice, hf_index, ett_tcap_Associate_source_diagnostic,
1245
0
                                 NULL);
1246
1247
0
  return offset;
1248
0
}
1249
1250
1251
static const ber_sequence_t AARE_user_information_sequence_of[1] = {
1252
  { &hf_tcap_aare_user_information_item, BER_CLASS_UNI, BER_UNI_TAG_EXTERNAL, BER_FLAGS_NOOWNTAG, dissect_tcap_EXTERNAL },
1253
};
1254
1255
static int
1256
0
dissect_tcap_AARE_user_information(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1257
0
  offset = dissect_ber_sequence_of(implicit_tag, actx, tree, tvb, offset,
1258
0
                                      AARE_user_information_sequence_of, hf_index, ett_tcap_AARE_user_information);
1259
1260
0
  return offset;
1261
0
}
1262
1263
1264
static const ber_sequence_t AARE_apdu_U_sequence[] = {
1265
  { &hf_tcap_aare_protocol_version, BER_CLASS_CON, 0, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_tcap_AARE_protocol_version },
1266
  { &hf_tcap_aare_application_context_name, BER_CLASS_CON, 1, 0, dissect_tcap_AARE_application_context_name },
1267
  { &hf_tcap_result         , BER_CLASS_CON, 2, 0, dissect_tcap_Associate_result },
1268
  { &hf_tcap_result_source_diagnostic, BER_CLASS_CON, 3, BER_FLAGS_NOTCHKTAG, dissect_tcap_Associate_source_diagnostic },
1269
  { &hf_tcap_aare_user_information, BER_CLASS_CON, 30, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_tcap_AARE_user_information },
1270
  { NULL, 0, 0, 0, NULL }
1271
};
1272
1273
static int
1274
0
dissect_tcap_AARE_apdu_U(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1275
0
  offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
1276
0
                                   AARE_apdu_U_sequence, hf_index, ett_tcap_AARE_apdu_U);
1277
1278
0
  return offset;
1279
0
}
1280
1281
1282
1283
static int
1284
0
dissect_tcap_AARE_apdu(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1285
0
  offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
1286
0
                                      hf_index, BER_CLASS_APP, 1, true, dissect_tcap_AARE_apdu_U);
1287
1288
0
  return offset;
1289
0
}
1290
1291
1292
static const value_string tcap_ABRT_source_vals[] = {
1293
  {   0, "dialogue-service-user" },
1294
  {   1, "dialogue-service-provider" },
1295
  { 0, NULL }
1296
};
1297
1298
1299
static int
1300
0
dissect_tcap_ABRT_source(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1301
0
  offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
1302
0
                                                NULL);
1303
1304
0
  return offset;
1305
0
}
1306
1307
1308
static const ber_sequence_t ABRT_user_information_sequence_of[1] = {
1309
  { &hf_tcap_abrt_user_information_item, BER_CLASS_UNI, BER_UNI_TAG_EXTERNAL, BER_FLAGS_NOOWNTAG, dissect_tcap_EXTERNAL },
1310
};
1311
1312
static int
1313
0
dissect_tcap_ABRT_user_information(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1314
0
  offset = dissect_ber_sequence_of(implicit_tag, actx, tree, tvb, offset,
1315
0
                                      ABRT_user_information_sequence_of, hf_index, ett_tcap_ABRT_user_information);
1316
1317
0
  return offset;
1318
0
}
1319
1320
1321
static const ber_sequence_t ABRT_apdu_U_sequence[] = {
1322
  { &hf_tcap_abort_source   , BER_CLASS_CON, 0, BER_FLAGS_IMPLTAG, dissect_tcap_ABRT_source },
1323
  { &hf_tcap_abrt_user_information, BER_CLASS_CON, 30, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_tcap_ABRT_user_information },
1324
  { NULL, 0, 0, 0, NULL }
1325
};
1326
1327
static int
1328
0
dissect_tcap_ABRT_apdu_U(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1329
0
  offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
1330
0
                                   ABRT_apdu_U_sequence, hf_index, ett_tcap_ABRT_apdu_U);
1331
1332
0
  return offset;
1333
0
}
1334
1335
1336
1337
static int
1338
0
dissect_tcap_ABRT_apdu(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1339
0
  offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
1340
0
                                      hf_index, BER_CLASS_APP, 4, true, dissect_tcap_ABRT_apdu_U);
1341
1342
0
  return offset;
1343
0
}
1344
1345
1346
const value_string tcap_DialoguePDU_vals[] = {
1347
  {   0, "dialogueRequest" },
1348
  {   1, "dialogueResponse" },
1349
  {   4, "dialogueAbort" },
1350
  { 0, NULL }
1351
};
1352
1353
static const ber_choice_t DialoguePDU_choice[] = {
1354
  {   0, &hf_tcap_dialogueRequest, BER_CLASS_APP, 0, BER_FLAGS_NOOWNTAG, dissect_tcap_AARQ_apdu },
1355
  {   1, &hf_tcap_dialogueResponse, BER_CLASS_APP, 1, BER_FLAGS_NOOWNTAG, dissect_tcap_AARE_apdu },
1356
  {   4, &hf_tcap_dialogueAbort  , BER_CLASS_APP, 4, BER_FLAGS_NOOWNTAG, dissect_tcap_ABRT_apdu },
1357
  { 0, NULL, 0, 0, 0, NULL }
1358
};
1359
1360
int
1361
0
dissect_tcap_DialoguePDU(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1362
0
  offset = dissect_ber_choice(actx, tree, tvb, offset,
1363
0
                                 DialoguePDU_choice, hf_index, ett_tcap_DialoguePDU,
1364
0
                                 NULL);
1365
1366
0
  return offset;
1367
0
}
1368
1369
/*--- PDUs ---*/
1370
1371
0
static int dissect_UniDialoguePDU_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_) {
1372
0
  int offset = 0;
1373
0
  asn1_ctx_t asn1_ctx;
1374
0
  asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, true, pinfo);
1375
0
  offset = dissect_tcap_UniDialoguePDU(false, tvb, offset, &asn1_ctx, tree, hf_tcap_UniDialoguePDU_PDU);
1376
0
  return offset;
1377
0
}
1378
0
static int dissect_DialoguePDU_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_) {
1379
0
  int offset = 0;
1380
0
  asn1_ctx_t asn1_ctx;
1381
0
  asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, true, pinfo);
1382
0
  offset = dissect_tcap_DialoguePDU(false, tvb, offset, &asn1_ctx, tree, hf_tcap_DialoguePDU_PDU);
1383
0
  return offset;
1384
0
}
1385
1386
1387
/*
1388
 * DEBUG functions
1389
 */
1390
#undef DEBUG_TCAPSRT
1391
/* #define DEBUG_TCAPSRT */
1392
1393
#ifdef DEBUG_TCAPSRT
1394
#include <stdio.h>
1395
#include <stdarg.h>
1396
static unsigned debug_level = 99;
1397
1398
static void
1399
dbg(unsigned level, const char* fmt, ...)
1400
{
1401
  va_list ap;
1402
1403
  if (level > debug_level) return;
1404
  va_start(ap,fmt);
1405
  vfprintf(stderr, fmt, ap);
1406
  va_end(ap);
1407
}
1408
#endif
1409
1410
static int
1411
tcaphash_context_equal(const void *k1, const void *k2)
1412
0
{
1413
0
  const struct tcaphash_context_key_t *key1 = (const struct tcaphash_context_key_t *) k1;
1414
0
  const struct tcaphash_context_key_t *key2 = (const struct tcaphash_context_key_t *) k2;
1415
1416
0
  return (key1->session_id == key2->session_id);
1417
0
}
1418
1419
/* calculate a hash key */
1420
static unsigned
1421
tcaphash_context_calchash(const void *k)
1422
0
{
1423
0
  const struct tcaphash_context_key_t *key = (const struct tcaphash_context_key_t *) k;
1424
0
  return key->session_id;
1425
0
}
1426
1427
1428
static int
1429
tcaphash_begin_equal(const void *k1, const void *k2)
1430
0
{
1431
0
  const struct tcaphash_begin_info_key_t *key1 = (const struct tcaphash_begin_info_key_t *) k1;
1432
0
  const struct tcaphash_begin_info_key_t *key2 = (const struct tcaphash_begin_info_key_t *) k2;
1433
1434
0
  if (key1->hashKey == key2->hashKey) {
1435
0
    if ( (key1->pc_hash == key2->pc_hash) && (key1->tid == key2->tid) )
1436
0
      return true;
1437
0
  }
1438
0
  return false;
1439
0
}
1440
1441
/* calculate a hash key */
1442
static unsigned
1443
tcaphash_begin_calchash(const void *k)
1444
0
{
1445
0
  const struct tcaphash_begin_info_key_t *key = (const struct tcaphash_begin_info_key_t *) k;
1446
0
  unsigned hashkey;
1447
  /* hashkey = key->opc_hash<<16 + key->dpc_hash<<8 + key->src_tid; */
1448
0
  hashkey = key->tid;
1449
0
  return hashkey;
1450
0
}
1451
1452
static int
1453
tcaphash_cont_equal(const void *k1, const void *k2)
1454
0
{
1455
0
  const struct tcaphash_cont_info_key_t *key1 = (const struct tcaphash_cont_info_key_t *) k1;
1456
0
  const struct tcaphash_cont_info_key_t *key2 = (const struct tcaphash_cont_info_key_t *) k2;
1457
1458
0
  if (key1->hashKey == key2->hashKey) {
1459
1460
0
    if ( (key1->opc_hash == key2->opc_hash) &&
1461
0
         (key1->dpc_hash == key2->dpc_hash) &&
1462
0
         (key1->src_tid == key2->src_tid) &&
1463
0
         (key1->dst_tid == key2->dst_tid) ) {
1464
0
      return true;
1465
0
    }
1466
0
    else if ( (key1->opc_hash == key2->dpc_hash) &&
1467
0
              (key1->dpc_hash == key2->opc_hash) &&
1468
0
              (key1->src_tid == key2->dst_tid) &&
1469
0
              (key1->dst_tid == key2->src_tid) ) {
1470
0
      return true;
1471
0
    }
1472
0
  }
1473
0
  return false;
1474
0
}
1475
1476
/* calculate a hash key */
1477
static unsigned
1478
tcaphash_cont_calchash(const void *k)
1479
0
{
1480
0
  const struct tcaphash_cont_info_key_t *key = (const struct tcaphash_cont_info_key_t *) k;
1481
0
  unsigned hashkey;
1482
0
  hashkey = key->src_tid + key->dst_tid;
1483
0
  return hashkey;
1484
0
}
1485
1486
1487
static int
1488
tcaphash_end_equal(const void *k1, const void *k2)
1489
0
{
1490
0
  const struct tcaphash_end_info_key_t *key1 = (const struct tcaphash_end_info_key_t *) k1;
1491
0
  const struct tcaphash_end_info_key_t *key2 = (const struct tcaphash_end_info_key_t *) k2;
1492
1493
0
  if (key1->hashKey == key2->hashKey) {
1494
0
    if ( (key1->opc_hash == key2->opc_hash) &&
1495
0
         (key1->dpc_hash == key2->dpc_hash) &&
1496
0
         (key1->tid == key2->tid) )
1497
0
      return true;
1498
0
  }
1499
0
  return false;
1500
0
}
1501
1502
/* calculate a hash key */
1503
static unsigned
1504
tcaphash_end_calchash(const void *k)
1505
0
{
1506
0
  const struct tcaphash_end_info_key_t *key = (const struct tcaphash_end_info_key_t *) k;
1507
0
  unsigned hashkey;
1508
0
  hashkey = key->tid;
1509
0
  return hashkey;
1510
0
}
1511
1512
static int
1513
tcaphash_ansi_equal(const void *k1, const void *k2)
1514
0
{
1515
0
  const struct tcaphash_ansi_info_key_t *key1 = (const struct tcaphash_ansi_info_key_t *) k1;
1516
0
  const struct tcaphash_ansi_info_key_t *key2 = (const struct tcaphash_ansi_info_key_t *) k2;
1517
1518
0
  if (key1->hashKey == key2->hashKey) {
1519
1520
0
    if ( ( (key1->opc_hash == key2->opc_hash) &&
1521
0
           (key1->dpc_hash == key2->dpc_hash) &&
1522
0
           (key1->tid == key2->tid) )
1523
0
         ||
1524
0
         ( (key1->opc_hash == key2->dpc_hash) &&
1525
0
           (key1->dpc_hash == key2->opc_hash) &&
1526
0
           (key1->tid == key2->tid) )
1527
0
         )
1528
0
      return true;
1529
0
  }
1530
0
  return false;
1531
0
}
1532
1533
/* calculate a hash key */
1534
static unsigned
1535
tcaphash_ansi_calchash(const void *k)
1536
0
{
1537
0
  const struct tcaphash_ansi_info_key_t *key = (const struct tcaphash_ansi_info_key_t *) k;
1538
0
  unsigned hashkey;
1539
  /* hashkey = key->opc_hash<<16 + key->dpc_hash<<8 + key->src_tid; */
1540
0
  hashkey = key->tid;
1541
0
  return hashkey;
1542
0
}
1543
1544
/*
1545
 * Update a record with the data of the Request
1546
 */
1547
static void
1548
update_tcaphash_begincall(struct tcaphash_begincall_t *p_tcaphash_begincall,
1549
                          packet_info *pinfo)
1550
0
{
1551
0
  p_tcaphash_begincall->context->first_frame = pinfo->num;
1552
0
  p_tcaphash_begincall->context->last_frame = 0;
1553
0
  p_tcaphash_begincall->context->responded = false;
1554
0
  p_tcaphash_begincall->context->begin_time = pinfo->abs_ts;
1555
0
}
1556
1557
/*
1558
 * Append a new dialogue, using the same Key, to the chained list
1559
 * The time is stored too
1560
 */
1561
static struct tcaphash_begincall_t *
1562
append_tcaphash_begincall(struct tcaphash_begincall_t *prev_begincall,
1563
                          struct tcaphash_context_t *p_tcaphash_context,
1564
                          packet_info *pinfo)
1565
0
{
1566
0
  struct tcaphash_begincall_t *p_new_tcaphash_begincall = NULL;
1567
1568
  /* Append the transaction to the list, when the same key is found
1569
     This should append when the tcap-transaction Id is reused  */
1570
1571
0
  p_new_tcaphash_begincall = wmem_new0(wmem_file_scope(), struct tcaphash_begincall_t);
1572
0
  p_new_tcaphash_begincall->context=p_tcaphash_context;
1573
0
  p_tcaphash_context->begincall=p_new_tcaphash_begincall;
1574
0
  p_new_tcaphash_begincall->beginkey=prev_begincall->beginkey;
1575
0
  p_new_tcaphash_begincall->context->first_frame = pinfo->num;
1576
0
  p_new_tcaphash_begincall->next_begincall=NULL;
1577
0
  p_new_tcaphash_begincall->previous_begincall=prev_begincall;
1578
0
  p_new_tcaphash_begincall->father=false;
1579
1580
#ifdef DEBUG_TCAPSRT
1581
  dbg(10,"+B%d ", p_new_tcaphash_begincall->context->session_id);
1582
#endif
1583
  /* Insert in the chained list */
1584
0
  prev_begincall->next_begincall = p_new_tcaphash_begincall;
1585
0
  if (prev_begincall->context->last_frame == 0) {
1586
#ifdef DEBUG_TCAPSRT
1587
    dbg(10,"last ");
1588
#endif
1589
0
    prev_begincall->context->last_frame = pinfo->num-1;
1590
0
  }
1591
0
  return p_new_tcaphash_begincall;
1592
0
}
1593
1594
/*
1595
 * Update a record with the data of the Request
1596
 */
1597
static void
1598
update_tcaphash_ansicall(struct tcaphash_ansicall_t *p_tcaphash_ansicall,
1599
                          packet_info *pinfo)
1600
0
{
1601
0
  p_tcaphash_ansicall->context->first_frame = pinfo->num;
1602
0
  p_tcaphash_ansicall->context->last_frame = 0;
1603
0
  p_tcaphash_ansicall->context->responded = false;
1604
0
  p_tcaphash_ansicall->context->begin_time = pinfo->abs_ts;
1605
0
}
1606
1607
/*
1608
 * Append a new dialogue, using the same Key, to the chained list
1609
 * The time is stored too
1610
 */
1611
static struct tcaphash_ansicall_t *
1612
append_tcaphash_ansicall(struct tcaphash_ansicall_t *prev_ansicall,
1613
                          struct tcaphash_context_t *p_tcaphash_context,
1614
                          packet_info *pinfo)
1615
0
{
1616
0
  struct tcaphash_ansicall_t *p_new_tcaphash_ansicall = NULL;
1617
1618
  /* Append the transaction to the list, when the same key is found
1619
     This should append when the tcap-transaction Id is reused  */
1620
1621
0
  p_new_tcaphash_ansicall = wmem_new0(wmem_file_scope(), struct tcaphash_ansicall_t);
1622
0
  p_new_tcaphash_ansicall->context=p_tcaphash_context;
1623
0
  p_tcaphash_context->ansicall=p_new_tcaphash_ansicall;
1624
0
  p_new_tcaphash_ansicall->ansikey=prev_ansicall->ansikey;
1625
0
  p_new_tcaphash_ansicall->context->first_frame = pinfo->num;
1626
0
  p_new_tcaphash_ansicall->next_ansicall=NULL;
1627
0
  p_new_tcaphash_ansicall->previous_ansicall=prev_ansicall;
1628
0
  p_new_tcaphash_ansicall->father=false;
1629
1630
#ifdef DEBUG_TCAPSRT
1631
  dbg(10,"+A%d ", p_new_tcaphash_ansicall->context->session_id);
1632
#endif
1633
  /* Insert in the chained list */
1634
0
  prev_ansicall->next_ansicall = p_new_tcaphash_ansicall;
1635
0
  if (prev_ansicall->context->last_frame == 0) {
1636
#ifdef DEBUG_TCAPSRT
1637
    dbg(10,"last ");
1638
#endif
1639
0
    prev_ansicall->context->last_frame = pinfo->num-1;
1640
0
  }
1641
0
  return p_new_tcaphash_ansicall;
1642
0
}
1643
1644
1645
static struct tcaphash_contcall_t *
1646
append_tcaphash_contcall(struct tcaphash_contcall_t *prev_contcall,
1647
                         struct tcaphash_context_t *p_tcaphash_context)
1648
0
{
1649
0
  struct tcaphash_contcall_t *p_new_tcaphash_contcall = NULL;
1650
1651
  /* Append the transaction to the list, when the same key is found
1652
     This should append when the tcap-transaction Id is reused  */
1653
1654
0
  p_new_tcaphash_contcall = wmem_new0(wmem_file_scope(), struct tcaphash_contcall_t);
1655
0
  p_new_tcaphash_contcall->context=p_tcaphash_context;
1656
0
  p_tcaphash_context->contcall=p_new_tcaphash_contcall;
1657
0
  p_new_tcaphash_contcall->contkey=prev_contcall->contkey;
1658
0
  p_new_tcaphash_contcall->next_contcall=NULL;
1659
0
  p_new_tcaphash_contcall->previous_contcall=prev_contcall;
1660
0
  p_new_tcaphash_contcall->father=false;
1661
1662
#ifdef DEBUG_TCAPSRT
1663
  dbg(10,"+C%d ", p_new_tcaphash_contcall->context->session_id);
1664
#endif
1665
  /* Insert in the chained list */
1666
0
  prev_contcall->next_contcall = p_new_tcaphash_contcall;
1667
0
  return p_new_tcaphash_contcall;
1668
0
}
1669
1670
1671
static struct tcaphash_endcall_t *
1672
append_tcaphash_endcall(struct tcaphash_endcall_t *prev_endcall,
1673
                        struct tcaphash_context_t *p_tcaphash_context)
1674
0
{
1675
0
  struct tcaphash_endcall_t *p_new_tcaphash_endcall = NULL;
1676
1677
  /* Append the transaction to the list, when the same key is found
1678
     This should append when the tcap-transaction Id is reused  */
1679
1680
0
  p_new_tcaphash_endcall = wmem_new0(wmem_file_scope(), struct tcaphash_endcall_t);
1681
0
  p_new_tcaphash_endcall->context=p_tcaphash_context;
1682
0
  p_tcaphash_context->endcall=p_new_tcaphash_endcall;
1683
0
  p_new_tcaphash_endcall->endkey=prev_endcall->endkey;
1684
0
  p_new_tcaphash_endcall->next_endcall=NULL;
1685
0
  p_new_tcaphash_endcall->previous_endcall=prev_endcall;
1686
0
  p_new_tcaphash_endcall->father=false;
1687
1688
#ifdef DEBUG_TCAPSRT
1689
  dbg(10,"+E%d ", p_new_tcaphash_endcall->context->session_id);
1690
#endif
1691
  /* Insert in the chained list */
1692
0
  prev_endcall->next_endcall = p_new_tcaphash_endcall;
1693
0
  return p_new_tcaphash_endcall;
1694
0
}
1695
1696
1697
/*
1698
 * Find the dialog by Key and Time
1699
 */
1700
static struct tcaphash_begincall_t *
1701
find_tcaphash_begin(struct tcaphash_begin_info_key_t *p_tcaphash_begin_key,
1702
                    packet_info *pinfo, bool isBegin)
1703
0
{
1704
0
  struct tcaphash_begincall_t *p_tcaphash_begincall = NULL;
1705
0
  p_tcaphash_begincall = (struct tcaphash_begincall_t *)wmem_map_lookup(tcaphash_begin, p_tcaphash_begin_key);
1706
1707
0
  if(p_tcaphash_begincall) {
1708
0
    do {
1709
0
      if ( p_tcaphash_begincall->context ) {
1710
0
        if ( ( isBegin &&
1711
0
               pinfo->num == p_tcaphash_begincall->context->first_frame )
1712
0
             ||
1713
0
             ( !isBegin &&
1714
0
               pinfo->num >= p_tcaphash_begincall->context->first_frame &&
1715
0
               ( p_tcaphash_begincall->context->last_frame?pinfo->num <= p_tcaphash_begincall->context->last_frame:1 )
1716
0
               )
1717
0
             ) {
1718
          /* We have a dialogue, with this key, opened before this request */
1719
#ifdef DEBUG_TCAPSRT
1720
          dbg(10,"B%d ", p_tcaphash_begincall->context->session_id);
1721
#endif
1722
0
          return p_tcaphash_begincall;
1723
0
        }
1724
#ifdef DEBUG_TCAPSRT
1725
      dbg(60,"[B%d] ", p_tcaphash_begincall->context->session_id);
1726
#endif
1727
0
      }
1728
      /* Break when list end is reached */
1729
0
      if(p_tcaphash_begincall->next_begincall == NULL) {
1730
#ifdef DEBUG_TCAPSRT
1731
        dbg(23,"End of Blist ");
1732
#endif
1733
0
        break;
1734
0
      }
1735
0
      p_tcaphash_begincall = p_tcaphash_begincall->next_begincall;
1736
0
    } while (p_tcaphash_begincall != NULL) ;
1737
0
  } else {
1738
#ifdef DEBUG_TCAPSRT
1739
    dbg(23,"Not in Bhash ");
1740
#endif
1741
0
  }
1742
0
  return NULL;
1743
0
}
1744
1745
1746
1747
static struct tcaphash_contcall_t *
1748
find_tcaphash_cont(struct tcaphash_cont_info_key_t *p_tcaphash_cont_key,
1749
                   packet_info *pinfo)
1750
0
{
1751
0
  struct tcaphash_contcall_t *p_tcaphash_contcall = NULL;
1752
0
  p_tcaphash_contcall = (struct tcaphash_contcall_t *)wmem_map_lookup(tcaphash_cont, p_tcaphash_cont_key);
1753
1754
0
  if(p_tcaphash_contcall) {
1755
0
    do {
1756
0
      if ( p_tcaphash_contcall->context ) {
1757
0
        if (pinfo->num >= p_tcaphash_contcall->context->first_frame &&
1758
0
            (p_tcaphash_contcall->context->last_frame?pinfo->num <= p_tcaphash_contcall->context->last_frame:1) ) {
1759
          /* We have a dialogue, with this key, opened before this request */
1760
#ifdef DEBUG_TCAPSRT
1761
          dbg(10,"C%d ", p_tcaphash_contcall->context->session_id);
1762
#endif
1763
0
          return p_tcaphash_contcall;
1764
0
        }
1765
#ifdef DEBUG_TCAPSRT
1766
        dbg(60,"[C%d] ", p_tcaphash_contcall->context->session_id);
1767
#endif
1768
0
      }
1769
      /* Break when list end is reached */
1770
0
      if(p_tcaphash_contcall->next_contcall == NULL) {
1771
#ifdef DEBUG_TCAPSRT
1772
        dbg(23,"End of Clist ");
1773
#endif
1774
0
        break;
1775
0
      }
1776
0
      p_tcaphash_contcall = p_tcaphash_contcall->next_contcall;
1777
0
    } while (p_tcaphash_contcall != NULL) ;
1778
0
  } else {
1779
#ifdef DEBUG_TCAPSRT
1780
    dbg(23,"Not in Chash ");
1781
#endif
1782
0
  }
1783
0
  return NULL;
1784
0
}
1785
1786
static struct tcaphash_endcall_t *
1787
find_tcaphash_end(struct tcaphash_end_info_key_t *p_tcaphash_end_key,
1788
                  packet_info *pinfo, bool isEnd)
1789
0
{
1790
0
  struct tcaphash_endcall_t *p_tcaphash_endcall = NULL;
1791
0
  p_tcaphash_endcall = (struct tcaphash_endcall_t *)wmem_map_lookup(tcaphash_end, p_tcaphash_end_key);
1792
1793
0
  if(p_tcaphash_endcall) {
1794
0
    do {
1795
0
      if ( p_tcaphash_endcall->context ) {
1796
0
        if ( ( isEnd &&
1797
0
               (p_tcaphash_endcall->context->last_frame?pinfo->num == p_tcaphash_endcall->context->last_frame:1)
1798
0
               )
1799
0
             ||
1800
0
             ( !isEnd &&
1801
0
               pinfo->num >= p_tcaphash_endcall->context->first_frame &&
1802
0
               (p_tcaphash_endcall->context->last_frame?pinfo->num <= p_tcaphash_endcall->context->last_frame:1)
1803
0
               )
1804
0
             ) {
1805
          /* We have a dialogue, with this key, opened before this request */
1806
#ifdef DEBUG_TCAPSRT
1807
          dbg(10,"E%d ", p_tcaphash_endcall->context->session_id);
1808
#endif
1809
0
          return p_tcaphash_endcall;
1810
0
        }
1811
#ifdef DEBUG_TCAPSRT
1812
          dbg(60,"[E%d] ", p_tcaphash_endcall->context->session_id);
1813
#endif
1814
0
      }
1815
      /* Break when list end is reached */
1816
0
      if(p_tcaphash_endcall->next_endcall == NULL) {
1817
#ifdef DEBUG_TCAPSRT
1818
        dbg(23,"End of Elist ");
1819
#endif
1820
0
        break;
1821
0
      }
1822
0
      p_tcaphash_endcall = p_tcaphash_endcall->next_endcall;
1823
0
    } while (p_tcaphash_endcall != NULL) ;
1824
0
  } else {
1825
#ifdef DEBUG_TCAPSRT
1826
    dbg(23,"Not in Ehash ");
1827
#endif
1828
0
  }
1829
0
  return NULL;
1830
0
}
1831
1832
/*
1833
 * New record to create, to identify a new transaction
1834
 */
1835
static struct tcaphash_context_t *
1836
new_tcaphash_context(struct tcaphash_context_key_t *p_tcaphash_context_key,
1837
                     packet_info *pinfo)
1838
0
{
1839
0
  struct tcaphash_context_key_t *p_new_tcaphash_context_key;
1840
0
  struct tcaphash_context_t *p_new_tcaphash_context = NULL;
1841
1842
  /* Register the transaction in the hash table
1843
     with the tcap transaction Id as Main Key
1844
     Once created, this entry will be updated later */
1845
1846
0
  p_new_tcaphash_context_key = wmem_new(wmem_file_scope(), struct tcaphash_context_key_t);
1847
0
  p_new_tcaphash_context_key->session_id = p_tcaphash_context_key->session_id;
1848
1849
0
  p_new_tcaphash_context = wmem_new0(wmem_file_scope(), struct tcaphash_context_t);
1850
0
  p_new_tcaphash_context->key = p_new_tcaphash_context_key;
1851
0
  p_new_tcaphash_context->session_id = p_tcaphash_context_key->session_id;
1852
0
  p_new_tcaphash_context->first_frame = pinfo->num;
1853
#ifdef DEBUG_TCAPSRT
1854
  dbg(10,"S%d ", p_new_tcaphash_context->session_id);
1855
#endif
1856
  /* store it */
1857
0
  wmem_map_insert(tcaphash_context, p_new_tcaphash_context_key, p_new_tcaphash_context);
1858
0
  return p_new_tcaphash_context;
1859
0
}
1860
1861
/*
1862
 * New record to create, to identify a new transaction
1863
 */
1864
static struct tcaphash_begincall_t *
1865
new_tcaphash_begin(struct tcaphash_begin_info_key_t *p_tcaphash_begin_key,
1866
                   struct tcaphash_context_t *p_tcaphash_context)
1867
0
{
1868
0
  struct tcaphash_begin_info_key_t *p_new_tcaphash_begin_key;
1869
0
  struct tcaphash_begincall_t *p_new_tcaphash_begincall = NULL;
1870
1871
  /* Register the transaction in the hash table
1872
     with the tcap transaction Id as Main Key
1873
     Once created, this entry will be updated later */
1874
1875
0
  p_new_tcaphash_begin_key = wmem_new(wmem_file_scope(), struct tcaphash_begin_info_key_t);
1876
0
  p_new_tcaphash_begin_key->hashKey = p_tcaphash_begin_key->hashKey;
1877
0
  p_new_tcaphash_begin_key->tid = p_tcaphash_begin_key->tid;
1878
0
  p_new_tcaphash_begin_key->pc_hash = p_tcaphash_begin_key->pc_hash;
1879
1880
0
 p_new_tcaphash_begincall = wmem_new0(wmem_file_scope(), struct tcaphash_begincall_t);
1881
0
  p_new_tcaphash_begincall->beginkey=p_new_tcaphash_begin_key;
1882
0
  p_new_tcaphash_begincall->context=p_tcaphash_context;
1883
0
  p_tcaphash_context->begincall=p_new_tcaphash_begincall;
1884
0
  p_new_tcaphash_begincall->father=true;
1885
0
  p_new_tcaphash_begincall->next_begincall=NULL;
1886
0
  p_new_tcaphash_begincall->previous_begincall=NULL;
1887
1888
#ifdef DEBUG_TCAPSRT
1889
  dbg(10,"B%d ", p_new_tcaphash_begincall->context->session_id);
1890
#endif
1891
  /* store it */
1892
0
  wmem_map_insert(tcaphash_begin, p_new_tcaphash_begin_key, p_new_tcaphash_begincall);
1893
0
  return p_new_tcaphash_begincall;
1894
0
}
1895
1896
1897
1898
/*
1899
 * New record to create, to identify a new transaction
1900
 */
1901
static struct tcaphash_contcall_t *
1902
new_tcaphash_cont(struct tcaphash_cont_info_key_t *p_tcaphash_cont_key,
1903
                  struct tcaphash_context_t *p_tcaphash_context)
1904
0
{
1905
0
  struct tcaphash_cont_info_key_t *p_new_tcaphash_cont_key;
1906
0
  struct tcaphash_contcall_t *p_new_tcaphash_contcall = NULL;
1907
1908
  /* Register the transaction in the hash table
1909
     with the tcap transaction Id as Main Key
1910
     Once created, this entry will be updated later */
1911
1912
0
  p_new_tcaphash_cont_key = wmem_new(wmem_file_scope(), struct tcaphash_cont_info_key_t);
1913
0
  p_new_tcaphash_cont_key->hashKey = p_tcaphash_cont_key->hashKey;
1914
0
  p_new_tcaphash_cont_key->src_tid = p_tcaphash_cont_key->src_tid;
1915
0
  p_new_tcaphash_cont_key->dst_tid = p_tcaphash_cont_key->dst_tid;
1916
0
  p_new_tcaphash_cont_key->opc_hash = p_tcaphash_cont_key->opc_hash;
1917
0
  p_new_tcaphash_cont_key->dpc_hash = p_tcaphash_cont_key->dpc_hash;
1918
1919
0
  p_new_tcaphash_contcall = wmem_new0(wmem_file_scope(), struct tcaphash_contcall_t);
1920
0
  p_new_tcaphash_contcall->contkey=p_new_tcaphash_cont_key;
1921
0
  p_new_tcaphash_contcall->context=p_tcaphash_context;
1922
0
  p_tcaphash_context->contcall=p_new_tcaphash_contcall;
1923
0
  p_new_tcaphash_contcall->father=true;
1924
0
  p_new_tcaphash_contcall->next_contcall=NULL;
1925
0
  p_new_tcaphash_contcall->previous_contcall=NULL;
1926
1927
#ifdef DEBUG_TCAPSRT
1928
  dbg(10,"C%d ", p_new_tcaphash_contcall->context->session_id);
1929
#endif
1930
  /* store it */
1931
0
  wmem_map_insert(tcaphash_cont, p_new_tcaphash_cont_key, p_new_tcaphash_contcall);
1932
0
  return p_new_tcaphash_contcall;
1933
0
}
1934
1935
1936
/*
1937
 * New record to create, to identify a new transaction
1938
 */
1939
static struct tcaphash_endcall_t *
1940
new_tcaphash_end(struct tcaphash_end_info_key_t *p_tcaphash_end_key,
1941
                 struct tcaphash_context_t *p_tcaphash_context)
1942
0
{
1943
0
  struct tcaphash_end_info_key_t *p_new_tcaphash_end_key;
1944
0
  struct tcaphash_endcall_t *p_new_tcaphash_endcall = NULL;
1945
1946
  /* Register the transaction in the hash table
1947
     with the tcap transaction Id as Main Key
1948
     Once created, this entry will be updated later */
1949
1950
0
  p_new_tcaphash_end_key = wmem_new(wmem_file_scope(), struct tcaphash_end_info_key_t);
1951
0
  p_new_tcaphash_end_key->hashKey = p_tcaphash_end_key->hashKey;
1952
0
  p_new_tcaphash_end_key->tid = p_tcaphash_end_key->tid;
1953
0
  p_new_tcaphash_end_key->opc_hash = p_tcaphash_end_key->opc_hash;
1954
0
  p_new_tcaphash_end_key->dpc_hash = p_tcaphash_end_key->dpc_hash;
1955
1956
0
  p_new_tcaphash_endcall = wmem_new0(wmem_file_scope(), struct tcaphash_endcall_t);
1957
0
  p_new_tcaphash_endcall->endkey=p_new_tcaphash_end_key;
1958
0
  p_new_tcaphash_endcall->context=p_tcaphash_context;
1959
0
  p_tcaphash_context->endcall=p_new_tcaphash_endcall;
1960
0
  p_new_tcaphash_endcall->father=true;
1961
0
  p_new_tcaphash_endcall->next_endcall=NULL;
1962
0
  p_new_tcaphash_endcall->previous_endcall=NULL;
1963
1964
#ifdef DEBUG_TCAPSRT
1965
  dbg(10,"E%d ", p_new_tcaphash_endcall->context->session_id);
1966
#endif
1967
  /* store it */
1968
0
  wmem_map_insert(tcaphash_end, p_new_tcaphash_end_key, p_new_tcaphash_endcall);
1969
0
  return p_new_tcaphash_endcall;
1970
0
}
1971
/*
1972
 * New record to create, to identify a new transaction
1973
 */
1974
static struct tcaphash_ansicall_t *
1975
new_tcaphash_ansi(struct tcaphash_ansi_info_key_t *p_tcaphash_ansi_key,
1976
                   struct tcaphash_context_t *p_tcaphash_context)
1977
0
{
1978
0
  struct tcaphash_ansi_info_key_t *p_new_tcaphash_ansi_key;
1979
0
  struct tcaphash_ansicall_t *p_new_tcaphash_ansicall = NULL;
1980
1981
  /* Register the transaction in the hash table
1982
     with the tcap transaction Id as Main Key
1983
     Once created, this entry will be updated later */
1984
1985
0
  p_new_tcaphash_ansi_key = wmem_new(wmem_file_scope(), struct tcaphash_ansi_info_key_t);
1986
0
  p_new_tcaphash_ansi_key->hashKey = p_tcaphash_ansi_key->hashKey;
1987
0
  p_new_tcaphash_ansi_key->tid = p_tcaphash_ansi_key->tid;
1988
0
  p_new_tcaphash_ansi_key->opc_hash = p_tcaphash_ansi_key->opc_hash;
1989
0
  p_new_tcaphash_ansi_key->dpc_hash = p_tcaphash_ansi_key->dpc_hash;
1990
1991
0
  p_new_tcaphash_ansicall = wmem_new0(wmem_file_scope(), struct tcaphash_ansicall_t);
1992
0
  p_new_tcaphash_ansicall->ansikey=p_new_tcaphash_ansi_key;
1993
0
  p_new_tcaphash_ansicall->context=p_tcaphash_context;
1994
0
  p_tcaphash_context->ansicall=p_new_tcaphash_ansicall;
1995
0
  p_new_tcaphash_ansicall->father=true;
1996
0
  p_new_tcaphash_ansicall->next_ansicall=NULL;
1997
0
  p_new_tcaphash_ansicall->previous_ansicall=NULL;
1998
1999
#ifdef DEBUG_TCAPSRT
2000
  dbg(10,"A%d ", p_new_tcaphash_ansicall->context->session_id);
2001
#endif
2002
  /* store it */
2003
0
  wmem_map_insert(tcaphash_ansi, p_new_tcaphash_ansi_key, p_new_tcaphash_ansicall);
2004
0
  return p_new_tcaphash_ansicall;
2005
0
}
2006
2007
static struct tcaphash_contcall_t *
2008
create_tcaphash_cont(struct tcaphash_cont_info_key_t *p_tcaphash_cont_key,
2009
                     struct tcaphash_context_t *p_tcaphash_context)
2010
0
{
2011
0
  struct tcaphash_contcall_t *p_tcaphash_contcall1 = NULL;
2012
0
  struct tcaphash_contcall_t *p_tcaphash_contcall = NULL;
2013
2014
0
  p_tcaphash_contcall1 = (struct tcaphash_contcall_t *)
2015
0
    wmem_map_lookup(tcaphash_cont, p_tcaphash_cont_key);
2016
2017
0
  if (p_tcaphash_contcall1) {
2018
    /* Walk through list of transaction with identical keys */
2019
    /* go to the end to insert new record */
2020
0
    do {
2021
0
      if (!p_tcaphash_contcall1->next_contcall) {
2022
0
        p_tcaphash_contcall=append_tcaphash_contcall(p_tcaphash_contcall1,
2023
0
                                                     p_tcaphash_context);
2024
0
        break;
2025
0
      }
2026
0
      p_tcaphash_contcall1 = p_tcaphash_contcall1->next_contcall;
2027
0
    } while (p_tcaphash_contcall1 != NULL );
2028
0
  } else {
2029
0
    p_tcaphash_contcall = new_tcaphash_cont(p_tcaphash_cont_key,
2030
0
                                            p_tcaphash_context);
2031
0
  }
2032
0
  return p_tcaphash_contcall;
2033
0
}
2034
2035
2036
static struct tcaphash_endcall_t *
2037
create_tcaphash_end(struct tcaphash_end_info_key_t *p_tcaphash_end_key,
2038
                    struct tcaphash_context_t *p_tcaphash_context)
2039
0
{
2040
0
  struct tcaphash_endcall_t *p_tcaphash_endcall1 = NULL;
2041
0
  struct tcaphash_endcall_t *p_tcaphash_endcall = NULL;
2042
2043
0
  p_tcaphash_endcall1 = (struct tcaphash_endcall_t *)
2044
0
    wmem_map_lookup(tcaphash_end, p_tcaphash_end_key);
2045
2046
0
  if (p_tcaphash_endcall1) {
2047
    /* Walk through list of transaction with identical keys */
2048
    /* go to the end to insert new record */
2049
0
    do {
2050
0
      if (!p_tcaphash_endcall1->next_endcall) {
2051
0
        p_tcaphash_endcall=append_tcaphash_endcall(p_tcaphash_endcall1,
2052
0
                                                   p_tcaphash_context);
2053
0
        break;
2054
0
      }
2055
0
      p_tcaphash_endcall1 = p_tcaphash_endcall1->next_endcall;
2056
0
    } while (p_tcaphash_endcall1 != NULL );
2057
0
  } else {
2058
0
    p_tcaphash_endcall = new_tcaphash_end(p_tcaphash_end_key,
2059
0
                                          p_tcaphash_context);
2060
0
  }
2061
0
  return p_tcaphash_endcall;
2062
0
}
2063
2064
/*
2065
 * Create the record identifiying the TCAP transaction
2066
 * When the identifier for the transaction is reused, check
2067
 * the following criteria before to append a new record:
2068
 * - a timeout corresponding to a message retransmission is detected,
2069
 * - a message hast been lost
2070
 * - or the previous transaction has been  be closed
2071
 */
2072
static struct tcaphash_context_t *
2073
tcaphash_begin_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2074
                        struct tcapsrt_info_t *p_tcapsrt_info)
2075
0
{
2076
0
  struct tcaphash_context_t *p_tcaphash_context=NULL;
2077
0
  struct tcaphash_context_key_t tcaphash_context_key;
2078
0
  struct tcaphash_begincall_t *p_tcaphash_begincall, *p_new_tcaphash_begincall=NULL;
2079
0
  struct tcaphash_begin_info_key_t tcaphash_begin_key;
2080
0
  proto_item *pi;
2081
0
  proto_item *stat_item=NULL;
2082
0
  proto_tree *stat_tree=NULL;
2083
2084
#ifdef DEBUG_TCAPSRT
2085
  dbg(51,"src %s srcTid %lx dst %s ", address_to_str(pinfo->pool, &pinfo->src), p_tcapsrt_info->src_tid, address_to_str(pinfo->pool, &pinfo->dst));
2086
#endif
2087
2088
  /* prepare the key data */
2089
0
  tcaphash_begin_key.tid = p_tcapsrt_info->src_tid;
2090
0
  if (pinfo->src.type == ss7pc_address_type && pinfo->dst.type == ss7pc_address_type)
2091
0
  {
2092
    /* We have MTP3 PCs (so we can safely do this cast) */
2093
0
    tcaphash_begin_key.pc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
2094
0
  } else {
2095
    /* Don't have MTP3 PCs (have SCCP GT ?) */
2096
0
    tcaphash_begin_key.pc_hash = g_str_hash(address_to_str(pinfo->pool, &pinfo->src));
2097
0
  }
2098
0
  tcaphash_begin_key.hashKey=tcaphash_begin_calchash(&tcaphash_begin_key);
2099
2100
  /* look up the request */
2101
#ifdef DEBUG_TCAPSRT
2102
  dbg(10,"\n Hbegin #%u ", pinfo->num);
2103
  dbg(11,"key %lx ",tcaphash_begin_key.hashKey);
2104
  dbg(51,"addr %s ", address_to_str(pinfo->pool, &pinfo->src));
2105
  dbg(51,"Tid %lx \n",tcaphash_begin_key.tid);
2106
#endif
2107
2108
0
  p_tcaphash_begincall = (struct tcaphash_begincall_t *)
2109
0
  wmem_map_lookup(tcaphash_begin, &tcaphash_begin_key);
2110
2111
0
  if (p_tcaphash_begincall) {
2112
    /* Walk through list of transaction with identical keys */
2113
0
    do {
2114
      /* Check if the request with this reqSeqNum has been seen, with the same Message Type */
2115
0
      if (pinfo->num == p_tcaphash_begincall->context->first_frame) {
2116
        /* We have seen this request before -> do nothing */
2117
#ifdef DEBUG_TCAPSRT
2118
        dbg(22,"Already seen ");
2119
#endif
2120
0
        p_tcaphash_context=p_tcaphash_begincall->context;
2121
0
        break;
2122
0
      }
2123
      /* If the last record for Tcap transaction with identifier has not been reached */
2124
0
      if (!p_tcaphash_begincall->next_begincall) {
2125
        /* check if we have to create a new record or not */
2126
        /* if last request has been responded (response number is known)
2127
           and this request appears after last response (has bigger frame number)
2128
           and last request occurred after the timeout for repetition,
2129
           or
2130
           if last request hasn't been responded (so number unknown)
2131
           and this request appears after last request (has bigger frame number)
2132
           and this request occurred after the timeout for message lost */
2133
0
        if ( ( p_tcaphash_begincall->context->last_frame != 0
2134
0
               && pinfo->num > p_tcaphash_begincall->context->first_frame
2135
0
               && (unsigned) pinfo->abs_ts.secs > (unsigned)(p_tcaphash_begincall->context->begin_time.secs + gtcap_RepetitionTimeout)
2136
0
               ) ||
2137
0
             ( p_tcaphash_begincall->context->last_frame == 0
2138
0
               && pinfo->num > p_tcaphash_begincall->context->first_frame
2139
0
               && (unsigned)pinfo->abs_ts.secs > (unsigned)(p_tcaphash_begincall->context->begin_time.secs + gtcap_LostTimeout)
2140
0
               )
2141
0
             )
2142
0
          {
2143
            /* we decide that we have a new request */
2144
            /* Append new record to the list */
2145
#ifdef DEBUG_TCAPSRT
2146
            dbg(12,"(timeout) Append key %lx ",tcaphash_begin_key.hashKey);
2147
            dbg(12,"Frame %u rsp %u ",pinfo->num,p_tcaphash_begincall->context->last_frame );
2148
#endif
2149
0
            tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
2150
0
            p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
2151
2152
0
            p_new_tcaphash_begincall = append_tcaphash_begincall(p_tcaphash_begincall,
2153
0
                                                                 p_tcaphash_context,
2154
0
                                                                 pinfo);
2155
#ifdef DEBUG_TCAPSRT
2156
            dbg(12,"Update key %lx ",tcaphash_begin_key.hashKey);
2157
#endif
2158
0
            update_tcaphash_begincall(p_new_tcaphash_begincall, pinfo);
2159
0
          } else { /* timeout or message lost */
2160
2161
          /* If the Tid is reused for a closed Transaction */
2162
          /* Or if we received an TC_BEGIN for a Transaction marked as "closed" */
2163
          /* (this is the case, for pre-arranged END, the transaction is marked as closed */
2164
          /* by the upper layer, thank to a callback method close) */
2165
0
          if ( p_tcaphash_begincall->context->closed) {
2166
#ifdef DEBUG_TCAPSRT
2167
            dbg(12,"(closed) Append key %lu ",tcaphash_begin_key.hashKey);
2168
            dbg(12,"Frame %u rsp %u ",pinfo->num,p_tcaphash_begincall->context->last_frame );
2169
#endif
2170
0
            tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
2171
0
            p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
2172
0
            p_new_tcaphash_begincall = append_tcaphash_begincall(p_tcaphash_begincall,
2173
0
                                                                 p_tcaphash_context,
2174
0
                                                                 pinfo);
2175
2176
#ifdef DEBUG_TCAPSRT
2177
            dbg(12,"Update key %lu ",tcaphash_begin_key.hashKey);
2178
#endif
2179
0
            update_tcaphash_begincall(p_new_tcaphash_begincall, pinfo);
2180
2181
0
          } else {
2182
            /* the TCAP session is not closed, so, either messages have been lost */
2183
            /* or it's a duplicate request. Mark it as such. */
2184
#ifdef DEBUG_TCAPSRT
2185
            dbg(21,"Display_duplicate %d ",p_tcaphash_begincall->context->first_frame);
2186
#endif
2187
0
            p_tcaphash_context=p_tcaphash_begincall->context;
2188
0
            if (gtcap_DisplaySRT && tree) {
2189
0
              stat_tree = proto_tree_add_subtree(tree, tvb, 0, -1, ett_tcap_stat, &stat_item, "Stat");
2190
0
              proto_item_set_generated(stat_item);
2191
0
              pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_Duplicate, tvb, 0, 0,
2192
0
                                              p_tcaphash_context->first_frame,
2193
0
                                              "Duplicate with session %u in frame %u",
2194
0
                                              p_tcaphash_context->session_id,p_tcaphash_context->first_frame);
2195
0
              proto_item_set_generated(pi);
2196
0
            }
2197
0
            return p_tcaphash_context;
2198
0
          } /* Previous session closed */
2199
0
        } /* test with Timeout or message Lost */
2200
0
        break;
2201
0
      } /* Next call is NULL */
2202
      /* Repeat the tests for the next record with the same transaction identifier */
2203
0
      p_tcaphash_begincall = p_tcaphash_begincall->next_begincall;
2204
0
    } while (p_tcaphash_begincall != NULL );
2205
    /*
2206
     * End of analyze for the list be TC_BEGIN with same transaction ID
2207
     */
2208
0
  } else { /* p_tcaphash_begincall has not been found */
2209
    /*
2210
     * Create a new TCAP context
2211
     */
2212
#ifdef DEBUG_TCAPSRT
2213
    dbg(10,"New key %lx ",tcaphash_begin_key.hashKey);
2214
#endif
2215
2216
0
    tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
2217
0
    p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
2218
0
    p_tcaphash_begincall = new_tcaphash_begin(&tcaphash_begin_key, p_tcaphash_context);
2219
2220
#ifdef DEBUG_TCAPSRT
2221
    dbg(11,"Update key %lx ",tcaphash_begin_key.hashKey);
2222
    dbg(11,"Frame reqlink #%u ", pinfo->num);
2223
#endif
2224
0
    update_tcaphash_begincall(p_tcaphash_begincall, pinfo);
2225
0
  }
2226
2227
  /* display tcap session, if available */
2228
0
  if ( gtcap_DisplaySRT && tree &&
2229
0
       p_tcaphash_context &&
2230
0
       p_tcaphash_context->session_id) {
2231
0
    stat_tree = proto_tree_add_subtree(tree, tvb, 0, 0, ett_tcap_stat, &stat_item, "Stat");
2232
0
    proto_item_set_generated(stat_item);
2233
0
    pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
2234
0
    proto_item_set_generated(pi);
2235
2236
    /* add link to response frame, if available */
2237
    /* p_tcaphash_begincall->context->last_frame) */
2238
0
    if( p_tcaphash_context->last_frame != 0 ){
2239
#ifdef DEBUG_TCAPSRT
2240
      dbg(20,"Display_frameRsplink %d ",p_tcaphash_context->last_frame);
2241
#endif
2242
0
      pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_BeginSession, tvb, 0, 0,
2243
0
                                      p_tcaphash_context->last_frame,
2244
0
                                      "End of session in frame %u",
2245
0
                                      p_tcaphash_context->last_frame);
2246
0
      proto_item_set_generated(pi);
2247
0
    }
2248
0
  }
2249
0
  return p_tcaphash_context;
2250
0
}
2251
2252
/*
2253
* Try to find a TCAP session according to the source and destination
2254
* Identifier given in the TC_CONT
2255
* If nothing is found, it is probably a session in opening state, so try to find
2256
* a tcap session registered with a TC_BEGIN "key", matching the destination Id of the TC_CONT
2257
* Then associate the TC_CONT "key" to the TCAP context, and create a TC_END "key"
2258
* and display the available info for the TCAP context
2259
*/
2260
static struct tcaphash_context_t *
2261
tcaphash_cont_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2262
                       struct tcapsrt_info_t *p_tcapsrt_info)
2263
0
{
2264
0
  struct tcaphash_context_t *p_tcaphash_context=NULL;
2265
0
  struct tcaphash_contcall_t *p_tcaphash_contcall;
2266
0
  struct tcaphash_cont_info_key_t tcaphash_cont_key;
2267
0
  struct tcaphash_begin_info_key_t tcaphash_begin_key;
2268
0
  struct tcaphash_begincall_t *p_tcaphash_begincall;
2269
0
  struct tcaphash_end_info_key_t tcaphash_end_key;
2270
0
  proto_item *pi;
2271
0
  proto_item *stat_item=NULL;
2272
0
  proto_tree *stat_tree=NULL;
2273
0
  bool use_dst = false;
2274
2275
#ifdef DEBUG_TCAPSRT
2276
  dbg(51,"src %s srcTid %lx dst %s dstTid %lx ", address_to_str(pinfo->pool, &pinfo->src), p_tcapsrt_info->src_tid, address_to_str(pinfo->pool, &pinfo->dst), p_tcapsrt_info->dst_tid);
2277
  dbg(10,"\n Hcont #%u ", pinfo->num);
2278
#endif
2279
2280
  /* look only for matching request, if matching conversation is available. */
2281
0
  tcaphash_cont_key.src_tid = p_tcapsrt_info->src_tid;
2282
0
  tcaphash_cont_key.dst_tid = p_tcapsrt_info->dst_tid;
2283
0
  if (pinfo->src.type == ss7pc_address_type && pinfo->dst.type == ss7pc_address_type)
2284
0
  {
2285
    /* We have MTP3 PCs (so we can safely do this cast) */
2286
0
    tcaphash_cont_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
2287
0
    tcaphash_cont_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
2288
0
  } else {
2289
    /* Don't have MTP3 PCs (have SCCP GT ?) */
2290
0
    tcaphash_cont_key.opc_hash = g_str_hash(address_to_str(pinfo->pool, &pinfo->src));
2291
0
    tcaphash_cont_key.dpc_hash = g_str_hash(address_to_str(pinfo->pool, &pinfo->dst));
2292
0
  }
2293
0
  tcaphash_cont_key.hashKey=tcaphash_cont_calchash(&tcaphash_cont_key);
2294
2295
#ifdef DEBUG_TCAPSRT
2296
  dbg(11,"Ckey %lx ", tcaphash_cont_key.hashKey);
2297
  dbg(51,"addr %s %s ", address_to_str(pinfo->pool, &pinfo->src), address_to_str(pinfo->pool, &pinfo->dst));
2298
  dbg(51,"Tid %lx %lx \n",tcaphash_cont_key.src_tid, tcaphash_cont_key.dst_tid);
2299
#endif
2300
0
  p_tcaphash_contcall = find_tcaphash_cont(&tcaphash_cont_key, pinfo);
2301
0
  if(p_tcaphash_contcall) {
2302
#ifdef DEBUG_TCAPSRT
2303
    dbg(12,"CFound ");
2304
#endif
2305
0
    p_tcaphash_context=p_tcaphash_contcall->context;
2306
0
  } else { /* cont not found */
2307
#ifdef DEBUG_TCAPSRT
2308
    dbg(12,"CnotFound ");
2309
#endif
2310
    /* Find the TCAP transaction according to the TC_BEGIN (from dtid,dst) */
2311
0
    tcaphash_begin_key.tid = p_tcapsrt_info->dst_tid;
2312
0
    if (pinfo->src.type == ss7pc_address_type && pinfo->dst.type == ss7pc_address_type)
2313
0
    {
2314
      /* We have MTP3 PCs (so we can safely do this cast) */
2315
0
      tcaphash_begin_key.pc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
2316
0
    } else {
2317
      /* Don't have MTP3 PCs (have SCCP GT ?) */
2318
0
      tcaphash_begin_key.pc_hash = g_str_hash(address_to_str(pinfo->pool, &pinfo->dst));
2319
0
    }
2320
0
    tcaphash_begin_key.hashKey=tcaphash_begin_calchash(&tcaphash_begin_key);
2321
2322
#ifdef DEBUG_TCAPSRT
2323
    dbg(11,"Bkey %lx ", tcaphash_begin_key.hashKey);
2324
    dbg(51,"addr %s ", address_to_str(pinfo->pool, &pinfo->dst));
2325
    dbg(51,"Tid %lx \n",tcaphash_begin_key.tid);
2326
#endif
2327
0
    p_tcaphash_begincall = find_tcaphash_begin(&tcaphash_begin_key, pinfo, false);
2328
0
    if(!p_tcaphash_begincall){
2329
0
      try_src:
2330
/* can this actually happen? */
2331
#ifdef DEBUG_TCAPSRT
2332
        dbg(12,"BNotFound trying stid,src");
2333
#endif
2334
        /* Do we have a continue from the same source? (stid,src) */
2335
0
        use_dst = true;
2336
0
        tcaphash_begin_key.tid = p_tcapsrt_info->src_tid;
2337
0
        if (pinfo->src.type == ss7pc_address_type && pinfo->dst.type == ss7pc_address_type)
2338
0
        {
2339
          /* We have MTP3 PCs (so we can safely do this cast) */
2340
0
          tcaphash_begin_key.pc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
2341
0
        } else {
2342
          /* Don't have MTP3 PCs (have SCCP GT ?) */
2343
0
          tcaphash_begin_key.pc_hash = g_str_hash(address_to_str(pinfo->pool, &pinfo->src));
2344
0
        }
2345
0
        tcaphash_begin_key.hashKey=tcaphash_begin_calchash(&tcaphash_begin_key);
2346
#ifdef DEBUG_TCAPSRT
2347
        dbg(11,"Bkey %lx ", tcaphash_begin_key.hashKey);
2348
        dbg(51,"addr %s ", address_to_str(pinfo->pool, &pinfo->src));
2349
        dbg(51,"Tid %lx \n",tcaphash_begin_key.tid);
2350
#endif
2351
0
        p_tcaphash_begincall = find_tcaphash_begin(&tcaphash_begin_key, pinfo,false);
2352
0
    }
2353
0
    if(p_tcaphash_begincall &&
2354
0
       !p_tcaphash_begincall->context->contcall ) {
2355
#ifdef DEBUG_TCAPSRT
2356
      dbg(12,"BFound \n");
2357
#endif
2358
0
      p_tcaphash_context=p_tcaphash_begincall->context;
2359
0
      p_tcaphash_context->responded=true;
2360
2361
#ifdef DEBUG_TCAPSRT
2362
      dbg(10,"New Ckey %lx ",tcaphash_cont_key.hashKey);
2363
      dbg(11,"Frame reqlink #%u \n", pinfo->num);
2364
#endif
2365
0
      create_tcaphash_cont(&tcaphash_cont_key,
2366
0
                           p_tcaphash_begincall->context);
2367
2368
      /* Create END for (stid,src) or (dtid,dst) */
2369
0
      tcaphash_end_key.tid = use_dst ? p_tcapsrt_info->dst_tid : p_tcapsrt_info->src_tid;
2370
0
      if (pinfo->src.type == ss7pc_address_type && pinfo->dst.type == ss7pc_address_type)
2371
0
      {
2372
        /* We have MTP3 PCs (so we can safely do this cast) */
2373
0
        tcaphash_end_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)(use_dst ? pinfo->dst.data : pinfo->src.data));
2374
0
        tcaphash_end_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)(use_dst ? pinfo->src.data : pinfo->dst.data));
2375
0
    } else {
2376
        /* Don't have MTP3 PCs (have SCCP GT ?) */
2377
0
        tcaphash_end_key.dpc_hash = g_str_hash(address_to_str(pinfo->pool, use_dst ? &pinfo->dst : &pinfo->src));
2378
0
        tcaphash_end_key.opc_hash = g_str_hash(address_to_str(pinfo->pool, use_dst ? &pinfo->src : &pinfo->dst));
2379
0
    }
2380
0
      tcaphash_end_key.hashKey=tcaphash_end_calchash(&tcaphash_end_key);
2381
2382
#ifdef DEBUG_TCAPSRT
2383
      dbg(10,"New Ekey %lx ",tcaphash_end_key.hashKey);
2384
      dbg(51,"addr %s ", address_to_str(pinfo->pool, use_dst ? &pinfo->dst : &pinfo->src));
2385
      dbg(51,"Tid %lx ",tcaphash_end_key.tid);
2386
      dbg(11,"Frame reqlink #%u ", pinfo->num);
2387
#endif
2388
0
      create_tcaphash_end(&tcaphash_end_key,
2389
0
                          p_tcaphash_begincall->context);
2390
2391
0
    } else { /* Begin not found */
2392
#ifdef DEBUG_TCAPSRT
2393
      dbg(12,"BnotFound ");
2394
#endif
2395
0
      if (!use_dst) {
2396
        /* make another try with src tid / address */
2397
0
        goto try_src;
2398
0
      }
2399
0
    } /* begin found */
2400
0
  } /* cont found */
2401
    /* display tcap session, if available */
2402
0
  if (gtcap_DisplaySRT && tree &&
2403
0
      p_tcaphash_context &&
2404
0
      p_tcaphash_context->session_id) {
2405
0
    stat_tree = proto_tree_add_subtree(tree, tvb, 0, -1, ett_tcap_stat, &stat_item, "Stat");
2406
0
    proto_item_set_generated(stat_item);
2407
0
    pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
2408
0
    proto_item_set_generated(pi);
2409
0
  }
2410
2411
0
  return p_tcaphash_context;
2412
0
}
2413
2414
/*
2415
* Try to find a TCAP session according to the destination Identifier given in the TC_END/TC_ABORT
2416
* If nothing is found,
2417
* - either it is a session in opening state,
2418
* - or the session is closed/aborted by the remote, ( so we switch the src and dst tid )
2419
* so try to find a tcap session registered with a TC_BEGIN "key",
2420
* matching the destination Id of the TC_END
2421
* Then associate the TC_CONT "key" to the TCAP context
2422
* and display the available info for the TCAP context
2423
*/
2424
2425
static struct tcaphash_context_t *
2426
tcaphash_end_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2427
                      struct tcapsrt_info_t *p_tcapsrt_info)
2428
0
{
2429
0
  struct tcaphash_context_t *p_tcaphash_context=NULL;
2430
2431
0
  struct tcaphash_end_info_key_t tcaphash_end_key;
2432
0
  struct tcaphash_endcall_t *p_tcaphash_endcall=NULL;
2433
2434
0
  struct tcaphash_begin_info_key_t tcaphash_begin_key;
2435
0
  struct tcaphash_begincall_t *p_tcaphash_begincall=NULL;
2436
0
  proto_item *pi;
2437
0
  nstime_t delta;
2438
0
  proto_item *stat_item=NULL;
2439
0
  proto_tree *stat_tree=NULL;
2440
2441
#ifdef DEBUG_TCAPSRT
2442
  dbg(51,"src %s dst %s dstTid %lx ", address_to_str(pinfo->pool, &pinfo->src), address_to_str(pinfo->pool, &pinfo->dst), p_tcapsrt_info->dst_tid);
2443
  dbg(10,"\n Hend #%u ", pinfo->num);
2444
#endif
2445
  /* look only for matching request, if matching conversation is available. */
2446
0
  tcaphash_end_key.tid = p_tcapsrt_info->dst_tid;
2447
0
  if (pinfo->src.type == ss7pc_address_type && pinfo->dst.type == ss7pc_address_type)
2448
0
  {
2449
    /* We have MTP3 PCs (so we can safely do this cast) */
2450
0
    tcaphash_end_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
2451
0
    tcaphash_end_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
2452
0
  } else {
2453
    /* Don't have MTP3 PCs (have SCCP GT ?) */
2454
0
    tcaphash_end_key.opc_hash = g_str_hash(address_to_str(pinfo->pool, &pinfo->src));
2455
0
    tcaphash_end_key.dpc_hash = g_str_hash(address_to_str(pinfo->pool, &pinfo->dst));
2456
0
}
2457
0
  tcaphash_end_key.hashKey=tcaphash_end_calchash(&tcaphash_end_key);
2458
2459
#ifdef DEBUG_TCAPSRT
2460
  dbg(11,"Ekey %lx ",tcaphash_end_key.hashKey);
2461
  dbg(11,"addr %s ", address_to_str(pinfo->pool, &pinfo->dst));
2462
  dbg(51,"Tid %lx ",tcaphash_end_key.tid);
2463
#endif
2464
0
  p_tcaphash_endcall = find_tcaphash_end(&tcaphash_end_key, pinfo,true);
2465
2466
0
  if(!p_tcaphash_endcall) {
2467
#ifdef DEBUG_TCAPSRT
2468
    dbg(12,"EnotFound ");
2469
#endif
2470
0
    tcaphash_begin_key.tid = p_tcapsrt_info->dst_tid;
2471
0
    if (pinfo->src.type == ss7pc_address_type && pinfo->dst.type == ss7pc_address_type)
2472
0
    {
2473
      /* We have MTP3 PCs (so we can safely do this cast) */
2474
0
      tcaphash_begin_key.pc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
2475
0
    } else {
2476
      /* Don't have MTP3 PCs (have SCCP GT ?) */
2477
0
      tcaphash_begin_key.pc_hash = g_str_hash(address_to_str(pinfo->pool, &pinfo->dst));
2478
0
    }
2479
0
    tcaphash_begin_key.hashKey=tcaphash_begin_calchash(&tcaphash_begin_key);
2480
2481
#ifdef DEBUG_TCAPSRT
2482
    dbg(11,"Bkey %lx ", tcaphash_begin_key.hashKey);
2483
    dbg(51,"addr %s ", address_to_str(pinfo->pool, &pinfo->dst));
2484
    dbg(51,"Tid %lx ",tcaphash_begin_key.tid);
2485
#endif
2486
0
    p_tcaphash_begincall = find_tcaphash_begin(&tcaphash_begin_key, pinfo,false);
2487
0
    if(!p_tcaphash_begincall) {
2488
#ifdef DEBUG_TCAPSRT
2489
      dbg(12,"BnotFound ");
2490
#endif
2491
0
    }
2492
0
  }
2493
0
  if (p_tcaphash_endcall) {
2494
    /* Use the TC_BEGIN Destination reference */
2495
0
    p_tcaphash_context=p_tcaphash_endcall->context;
2496
0
  } else if (p_tcaphash_begincall) {
2497
    /* Use the TC_BEGIN Source reference */
2498
0
    p_tcaphash_context=p_tcaphash_begincall->context;
2499
0
  }
2500
2501
0
  if (p_tcaphash_context) {
2502
2503
#ifdef DEBUG_TCAPSRT
2504
    dbg(12,"Found, req=%d ",p_tcaphash_context->first_frame);
2505
#endif
2506
0
    if (gtcap_DisplaySRT && tree) {
2507
0
      stat_tree = proto_tree_add_subtree(tree, tvb, 0, -1, ett_tcap_stat, &stat_item, "Stat");
2508
0
      proto_item_set_generated(stat_item);
2509
2510
0
      pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
2511
0
      proto_item_set_generated(pi);
2512
0
    }
2513
2514
#ifdef DEBUG_TCAPSRT
2515
    dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
2516
#endif
2517
    /* Indicate the frame to which this is a reply. */
2518
0
    if (gtcap_DisplaySRT && stat_tree) {
2519
0
      pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
2520
0
                                      p_tcaphash_context->first_frame,
2521
0
                                      "Begin of session in frame %u",
2522
0
                                      p_tcaphash_context->first_frame);
2523
0
      proto_item_set_generated(pi);
2524
      /* Calculate Service Response Time */
2525
0
      nstime_delta(&delta, &pinfo->abs_ts, &p_tcaphash_context->begin_time);
2526
2527
      /* display Service Response Time and make it filterable */
2528
0
      pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
2529
0
      proto_item_set_generated(pi);
2530
0
    }
2531
    /* Close the context and remove it (if needed) */
2532
0
    tcapsrt_close(p_tcaphash_context,pinfo);
2533
2534
0
  } else {/* context present */
2535
#ifdef DEBUG_TCAPSRT
2536
    dbg(12,"Context notFound ");
2537
#endif
2538
0
  }
2539
0
  return p_tcaphash_context;
2540
0
}
2541
2542
/*
2543
 * ANSI PART
2544
 * Create the record identifiying the TCAP transaction
2545
 * When the identifier for the transaction is reused, check
2546
 * the following criteria before to append a new record:
2547
 * - a timeout corresponding to a message retransmission is detected,
2548
 * - a message hast been lost
2549
 * - or the previous transaction has been  be closed
2550
 */
2551
static struct tcaphash_context_t *
2552
tcaphash_ansi_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2553
                       struct tcapsrt_info_t *p_tcapsrt_info)
2554
0
{
2555
0
  struct tcaphash_context_t *p_tcaphash_context=NULL;
2556
0
  struct tcaphash_context_key_t tcaphash_context_key;
2557
0
  struct tcaphash_ansicall_t *p_tcaphash_ansicall, *p_new_tcaphash_ansicall;
2558
0
  struct tcaphash_ansi_info_key_t tcaphash_ansi_key;
2559
0
  proto_item *pi;
2560
0
  nstime_t delta;
2561
0
  bool isResponse=false;
2562
0
  proto_tree * stat_tree=NULL;
2563
0
  proto_item * stat_item=NULL;
2564
2565
  /* prepare the key data */
2566
0
  tcaphash_ansi_key.tid = p_tcapsrt_info->src_tid;
2567
0
  if (pinfo->src.type == ss7pc_address_type && pinfo->dst.type == ss7pc_address_type)
2568
0
  {
2569
    /* We have MTP3 PCs (so we can safely do this cast) */
2570
0
    tcaphash_ansi_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
2571
0
    tcaphash_ansi_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
2572
0
  } else {
2573
    /* Don't have MTP3 PCs (have SCCP GT ?) */
2574
0
    tcaphash_ansi_key.opc_hash = g_str_hash(address_to_str(pinfo->pool, &pinfo->src));
2575
0
    tcaphash_ansi_key.dpc_hash = g_str_hash(address_to_str(pinfo->pool, &pinfo->dst));
2576
0
  }
2577
0
  tcaphash_ansi_key.hashKey=tcaphash_ansi_calchash(&tcaphash_ansi_key);
2578
2579
  /* look up the request */
2580
#ifdef DEBUG_TCAPSRT
2581
  dbg(10,"\n Hansi #%u ", pinfo->num);
2582
  dbg(11,"key %lx ",tcaphash_ansi_key.hashKey);
2583
  dbg(51,"PC %s %s ",address_to_str(pinfo->pool, &pinfo->src), address_to_str(pinfo->pool, &pinfo->dst));
2584
  dbg(51,"Tid %lx ",tcaphash_ansi_key.tid);
2585
#endif
2586
0
  p_tcaphash_ansicall = (struct tcaphash_ansicall_t *)
2587
0
    wmem_map_lookup(tcaphash_ansi, &tcaphash_ansi_key);
2588
2589
0
  if (p_tcaphash_ansicall) {
2590
    /* Walk through list of transaction with identical keys */
2591
0
    do {
2592
      /* Check if the request with this reqSeqNum has been seen */
2593
0
      if (pinfo->num == p_tcaphash_ansicall->context->first_frame) {
2594
        /* We have seen this request before -> do nothing */
2595
#ifdef DEBUG_TCAPSRT
2596
        dbg(22,"Request already seen ");
2597
#endif
2598
0
        isResponse=false;
2599
0
        p_tcaphash_context=p_tcaphash_ansicall->context;
2600
0
        break;
2601
0
      }
2602
2603
      /* Check if the response with this reqSeqNum has been seen */
2604
0
      if (pinfo->num == p_tcaphash_ansicall->context->last_frame) {
2605
        /* We have seen this response before -> do nothing */
2606
#ifdef DEBUG_TCAPSRT
2607
        dbg(22,"Response already seen ");
2608
#endif
2609
0
        isResponse=true;
2610
0
        p_tcaphash_context=p_tcaphash_ansicall->context;
2611
0
        break;
2612
0
      }
2613
2614
      /* Check for the first Request without Response
2615
       received before this frame */
2616
0
      if ( pinfo->num > p_tcaphash_ansicall->context->first_frame &&
2617
0
           p_tcaphash_ansicall->context->last_frame==0 ) {
2618
        /* Take it, and update the context */
2619
2620
#ifdef DEBUG_TCAPSRT
2621
        dbg(12,"Update key %lx ",tcaphash_ansi_key.hashKey);
2622
#endif
2623
0
        p_tcaphash_ansicall->context->last_frame = pinfo->num;
2624
0
        p_tcaphash_ansicall->context->responded = true;
2625
0
        p_tcaphash_ansicall->context->closed = true;
2626
0
        p_tcaphash_context=p_tcaphash_ansicall->context;
2627
0
        isResponse=true;
2628
2629
0
        if (gtcap_DisplaySRT && tree) {
2630
0
          stat_tree = proto_tree_add_subtree(tree, tvb, 0, -1, ett_tcap_stat, &stat_item, "Stat");
2631
0
          proto_item_set_generated(stat_item);
2632
2633
0
          pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
2634
0
          proto_item_set_generated(pi);
2635
2636
#ifdef DEBUG_TCAPSRT
2637
          dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
2638
#endif
2639
          /* Indicate the frame to which this is a reply. */
2640
0
          pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
2641
0
                                          p_tcaphash_context->first_frame,
2642
0
                                          "Begin of session in frame %u",
2643
0
                                          p_tcaphash_context->first_frame);
2644
0
          proto_item_set_generated(pi);
2645
          /* Calculate Service Response Time */
2646
0
          nstime_delta(&delta, &pinfo->abs_ts, &p_tcaphash_context->begin_time);
2647
2648
          /* display Service Response Time and make it filterable */
2649
0
          pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
2650
0
          proto_item_set_generated(pi);
2651
0
        }
2652
0
        break;
2653
0
      } /* Lastframe=0, so take it */
2654
2655
2656
      /* If the last record for Tcap transaction with identifier has been reached */
2657
0
      if (!p_tcaphash_ansicall->next_ansicall) {
2658
        /* check if we have to create a new record or not */
2659
        /* if last request has been responded (response number in known)
2660
           and this request appears after last response (has bigger frame number)
2661
           and last request occurred after the timeout for repetition,
2662
           or
2663
           if last request hasn't been responded (so number unknown)
2664
           and this request appears after last request (has bigger frame number)
2665
           and this request occurred after the timeout for message lost */
2666
0
        if ( ( p_tcaphash_ansicall->context->last_frame != 0
2667
0
               && pinfo->num > p_tcaphash_ansicall->context->first_frame
2668
0
               && (unsigned) pinfo->abs_ts.secs > (unsigned)(p_tcaphash_ansicall->context->begin_time.secs + gtcap_RepetitionTimeout)
2669
0
               ) ||
2670
0
             ( p_tcaphash_ansicall->context->last_frame == 0
2671
0
               && pinfo->num > p_tcaphash_ansicall->context->first_frame
2672
0
               && (unsigned)pinfo->abs_ts.secs > (unsigned)(p_tcaphash_ansicall->context->begin_time.secs + gtcap_LostTimeout)
2673
0
               )
2674
0
             )
2675
0
          {
2676
            /* we decide that we have a new request */
2677
            /* Append new record to the list */
2678
#ifdef DEBUG_TCAPSRT
2679
            dbg(12,"(timeout) Append key %lx ",tcaphash_ansi_key.hashKey);
2680
            dbg(12,"Frame %u rsp %u ",pinfo->num,p_tcaphash_ansicall->context->last_frame );
2681
#endif
2682
0
            tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
2683
0
            p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
2684
0
            p_new_tcaphash_ansicall = append_tcaphash_ansicall(p_tcaphash_ansicall,
2685
0
                                                                 p_tcaphash_context,
2686
0
                                                                 pinfo);
2687
2688
#ifdef DEBUG_TCAPSRT
2689
            dbg(12,"Update key %lx ",tcaphash_ansi_key.hashKey);
2690
#endif
2691
0
            update_tcaphash_ansicall(p_new_tcaphash_ansicall, pinfo);
2692
0
            p_tcaphash_ansicall=p_new_tcaphash_ansicall;
2693
0
          } else {
2694
2695
          /* If the Tid is reused for a closed Transaction */
2696
0
          if ( p_tcaphash_ansicall->context->closed) {
2697
#ifdef DEBUG_TCAPSRT
2698
            dbg(12,"(closed) Append key %lu ",tcaphash_ansi_key.hashKey);
2699
            dbg(12,"Frame %u rsp %u ",pinfo->num,p_tcaphash_ansicall->context->last_frame );
2700
#endif
2701
0
            tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
2702
0
            p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
2703
0
            p_new_tcaphash_ansicall = append_tcaphash_ansicall(p_tcaphash_ansicall,
2704
0
                                                                 p_tcaphash_context,
2705
0
                                                                 pinfo);
2706
2707
#ifdef DEBUG_TCAPSRT
2708
            dbg(12,"Update key %lu ",tcaphash_ansi_key.hashKey);
2709
#endif
2710
0
            update_tcaphash_ansicall(p_new_tcaphash_ansicall, pinfo);
2711
0
            p_tcaphash_ansicall=p_new_tcaphash_ansicall;
2712
2713
0
          } else {
2714
            /* the Tid is reused for an opened Transaction */
2715
            /* so, this is the reply to the request of our context */
2716
0
            p_tcaphash_context=p_tcaphash_ansicall->context;
2717
#ifdef DEBUG_TCAPSRT
2718
            dbg(12,"Found, req=%d ",p_tcaphash_context->first_frame);
2719
#endif
2720
2721
0
            if (gtcap_DisplaySRT && tree) {
2722
0
              stat_tree = proto_tree_add_subtree(tree, tvb, 0, -1, ett_tcap_stat, &stat_item, "Stat");
2723
0
              proto_item_set_generated(stat_item);
2724
2725
0
              pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
2726
0
              proto_item_set_generated(pi);
2727
2728
#ifdef DEBUG_TCAPSRT
2729
              dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
2730
#endif
2731
              /* Indicate the frame to which this is a reply. */
2732
0
              pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
2733
0
                                              p_tcaphash_context->first_frame,
2734
0
                                              "Begin of session in frame %u",
2735
0
                                              p_tcaphash_context->first_frame);
2736
0
              proto_item_set_generated(pi);
2737
              /* Calculate Service Response Time */
2738
0
              nstime_delta(&delta, &pinfo->abs_ts, &p_tcaphash_context->begin_time);
2739
2740
              /* display Service Response Time and make it filterable */
2741
0
              pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
2742
0
              proto_item_set_generated(pi);
2743
0
            }
2744
0
            p_tcaphash_context=p_tcaphash_ansicall->context;
2745
0
          } /* test with Timeout */
2746
0
        } /* closed */
2747
0
        break;
2748
0
      } /* Next call is NULL */
2749
0
      p_tcaphash_ansicall = p_tcaphash_ansicall->next_ansicall;
2750
0
    } while (p_tcaphash_ansicall != NULL );
2751
    /*
2752
     * New TCAP context
2753
     */
2754
0
  } else { /* p_tcaphash_ansicall has not been found */
2755
#ifdef DEBUG_TCAPSRT
2756
    dbg(10,"New key %lx ",tcaphash_ansi_key.hashKey);
2757
#endif
2758
2759
0
    tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
2760
0
    p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
2761
0
    p_tcaphash_ansicall = new_tcaphash_ansi(&tcaphash_ansi_key, p_tcaphash_context);
2762
2763
#ifdef DEBUG_TCAPSRT
2764
    dbg(11,"Update key %lx ",tcaphash_ansi_key.hashKey);
2765
    dbg(11,"Frame reqlink #%u ", pinfo->num);
2766
#endif
2767
0
    update_tcaphash_ansicall(p_tcaphash_ansicall, pinfo);
2768
0
  }
2769
2770
  /* display tcap session, if available */
2771
0
  if ( gtcap_DisplaySRT && tree &&
2772
0
       p_tcaphash_context &&
2773
0
       p_tcaphash_context->session_id) {
2774
0
    stat_tree = proto_tree_add_subtree(tree, tvb, 0, -1, ett_tcap_stat, &stat_item, "Stat");
2775
0
    proto_item_set_generated(stat_item);
2776
0
    pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
2777
0
    proto_item_set_generated(pi);
2778
0
  }
2779
2780
2781
  /* add link to response frame, if available */
2782
0
  if( gtcap_DisplaySRT && stat_tree &&
2783
0
      p_tcaphash_ansicall->context->last_frame != 0){
2784
0
    if (!isResponse) { /* Request */
2785
#ifdef DEBUG_TCAPSRT
2786
      dbg(20,"Display_frameRsplink %d ",p_tcaphash_ansicall->context->last_frame);
2787
#endif
2788
0
      pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_BeginSession, tvb, 0, 0,
2789
0
                                      p_tcaphash_ansicall->context->last_frame,
2790
0
                                      "End of session in frame %u",
2791
0
                                      p_tcaphash_ansicall->context->last_frame);
2792
0
      proto_item_set_generated(pi);
2793
0
    } else { /* Response */
2794
#ifdef DEBUG_TCAPSRT
2795
      dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
2796
#endif
2797
      /* Indicate the frame to which this is a reply. */
2798
0
      if (gtcap_DisplaySRT) {
2799
0
        pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
2800
0
                                        p_tcaphash_context->first_frame,
2801
0
                                        "Begin of session in frame %u",
2802
0
                                        p_tcaphash_context->first_frame);
2803
0
        proto_item_set_generated(pi);
2804
        /* Calculate Service Response Time */
2805
0
        nstime_delta(&delta, &pinfo->abs_ts, &p_tcaphash_context->begin_time);
2806
2807
        /* display Service Response Time and make it filterable */
2808
0
        pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
2809
0
        proto_item_set_generated(pi);
2810
0
      }
2811
0
    } /* Request or Response */
2812
0
  }
2813
0
  return p_tcaphash_context;
2814
0
}
2815
2816
/*
2817
 * Service Response Time analyze
2818
 * Called just after dissector call
2819
 * Associate a TCAP context to a tcap session and display session related infomations
2820
 * like the first frame, the last, the session duration,
2821
 * and a uniq session identifier for the filtering
2822
 *
2823
 * For ETSI tcap, the TCAP context can be reached through three keys
2824
 * - a key (BEGIN) identifying the session according to the tcap source identifier
2825
 * - a key (CONT) identifying the established session (src_id and dst_id)
2826
 * - a key (END) identifying the session according to the tcap destination identifier
2827
 *
2828
 * For ANSI tcap, the TCAP context is reached through a uniq key
2829
 * - a key (ANSI) identifying the session according to the tcap identifier
2830
*/
2831
struct tcaphash_context_t *
2832
tcapsrt_call_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2833
                      struct tcapsrt_info_t *p_tcapsrt_info)
2834
24
{
2835
24
  struct tcaphash_context_t *tcap_context=NULL;
2836
2837
  /* if this packet isn't loaded because of a read filter, don't output anything */
2838
24
  if(pinfo == NULL || pinfo->num == 0) {
2839
0
    return NULL;
2840
0
  }
2841
2842
24
  switch (p_tcapsrt_info->ope) {
2843
2844
0
  case TC_BEGIN:
2845
#ifdef DEBUG_TCAPSRT
2846
    dbg(1,"\nTC_BEGIN ");
2847
#endif
2848
0
    tcap_context=tcaphash_begin_matching(tvb, pinfo, tree, p_tcapsrt_info);
2849
0
    break;
2850
2851
0
  case TC_CONT:
2852
#ifdef DEBUG_TCAPSRT
2853
    dbg(1,"\nTC_CONT ");
2854
#endif
2855
0
    tcap_context=tcaphash_cont_matching(tvb, pinfo, tree, p_tcapsrt_info);
2856
0
    break;
2857
2858
0
  case TC_ABORT:
2859
#ifdef DEBUG_TCAPSRT
2860
    dbg(1,"\nTC_ABORT ");
2861
#endif
2862
0
    tcap_context=tcaphash_end_matching(tvb, pinfo, tree, p_tcapsrt_info);
2863
0
    break;
2864
2865
0
  case TC_END:
2866
#ifdef DEBUG_TCAPSRT
2867
    dbg(1,"\nTC_END ");
2868
#endif
2869
0
    tcap_context=tcaphash_end_matching(tvb, pinfo, tree, p_tcapsrt_info);
2870
0
    break;
2871
2872
0
  case TC_ANSI_ALL:
2873
0
  case TC_ANSI_ABORT:
2874
#ifdef DEBUG_TCAPSRT
2875
    dbg(1,"\nTC_ANSI ");
2876
#endif
2877
0
    tcap_context=tcaphash_ansi_matching(tvb, pinfo, tree, p_tcapsrt_info);
2878
0
    break;
2879
2880
24
  default:
2881
#ifdef DEBUG_TCAPSRT
2882
    dbg(1,"\nUnknown %d ", p_tcapsrt_info->ope);
2883
#endif
2884
24
    break;
2885
24
  } /* switch tcapop */
2886
#ifdef DEBUG_TCAPSRT
2887
  if (tcap_context)
2888
    dbg(1,"session %d ", tcap_context->session_id);
2889
#endif
2890
24
  return tcap_context;
2891
24
}
2892
2893
/*
2894
 * Initialize the Message Info used by the main dissector
2895
 * Data are linked to a TCAP transaction
2896
 */
2897
struct tcapsrt_info_t *
2898
tcapsrt_razinfo(void)
2899
27
{
2900
27
  struct tcapsrt_info_t *p_tcapsrt_info ;
2901
2902
  /* Global buffer for packet extraction */
2903
27
  tcapsrt_global_current++;
2904
27
  if(tcapsrt_global_current==MAX_TCAP_INSTANCE){
2905
2
    tcapsrt_global_current=0;
2906
2
  }
2907
2908
27
  p_tcapsrt_info=&tcapsrt_global_info[tcapsrt_global_current];
2909
27
  memset(p_tcapsrt_info,0,sizeof(struct tcapsrt_info_t));
2910
2911
27
  return p_tcapsrt_info;
2912
27
}
2913
2914
void
2915
tcapsrt_close(struct tcaphash_context_t *p_tcaphash_context,
2916
              packet_info *pinfo)
2917
0
{
2918
#ifdef DEBUG_TCAPSRT
2919
  dbg(60,"Force close ");
2920
#endif
2921
0
  if (p_tcaphash_context) {
2922
0
    p_tcaphash_context->responded=true;
2923
0
    p_tcaphash_context->last_frame = pinfo->num;
2924
0
    p_tcaphash_context->end_time = pinfo->abs_ts;
2925
0
    p_tcaphash_context->closed=true;
2926
2927
    /* If the endkey is present */
2928
0
    if (p_tcaphash_context->endcall
2929
0
        && !gtcap_PersistentSRT) {
2930
0
      if (p_tcaphash_context->endcall->next_endcall) {
2931
0
        if (p_tcaphash_context->endcall->previous_endcall ) {
2932
#ifdef DEBUG_TCAPSRT
2933
          dbg(20,"deplace Ehash ");
2934
#endif
2935
0
          p_tcaphash_context->endcall->previous_endcall->next_endcall
2936
0
            = p_tcaphash_context->endcall->next_endcall;
2937
0
          p_tcaphash_context->endcall->next_endcall->previous_endcall
2938
0
            = p_tcaphash_context->endcall->previous_endcall;
2939
0
          wmem_map_remove(tcaphash_end, p_tcaphash_context->endcall->endkey);
2940
0
        } else {
2941
          /* cannot remove the father */
2942
#ifdef DEBUG_TCAPSRT
2943
          dbg(20,"father Ehash ");
2944
#endif
2945
0
        } /* no previous link, so father */
2946
0
      } else if (!gtcap_PersistentSRT) {
2947
#ifdef DEBUG_TCAPSRT
2948
        dbg(20,"remove Ehash ");
2949
#endif
2950
0
        wmem_map_remove(tcaphash_end, p_tcaphash_context->endcall->endkey);
2951
2952
0
      } /* endcall without chained string */
2953
0
    } /* no endcall */
2954
2955
2956
    /* If the contkey is present */
2957
0
    if (p_tcaphash_context->contcall
2958
0
        && !gtcap_PersistentSRT) {
2959
0
      if (p_tcaphash_context->contcall->next_contcall) {
2960
0
        if (p_tcaphash_context->contcall->previous_contcall ) {
2961
#ifdef DEBUG_TCAPSRT
2962
          dbg(20,"deplace Chash ");
2963
#endif
2964
0
          p_tcaphash_context->contcall->previous_contcall->next_contcall
2965
0
            = p_tcaphash_context->contcall->next_contcall;
2966
0
          p_tcaphash_context->contcall->next_contcall->previous_contcall
2967
0
            = p_tcaphash_context->contcall->previous_contcall;
2968
0
          wmem_map_remove(tcaphash_cont, p_tcaphash_context->contcall->contkey);
2969
0
        } else {
2970
          /* cannot remove the father */
2971
#ifdef DEBUG_TCAPSRT
2972
          dbg(20,"father Chash ");
2973
#endif
2974
0
        } /* no previous link, so father */
2975
0
      } else if (!gtcap_PersistentSRT) {
2976
#ifdef DEBUG_TCAPSRT
2977
        dbg(20,"remove Chash ");
2978
#endif
2979
0
        wmem_map_remove(tcaphash_cont, p_tcaphash_context->contcall->contkey);
2980
0
      } /* contcall without chained string */
2981
0
    } /* no contcall */
2982
2983
2984
    /* If the beginkey is present */
2985
0
    if (p_tcaphash_context->begincall
2986
0
        && !gtcap_PersistentSRT) {
2987
0
      if (p_tcaphash_context->begincall->next_begincall) {
2988
0
        if (p_tcaphash_context->begincall->previous_begincall ) {
2989
#ifdef DEBUG_TCAPSRT
2990
          dbg(20,"deplace Bhash ");
2991
#endif
2992
0
          p_tcaphash_context->begincall->previous_begincall->next_begincall
2993
0
            = p_tcaphash_context->begincall->next_begincall;
2994
0
          p_tcaphash_context->begincall->next_begincall->previous_begincall
2995
0
            = p_tcaphash_context->begincall->previous_begincall;
2996
0
          wmem_map_remove(tcaphash_begin, p_tcaphash_context->begincall->beginkey);
2997
0
        } else {
2998
          /* cannot remove the father */
2999
#ifdef DEBUG_TCAPSRT
3000
          dbg(20,"father Bhash ");
3001
#endif
3002
0
        }
3003
0
      } else  if (!gtcap_PersistentSRT) {
3004
#ifdef DEBUG_TCAPSRT
3005
        dbg(20,"remove Bhash ");
3006
#endif
3007
0
        wmem_map_remove(tcaphash_begin, p_tcaphash_context->begincall->beginkey);
3008
0
      } /* begincall without chained string */
3009
0
    } /* no begincall */
3010
3011
    /* If the ansikey is present */
3012
0
    if (p_tcaphash_context->ansicall
3013
0
        && !gtcap_PersistentSRT) {
3014
0
      if (p_tcaphash_context->ansicall->next_ansicall) {
3015
0
        if (p_tcaphash_context->ansicall->previous_ansicall ) {
3016
#ifdef DEBUG_TCAPSRT
3017
          dbg(20,"deplace Ahash ");
3018
#endif
3019
0
          p_tcaphash_context->ansicall->previous_ansicall->next_ansicall
3020
0
            = p_tcaphash_context->ansicall->next_ansicall;
3021
0
          p_tcaphash_context->ansicall->next_ansicall->previous_ansicall
3022
0
            = p_tcaphash_context->ansicall->previous_ansicall;
3023
0
          wmem_map_remove(tcaphash_ansi, p_tcaphash_context->ansicall->ansikey);
3024
0
        } else {
3025
          /* cannot remove the father */
3026
#ifdef DEBUG_TCAPSRT
3027
          dbg(20,"father Ahash ");
3028
#endif
3029
0
        }
3030
0
      } else  if (!gtcap_PersistentSRT) {
3031
#ifdef DEBUG_TCAPSRT
3032
        dbg(20,"remove Ahash ");
3033
#endif
3034
0
        wmem_map_remove(tcaphash_ansi, p_tcaphash_context->ansicall->ansikey);
3035
0
      } /* ansicall without chained string */
3036
0
    } /* no ansicall */
3037
3038
0
    if (!gtcap_PersistentSRT) {
3039
#ifdef DEBUG_TCAPSRT
3040
      dbg(20,"remove context ");
3041
#endif
3042
0
      wmem_map_remove(tcaphash_context, p_tcaphash_context->key);
3043
0
    }
3044
0
  } else { /* no context */
3045
#ifdef DEBUG_TCAPSRT
3046
    dbg(20,"No context to remove ");
3047
#endif
3048
0
  }
3049
0
}
3050
3051
const value_string tcap_component_type_str[] = {
3052
  { TCAP_COMP_INVOKE, "Invoke" },
3053
  { TCAP_COMP_RRL,    "Return Result(L)" },
3054
  { TCAP_COMP_RE,     "Return Error" },
3055
  { TCAP_COMP_REJECT, "Reject" },
3056
  { TCAP_COMP_RRN,    "Return Result(NL)" },
3057
  { 0,                NULL }
3058
};
3059
3060
static int
3061
dissect_tcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data _U_)
3062
29
{
3063
29
  proto_item *item=NULL;
3064
29
  proto_tree *tree=NULL;
3065
3066
29
  struct tcaphash_context_t * p_tcap_context;
3067
29
  dissector_handle_t subdissector_handle;
3068
29
  asn1_ctx_t asn1_ctx;
3069
29
  int8_t ber_class;
3070
29
  bool pc;
3071
29
  int tag;
3072
29
  struct tcap_private_t *p_tcap_private;
3073
3074
  /* Check if ANSI TCAP and call the ANSI TCAP dissector if that's the case
3075
   * PackageType ::= CHOICE { unidirectional            [PRIVATE 1] IMPLICIT UniTransactionPDU,
3076
   *                          queryWithPerm             [PRIVATE 2] IMPLICIT TransactionPDU,
3077
   *                          queryWithoutPerm          [PRIVATE 3] IMPLICIT TransactionPDU,
3078
   *                          response                  [PRIVATE 4] IMPLICIT TransactionPDU,
3079
   *                          conversationWithPerm      [PRIVATE 5] IMPLICIT TransactionPDU,
3080
   *                          conversationWithoutPerm   [PRIVATE 6] IMPLICIT TransactionPDU,
3081
   *                          abort                     [PRIVATE 22] IMPLICIT Abort
3082
   *                          }
3083
   *
3084
   *
3085
   */
3086
29
  get_ber_identifier(tvb, 0, &ber_class, &pc, &tag);
3087
3088
29
  if(ber_class == BER_CLASS_PRI){
3089
2
    switch (tag){
3090
3091
0
    case 1:
3092
0
    case 2:
3093
0
    case 3:
3094
0
    case 4:
3095
0
    case 5:
3096
0
    case 6:
3097
0
    case 22:
3098
0
      return call_dissector(ansi_tcap_handle, tvb, pinfo, parent_tree);
3099
3100
2
    default:
3101
2
      return tvb_captured_length(tvb);
3102
2
    }
3103
2
  }
3104
3105
  /* ITU TCAP */
3106
27
  asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, true, pinfo);
3107
3108
27
  tcap_top_tree = parent_tree;
3109
27
  tcap_stat_tree = NULL;
3110
3111
27
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCAP");
3112
3113
  /* create display subtree for the protocol */
3114
27
  if(parent_tree){
3115
27
    item = proto_tree_add_item(parent_tree, proto_tcap, tvb, 0, -1, ENC_NA);
3116
27
    tree = proto_item_add_subtree(item, ett_tcap);
3117
27
    tcap_stat_tree=tree;
3118
27
  }
3119
27
  cur_oid = NULL;
3120
27
  tcapext_oid = NULL;
3121
3122
27
  p_tcap_private = wmem_new0(pinfo->pool, struct tcap_private_t);
3123
27
  asn1_ctx.value_ptr = p_tcap_private;
3124
27
  gp_tcapsrt_info=tcapsrt_razinfo();
3125
27
  tcap_subdissector_used=false;
3126
27
  gp_tcap_context=NULL;
3127
27
  dissect_tcap_TCMessage(false, tvb, 0, &asn1_ctx, tree, -1);
3128
3129
27
  if (!tcap_subdissector_used ) {
3130
24
    p_tcap_context=tcapsrt_call_matching(tvb, pinfo, tcap_stat_tree, gp_tcapsrt_info);
3131
24
    p_tcap_private->context=p_tcap_context;
3132
3133
    /* If the current message is TCAP only,
3134
     * save the Application Context Name for the next messages
3135
     */
3136
24
    if ( p_tcap_context && cur_oid && !p_tcap_context->oid_present ) {
3137
      /* Save the application context and the sub dissector */
3138
0
      (void) g_strlcpy(p_tcap_context->oid, cur_oid, sizeof(p_tcap_context->oid));
3139
0
      p_tcap_context->oid_present=true;
3140
0
      if ( (subdissector_handle = dissector_get_string_handle(ber_oid_dissector_table, cur_oid)) ) {
3141
0
        p_tcap_context->subdissector_handle=subdissector_handle;
3142
0
        p_tcap_context->subdissector_present=true;
3143
0
      }
3144
0
    }
3145
24
    if (p_tcap_context && p_tcap_context->callback) {
3146
      /* Callback function for the upper layer */
3147
0
      (p_tcap_context->callback)(tvb, pinfo, tcap_stat_tree, p_tcap_context);
3148
0
    }
3149
24
  }
3150
27
  return tvb_captured_length(tvb);
3151
29
}
3152
3153
void
3154
proto_reg_handoff_tcap(void)
3155
14
{
3156
3157
14
  data_handle = find_dissector("data");
3158
14
  ansi_tcap_handle = find_dissector_add_dependency("ansi_tcap", proto_tcap);
3159
14
  ber_oid_dissector_table = find_dissector_table("ber.oid");
3160
3161
14
  ss7pc_address_type = address_type_get_by_name("AT_SS7PC");
3162
3163
14
  register_ber_oid_dissector("0.0.17.773.1.1.1", dissect_DialoguePDU_PDU, proto_tcap, "id-as-dialogue");
3164
14
  register_ber_oid_dissector("0.0.17.773.1.2.1", dissect_UniDialoguePDU_PDU, proto_tcap, "id-as-uniDialogue");
3165
3166
14
}
3167
3168
static void init_tcap(void);
3169
static void cleanup_tcap(void);
3170
3171
void
3172
proto_register_tcap(void)
3173
14
{
3174
3175
/* Setup list of header fields  See Section 1.6.1 for details*/
3176
14
  static hf_register_info hf[] = {
3177
14
    { &hf_tcap_tag,
3178
14
      { "Tag",
3179
14
        "tcap.msgtype",
3180
14
        FT_UINT8, BASE_HEX, NULL, 0,
3181
14
        NULL, HFILL }
3182
14
    },
3183
14
    { &hf_tcap_length,
3184
14
      { "Length",
3185
14
        "tcap.len",
3186
14
        FT_UINT8, BASE_DEC, NULL, 0,
3187
14
        NULL, HFILL }
3188
14
    },
3189
14
    { &hf_tcap_data,
3190
14
      { "Data",
3191
14
        "tcap.data",
3192
14
        FT_BYTES, BASE_NONE, NULL, 0,
3193
14
        NULL, HFILL }
3194
14
    },
3195
14
    { &hf_tcap_tid,
3196
14
      { "Transaction Id",
3197
14
         "tcap.tid",
3198
14
        FT_BYTES, BASE_NONE, NULL, 0,
3199
14
        NULL, HFILL }
3200
14
    },
3201
14
    { &hf_tcap_constructor_eoc,
3202
14
      { "CONSTRUCTOR EOC",
3203
14
         "tcap.constructor_eoc",
3204
14
        FT_UINT16, BASE_HEX, NULL, 0,
3205
14
        NULL, HFILL }
3206
14
    },
3207
    /* Tcap Service Response Time */
3208
14
    { &hf_tcapsrt_SessionId,
3209
14
      { "Session Id",
3210
14
        "tcap.srt.session_id",
3211
14
        FT_UINT32, BASE_DEC, NULL, 0x0,
3212
14
        NULL, HFILL }
3213
14
    },
3214
14
    { &hf_tcapsrt_BeginSession,
3215
14
      { "Begin Session",
3216
14
        "tcap.srt.begin",
3217
14
        FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3218
14
        "SRT Begin of Session", HFILL }
3219
14
    },
3220
14
    { &hf_tcapsrt_EndSession,
3221
14
      { "End Session",
3222
14
        "tcap.srt.end",
3223
14
        FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3224
14
        "SRT End of Session", HFILL }
3225
14
    },
3226
14
    { &hf_tcapsrt_SessionTime,
3227
14
      { "Session duration",
3228
14
        "tcap.srt.sessiontime",
3229
14
        FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
3230
14
        "Duration of the TCAP session", HFILL }
3231
14
    },
3232
14
    { &hf_tcapsrt_Duplicate,
3233
14
      { "Session Duplicate",
3234
14
        "tcap.srt.duplicate",
3235
14
        FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3236
14
        "SRT Duplicated with Session", HFILL }
3237
14
    },
3238
14
    { &hf_tcap_UniDialoguePDU_PDU,
3239
14
      { "UniDialoguePDU", "tcap.UniDialoguePDU",
3240
14
        FT_UINT32, BASE_DEC, VALS(tcap_UniDialoguePDU_vals), 0,
3241
14
        NULL, HFILL }},
3242
14
    { &hf_tcap_DialoguePDU_PDU,
3243
14
      { "DialoguePDU", "tcap.DialoguePDU",
3244
14
        FT_UINT32, BASE_DEC, VALS(tcap_DialoguePDU_vals), 0,
3245
14
        NULL, HFILL }},
3246
14
    { &hf_tcap_oid,
3247
14
      { "oid", "tcap.oid",
3248
14
        FT_OID, BASE_NONE, NULL, 0,
3249
14
        "OBJECT_IDENTIFIER", HFILL }},
3250
14
    { &hf_tcap_dialog,
3251
14
      { "dialog", "tcap.dialog",
3252
14
        FT_BYTES, BASE_NONE, NULL, 0,
3253
14
        "Dialog1", HFILL }},
3254
14
    { &hf_tcap_unidirectional,
3255
14
      { "unidirectional", "tcap.unidirectional_element",
3256
14
        FT_NONE, BASE_NONE, NULL, 0,
3257
14
        NULL, HFILL }},
3258
14
    { &hf_tcap_begin,
3259
14
      { "begin", "tcap.begin_element",
3260
14
        FT_NONE, BASE_NONE, NULL, 0,
3261
14
        NULL, HFILL }},
3262
14
    { &hf_tcap_end,
3263
14
      { "end", "tcap.end_element",
3264
14
        FT_NONE, BASE_NONE, NULL, 0,
3265
14
        NULL, HFILL }},
3266
14
    { &hf_tcap_continue,
3267
14
      { "continue", "tcap.continue_element",
3268
14
        FT_NONE, BASE_NONE, NULL, 0,
3269
14
        NULL, HFILL }},
3270
14
    { &hf_tcap_abort,
3271
14
      { "abort", "tcap.abort_element",
3272
14
        FT_NONE, BASE_NONE, NULL, 0,
3273
14
        NULL, HFILL }},
3274
14
    { &hf_tcap_dialoguePortion,
3275
14
      { "dialoguePortion", "tcap.dialoguePortion",
3276
14
        FT_BYTES, BASE_NONE, NULL, 0,
3277
14
        NULL, HFILL }},
3278
14
    { &hf_tcap_components,
3279
14
      { "components", "tcap.components",
3280
14
        FT_UINT32, BASE_DEC, NULL, 0,
3281
14
        "ComponentPortion", HFILL }},
3282
14
    { &hf_tcap_otid,
3283
14
      { "otid", "tcap.otid",
3284
14
        FT_BYTES, BASE_NONE, NULL, 0,
3285
14
        "OrigTransactionID", HFILL }},
3286
14
    { &hf_tcap_dtid,
3287
14
      { "dtid", "tcap.dtid",
3288
14
        FT_BYTES, BASE_NONE, NULL, 0,
3289
14
        "DestTransactionID", HFILL }},
3290
14
    { &hf_tcap_reason,
3291
14
      { "reason", "tcap.reason",
3292
14
        FT_UINT32, BASE_DEC, VALS(tcap_Reason_vals), 0,
3293
14
        NULL, HFILL }},
3294
14
    { &hf_tcap_p_abortCause,
3295
14
      { "p-abortCause", "tcap.p_abortCause",
3296
14
        FT_UINT32, BASE_DEC, VALS(tcap_P_AbortCause_U_vals), 0,
3297
14
        NULL, HFILL }},
3298
14
    { &hf_tcap_u_abortCause,
3299
14
      { "u-abortCause", "tcap.u_abortCause",
3300
14
        FT_BYTES, BASE_NONE, NULL, 0,
3301
14
        "DialoguePortion", HFILL }},
3302
14
    { &hf_tcap__untag_item,
3303
14
      { "Component", "tcap.Component",
3304
14
        FT_UINT32, BASE_DEC, VALS(tcap_Component_vals), 0,
3305
14
        NULL, HFILL }},
3306
14
    { &hf_tcap_invoke,
3307
14
      { "invoke", "tcap.invoke_element",
3308
14
        FT_NONE, BASE_NONE, NULL, 0,
3309
14
        NULL, HFILL }},
3310
14
    { &hf_tcap_returnResultLast,
3311
14
      { "returnResultLast", "tcap.returnResultLast_element",
3312
14
        FT_NONE, BASE_NONE, NULL, 0,
3313
14
        "ReturnResult", HFILL }},
3314
14
    { &hf_tcap_returnError,
3315
14
      { "returnError", "tcap.returnError_element",
3316
14
        FT_NONE, BASE_NONE, NULL, 0,
3317
14
        NULL, HFILL }},
3318
14
    { &hf_tcap_reject,
3319
14
      { "reject", "tcap.reject_element",
3320
14
        FT_NONE, BASE_NONE, NULL, 0,
3321
14
        NULL, HFILL }},
3322
14
    { &hf_tcap_returnResultNotLast,
3323
14
      { "returnResultNotLast", "tcap.returnResultNotLast_element",
3324
14
        FT_NONE, BASE_NONE, NULL, 0,
3325
14
        "ReturnResult", HFILL }},
3326
14
    { &hf_tcap_invokeID,
3327
14
      { "invokeID", "tcap.invokeID",
3328
14
        FT_INT32, BASE_DEC, NULL, 0,
3329
14
        "InvokeIdType", HFILL }},
3330
14
    { &hf_tcap_linkedID,
3331
14
      { "linkedID", "tcap.linkedID",
3332
14
        FT_INT32, BASE_DEC, NULL, 0,
3333
14
        "InvokeIdType", HFILL }},
3334
14
    { &hf_tcap_opCode,
3335
14
      { "opCode", "tcap.opCode",
3336
14
        FT_UINT32, BASE_DEC, VALS(tcap_OPERATION_vals), 0,
3337
14
        "OPERATION", HFILL }},
3338
14
    { &hf_tcap_parameter,
3339
14
      { "parameter", "tcap.parameter_element",
3340
14
        FT_NONE, BASE_NONE, NULL, 0,
3341
14
        NULL, HFILL }},
3342
14
    { &hf_tcap_resultretres,
3343
14
      { "resultretres", "tcap.resultretres_element",
3344
14
        FT_NONE, BASE_NONE, NULL, 0,
3345
14
        NULL, HFILL }},
3346
14
    { &hf_tcap_errorCode,
3347
14
      { "errorCode", "tcap.errorCode",
3348
14
        FT_UINT32, BASE_DEC, VALS(tcap_ErrorCode_vals), 0,
3349
14
        NULL, HFILL }},
3350
14
    { &hf_tcap_invokeIDRej,
3351
14
      { "invokeIDRej", "tcap.invokeIDRej",
3352
14
        FT_UINT32, BASE_DEC, VALS(tcap_T_invokeIDRej_vals), 0,
3353
14
        NULL, HFILL }},
3354
14
    { &hf_tcap_derivable,
3355
14
      { "derivable", "tcap.derivable",
3356
14
        FT_INT32, BASE_DEC, NULL, 0,
3357
14
        "InvokeIdType", HFILL }},
3358
14
    { &hf_tcap_not_derivable,
3359
14
      { "not-derivable", "tcap.not_derivable_element",
3360
14
        FT_NONE, BASE_NONE, NULL, 0,
3361
14
        NULL, HFILL }},
3362
14
    { &hf_tcap_problem,
3363
14
      { "problem", "tcap.problem",
3364
14
        FT_UINT32, BASE_DEC, VALS(tcap_T_problem_vals), 0,
3365
14
        NULL, HFILL }},
3366
14
    { &hf_tcap_generalProblem,
3367
14
      { "generalProblem", "tcap.generalProblem",
3368
14
        FT_INT32, BASE_DEC, VALS(tcap_GeneralProblem_vals), 0,
3369
14
        NULL, HFILL }},
3370
14
    { &hf_tcap_invokeProblem,
3371
14
      { "invokeProblem", "tcap.invokeProblem",
3372
14
        FT_INT32, BASE_DEC, VALS(tcap_InvokeProblem_vals), 0,
3373
14
        NULL, HFILL }},
3374
14
    { &hf_tcap_returnResultProblem,
3375
14
      { "returnResultProblem", "tcap.returnResultProblem",
3376
14
        FT_INT32, BASE_DEC, VALS(tcap_ReturnResultProblem_vals), 0,
3377
14
        NULL, HFILL }},
3378
14
    { &hf_tcap_returnErrorProblem,
3379
14
      { "returnErrorProblem", "tcap.returnErrorProblem",
3380
14
        FT_INT32, BASE_DEC, VALS(tcap_ReturnErrorProblem_vals), 0,
3381
14
        NULL, HFILL }},
3382
14
    { &hf_tcap_localValue,
3383
14
      { "localValue", "tcap.localValue",
3384
14
        FT_INT32, BASE_DEC, NULL, 0,
3385
14
        "INTEGER", HFILL }},
3386
14
    { &hf_tcap_globalValue,
3387
14
      { "globalValue", "tcap.globalValue",
3388
14
        FT_OID, BASE_NONE, NULL, 0,
3389
14
        "OBJECT_IDENTIFIER", HFILL }},
3390
14
    { &hf_tcap_nationaler,
3391
14
      { "nationaler", "tcap.nationaler",
3392
14
        FT_INT32, BASE_DEC, NULL, 0,
3393
14
        "INTEGER_M32768_32767", HFILL }},
3394
14
    { &hf_tcap_privateer,
3395
14
      { "privateer", "tcap.privateer",
3396
14
        FT_INT32, BASE_DEC, NULL, 0,
3397
14
        "INTEGER", HFILL }},
3398
14
    { &hf_tcap_unidialoguePDU,
3399
14
      { "unidialoguePDU", "tcap.unidialoguePDU_element",
3400
14
        FT_NONE, BASE_NONE, NULL, 0,
3401
14
        "AUDT_apdu", HFILL }},
3402
14
    { &hf_tcap_audt_protocol_version,
3403
14
      { "protocol-version", "tcap.audt_protocol_version",
3404
14
        FT_BYTES, BASE_NONE, NULL, 0,
3405
14
        "AUDT_protocol_version", HFILL }},
3406
14
    { &hf_tcap_audt_application_context_name,
3407
14
      { "application-context-name", "tcap.audt_application_context_name",
3408
14
        FT_OID, BASE_NONE, NULL, 0,
3409
14
        "AUDT_application_context_name", HFILL }},
3410
14
    { &hf_tcap_audt_user_information,
3411
14
      { "user-information", "tcap.audt_user_information",
3412
14
        FT_UINT32, BASE_DEC, NULL, 0,
3413
14
        "AUDT_user_information", HFILL }},
3414
14
    { &hf_tcap_audt_user_information_item,
3415
14
      { "user-information item", "tcap.audt_user_information_item_element",
3416
14
        FT_NONE, BASE_NONE, NULL, 0,
3417
14
        "EXTERNAL", HFILL }},
3418
14
    { &hf_tcap_dialogueRequest,
3419
14
      { "dialogueRequest", "tcap.dialogueRequest_element",
3420
14
        FT_NONE, BASE_NONE, NULL, 0,
3421
14
        "AARQ_apdu", HFILL }},
3422
14
    { &hf_tcap_dialogueResponse,
3423
14
      { "dialogueResponse", "tcap.dialogueResponse_element",
3424
14
        FT_NONE, BASE_NONE, NULL, 0,
3425
14
        "AARE_apdu", HFILL }},
3426
14
    { &hf_tcap_dialogueAbort,
3427
14
      { "dialogueAbort", "tcap.dialogueAbort_element",
3428
14
        FT_NONE, BASE_NONE, NULL, 0,
3429
14
        "ABRT_apdu", HFILL }},
3430
14
    { &hf_tcap_aarq_protocol_version,
3431
14
      { "protocol-version", "tcap.aarq_protocol_version",
3432
14
        FT_BYTES, BASE_NONE, NULL, 0,
3433
14
        "AARQ_protocol_version", HFILL }},
3434
14
    { &hf_tcap_aarq_application_context_name,
3435
14
      { "application-context-name", "tcap.aarq_application_context_name",
3436
14
        FT_OID, BASE_NONE, NULL, 0,
3437
14
        "AARQ_application_context_name", HFILL }},
3438
14
    { &hf_tcap_aarq_user_information,
3439
14
      { "user-information", "tcap.aarq_user_information",
3440
14
        FT_UINT32, BASE_DEC, NULL, 0,
3441
14
        "AARQ_user_information", HFILL }},
3442
14
    { &hf_tcap_aarq_user_information_item,
3443
14
      { "user-information item", "tcap.aarq_user_information_item_element",
3444
14
        FT_NONE, BASE_NONE, NULL, 0,
3445
14
        "EXTERNAL", HFILL }},
3446
14
    { &hf_tcap_aare_protocol_version,
3447
14
      { "protocol-version", "tcap.aare_protocol_version",
3448
14
        FT_BYTES, BASE_NONE, NULL, 0,
3449
14
        "AARE_protocol_version", HFILL }},
3450
14
    { &hf_tcap_aare_application_context_name,
3451
14
      { "application-context-name", "tcap.aare_application_context_name",
3452
14
        FT_OID, BASE_NONE, NULL, 0,
3453
14
        "AARE_application_context_name", HFILL }},
3454
14
    { &hf_tcap_result,
3455
14
      { "result", "tcap.result",
3456
14
        FT_INT32, BASE_DEC, VALS(tcap_Associate_result_vals), 0,
3457
14
        "Associate_result", HFILL }},
3458
14
    { &hf_tcap_result_source_diagnostic,
3459
14
      { "result-source-diagnostic", "tcap.result_source_diagnostic",
3460
14
        FT_UINT32, BASE_DEC, VALS(tcap_Associate_source_diagnostic_vals), 0,
3461
14
        "Associate_source_diagnostic", HFILL }},
3462
14
    { &hf_tcap_aare_user_information,
3463
14
      { "user-information", "tcap.aare_user_information",
3464
14
        FT_UINT32, BASE_DEC, NULL, 0,
3465
14
        "AARE_user_information", HFILL }},
3466
14
    { &hf_tcap_aare_user_information_item,
3467
14
      { "user-information item", "tcap.aare_user_information_item_element",
3468
14
        FT_NONE, BASE_NONE, NULL, 0,
3469
14
        "EXTERNAL", HFILL }},
3470
14
    { &hf_tcap_abort_source,
3471
14
      { "abort-source", "tcap.abort_source",
3472
14
        FT_INT32, BASE_DEC, VALS(tcap_ABRT_source_vals), 0,
3473
14
        "ABRT_source", HFILL }},
3474
14
    { &hf_tcap_abrt_user_information,
3475
14
      { "user-information", "tcap.abrt_user_information",
3476
14
        FT_UINT32, BASE_DEC, NULL, 0,
3477
14
        "ABRT_user_information", HFILL }},
3478
14
    { &hf_tcap_abrt_user_information_item,
3479
14
      { "user-information item", "tcap.abrt_user_information_item_element",
3480
14
        FT_NONE, BASE_NONE, NULL, 0,
3481
14
        "EXTERNAL", HFILL }},
3482
14
    { &hf_tcap_dialogue_service_user,
3483
14
      { "dialogue-service-user", "tcap.dialogue_service_user",
3484
14
        FT_INT32, BASE_DEC, VALS(tcap_T_dialogue_service_user_vals), 0,
3485
14
        NULL, HFILL }},
3486
14
    { &hf_tcap_dialogue_service_provider,
3487
14
      { "dialogue-service-provider", "tcap.dialogue_service_provider",
3488
14
        FT_INT32, BASE_DEC, VALS(tcap_T_dialogue_service_provider_vals), 0,
3489
14
        NULL, HFILL }},
3490
14
    { &hf_tcap_AUDT_protocol_version_version1,
3491
14
      { "version1", "tcap.AUDT.protocol.version.version1",
3492
14
        FT_BOOLEAN, 8, NULL, 0x80,
3493
14
        NULL, HFILL }},
3494
14
    { &hf_tcap_AARQ_protocol_version_version1,
3495
14
      { "version1", "tcap.AARQ.protocol.version.version1",
3496
14
        FT_BOOLEAN, 8, NULL, 0x80,
3497
14
        NULL, HFILL }},
3498
14
    { &hf_tcap_AARE_protocol_version_version1,
3499
14
      { "version1", "tcap.AARE.protocol.version.version1",
3500
14
        FT_BOOLEAN, 8, NULL, 0x80,
3501
14
        NULL, HFILL }},
3502
14
  };
3503
3504
/* Setup protocol subtree array */
3505
14
  static int *ett[] = {
3506
14
    &ett_tcap,
3507
14
    &ett_param,
3508
14
    &ett_otid,
3509
14
    &ett_dtid,
3510
14
    &ett_tcap_stat,
3511
14
    &ett_tcap_ExternalPDU_U,
3512
14
    &ett_tcap_TCMessage,
3513
14
    &ett_tcap_Unidirectional,
3514
14
    &ett_tcap_Begin,
3515
14
    &ett_tcap_End,
3516
14
    &ett_tcap_Continue,
3517
14
    &ett_tcap_Abort,
3518
14
    &ett_tcap_Reason,
3519
14
    &ett_tcap_SEQUENCE_SIZE_1_MAX_OF_Component,
3520
14
    &ett_tcap_Component,
3521
14
    &ett_tcap_Invoke,
3522
14
    &ett_tcap_ReturnResult,
3523
14
    &ett_tcap_T_resultretres,
3524
14
    &ett_tcap_ReturnError,
3525
14
    &ett_tcap_Reject,
3526
14
    &ett_tcap_T_invokeIDRej,
3527
14
    &ett_tcap_T_problem,
3528
14
    &ett_tcap_OPERATION,
3529
14
    &ett_tcap_ErrorCode,
3530
14
    &ett_tcap_UniDialoguePDU,
3531
14
    &ett_tcap_AUDT_apdu_U,
3532
14
    &ett_tcap_AUDT_protocol_version,
3533
14
    &ett_tcap_AUDT_user_information,
3534
14
    &ett_tcap_DialoguePDU,
3535
14
    &ett_tcap_AARQ_apdu_U,
3536
14
    &ett_tcap_AARQ_protocol_version,
3537
14
    &ett_tcap_AARQ_user_information,
3538
14
    &ett_tcap_AARE_apdu_U,
3539
14
    &ett_tcap_AARE_protocol_version,
3540
14
    &ett_tcap_AARE_user_information,
3541
14
    &ett_tcap_ABRT_apdu_U,
3542
14
    &ett_tcap_ABRT_user_information,
3543
14
    &ett_tcap_Associate_source_diagnostic,
3544
14
  };
3545
3546
  /*static enum_val_t tcap_options[] = {
3547
    { "itu", "ITU",  ITU_TCAP_STANDARD },
3548
    { "ansi", "ANSI", ANSI_TCAP_STANDARD },
3549
    { NULL, NULL, 0 }
3550
  };*/
3551
3552
14
  module_t *tcap_module;
3553
3554
/* Register the protocol name and description */
3555
14
  proto_tcap = proto_register_protocol(PNAME, PSNAME, PFNAME);
3556
3557
/* Required function calls to register the header fields and subtrees used */
3558
14
  proto_register_field_array(proto_tcap, hf, array_length(hf));
3559
14
  proto_register_subtree_array(ett, array_length(ett));
3560
3561
14
  ansi_sub_dissectors = register_dissector_table("ansi_tcap.ssn", "ANSI SSN", proto_tcap, FT_UINT8, BASE_DEC);
3562
14
  itu_sub_dissectors = register_dissector_table("itu_tcap.ssn", "ITU SSN", proto_tcap, FT_UINT8, BASE_DEC);
3563
3564
14
  tcap_module = prefs_register_protocol(proto_tcap, NULL);
3565
3566
#if 0
3567
  prefs_register_enum_preference(tcap_module, "standard", "ITU TCAP standard",
3568
                                 "The SS7 standard used in ITU TCAP packets",
3569
                                 &tcap_standard, tcap_options, false);
3570
#else
3571
14
  prefs_register_obsolete_preference(tcap_module, "standard");
3572
14
#endif
3573
3574
#if 0
3575
  prefs_register_bool_preference(tcap_module, "lock_info_col", "Lock Info column",
3576
                                 "Always show TCAP in Info column",
3577
                                 &lock_info_col);
3578
#else
3579
14
  prefs_register_obsolete_preference(tcap_module, "lock_info_col");
3580
14
#endif
3581
3582
  /* Set default SSNs */
3583
14
  range_convert_str(wmem_epan_scope(), &global_ssn_range, "", MAX_SSN);
3584
3585
14
  prefs_register_range_preference(tcap_module, "ssn", "SCCP SSNs",
3586
14
                                  "SCCP (and SUA) SSNs to decode as TCAP",
3587
14
                                  &global_ssn_range, MAX_SSN);
3588
3589
14
  prefs_register_obsolete_preference(tcap_module, "srt");
3590
3591
14
  prefs_register_bool_preference(tcap_module, "persistentsrt",
3592
14
                                 "Persistent stats for SRT",
3593
14
                                 "Statistics for Response Time",
3594
14
                                 &gtcap_PersistentSRT);
3595
3596
14
  prefs_register_uint_preference(tcap_module, "repetitiontimeout",
3597
14
                                 "Repetition timeout",
3598
14
                                 "Maximal delay for message repetition",
3599
14
                                 10, &gtcap_RepetitionTimeout);
3600
3601
14
  prefs_register_uint_preference(tcap_module, "losttimeout",
3602
14
                                 "Lost timeout",
3603
14
                                 "Maximal delay for message lost",
3604
14
                                 10, &gtcap_LostTimeout);
3605
3606
  /* 'globally' register dissector */
3607
14
  tcap_handle = register_dissector("tcap", dissect_tcap, proto_tcap);
3608
3609
  /* hash-tables for SRT */
3610
14
  tcaphash_context = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), tcaphash_context_calchash, tcaphash_context_equal);
3611
14
  tcaphash_begin   = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), tcaphash_begin_calchash, tcaphash_begin_equal);
3612
14
  tcaphash_cont    = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), tcaphash_cont_calchash, tcaphash_cont_equal);
3613
14
  tcaphash_end     = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), tcaphash_end_calchash, tcaphash_end_equal);
3614
14
  tcaphash_ansi    = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), tcaphash_ansi_calchash, tcaphash_ansi_equal);
3615
3616
14
  register_init_routine(&init_tcap);
3617
14
  register_cleanup_routine(&cleanup_tcap);
3618
14
}
3619
3620
3621
static void range_delete_callback(uint32_t ssn, void *ptr _U_)
3622
0
{
3623
0
  if ( ssn && !get_ansi_tcap_subdissector(ssn) && !get_itu_tcap_subdissector(ssn) ) {
3624
0
    dissector_delete_uint("sccp.ssn", ssn, tcap_handle);
3625
0
  }
3626
0
}
3627
3628
static void range_add_callback(uint32_t ssn, void *ptr _U_)
3629
0
{
3630
0
  if (ssn && !get_ansi_tcap_subdissector(ssn) && !get_itu_tcap_subdissector(ssn) ) {
3631
0
    dissector_add_uint("sccp.ssn", ssn, tcap_handle);
3632
0
  }
3633
0
}
3634
3635
3636
static void init_tcap(void)
3637
14
{
3638
14
  ssn_range = range_copy(wmem_epan_scope(), global_ssn_range);
3639
14
  range_foreach(ssn_range, range_add_callback, NULL);
3640
3641
  /* Reset the session counter */
3642
14
  tcapsrt_global_SessionId=1;
3643
3644
  /* Display of SRT is enabled
3645
   * 1) For wireshark only if Persistent Stat is enabled
3646
   * 2) For tshark, if the CLI SRT tap is registered
3647
   */
3648
14
  gtcap_DisplaySRT=gtcap_PersistentSRT || gtcap_StatSRT;
3649
14
}
3650
3651
static void cleanup_tcap(void)
3652
0
{
3653
0
  range_foreach(ssn_range, range_delete_callback, NULL);
3654
0
  wmem_free(wmem_epan_scope(), ssn_range);
3655
0
}
3656
3657
static int
3658
// NOLINTNEXTLINE(misc-no-recursion)
3659
dissect_tcap_param(asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset)
3660
0
{
3661
0
  int tag_offset, saved_offset, len_offset;
3662
0
  tvbuff_t *next_tvb;
3663
0
  proto_tree *subtree;
3664
0
  int8_t ber_class;
3665
0
  bool pc;
3666
0
  int32_t tag;
3667
0
  uint32_t len;
3668
0
  uint32_t tag_length;
3669
0
  uint32_t len_length;
3670
0
  bool ind_field;
3671
3672
0
  while (tvb_reported_length_remaining(tvb, offset) > 0)
3673
0
  {
3674
0
    saved_offset = offset;
3675
3676
0
    offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag);
3677
0
    tag_offset = offset;
3678
0
    offset = get_ber_length(tvb, offset, &len, &ind_field);
3679
0
    len_offset = offset;
3680
3681
0
    tag_length = tag_offset - saved_offset;
3682
0
    len_length = len_offset - tag_offset;
3683
3684
0
    if (pc)
3685
0
    {
3686
0
      subtree = proto_tree_add_subtree(tree, tvb, saved_offset,
3687
0
        len + (len_offset - saved_offset), ett_param, NULL,
3688
0
        "CONSTRUCTOR");
3689
0
      proto_tree_add_uint_format(subtree, hf_tcap_tag, tvb,
3690
0
        saved_offset, tag_length, tag,
3691
0
        "CONSTRUCTOR Tag");
3692
0
      proto_tree_add_uint(subtree, hf_tcap_tag, tvb, saved_offset,
3693
0
        tag_length, ber_class);
3694
3695
0
      proto_tree_add_uint(subtree, hf_tcap_length, tvb, tag_offset,
3696
0
        len_length, len);
3697
3698
0
      if (len - (ind_field ? 2 : 0)) /*should always be positive unless we get an empty constructor pointless? */
3699
0
      {
3700
0
        next_tvb = tvb_new_subset_length(tvb, offset, len - (ind_field ? 2 : 0));
3701
0
        increment_dissection_depth(actx->pinfo);
3702
0
        dissect_tcap_param(actx, subtree,next_tvb,0);
3703
0
        decrement_dissection_depth(actx->pinfo);
3704
0
      }
3705
3706
0
      if (ind_field)
3707
0
        proto_tree_add_item(subtree, hf_tcap_constructor_eoc, tvb, offset+len-2, 2, ENC_BIG_ENDIAN);
3708
3709
0
      offset += len;
3710
0
    }
3711
0
    else
3712
0
    {
3713
0
      subtree = proto_tree_add_subtree_format(tree, tvb, saved_offset,
3714
0
        len + (len_offset - saved_offset), ett_param, NULL,
3715
0
        "Parameter (0x%.2x)", tag);
3716
3717
0
      proto_tree_add_uint(subtree, hf_tcap_tag, tvb, saved_offset,
3718
0
        tag_length, tag);
3719
3720
0
      proto_tree_add_uint(subtree, hf_tcap_length, tvb,
3721
0
        saved_offset+tag_length, len_length, len);
3722
3723
0
      if (len) /* check for NULLS */
3724
0
      {
3725
0
        next_tvb = tvb_new_subset_length(tvb, offset, len);
3726
0
        dissect_ber_octet_string(true, actx, tree, next_tvb, 0,
3727
0
          hf_tcap_data, NULL);
3728
0
      }
3729
3730
0
      offset += len;
3731
0
    }
3732
0
  }
3733
0
  return offset;
3734
0
}
3735
3736
/*
3737
 * Call ITU Subdissector to decode the Tcap Component
3738
 */
3739
static bool
3740
dissect_tcap_ITU_ComponentPDU(bool implicit_tag _U_, tvbuff_t *tvb, int offset _U_, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_)
3741
0
{
3742
0
  dissector_handle_t subdissector_handle=NULL;
3743
0
  bool is_subdissector=false;
3744
0
  struct tcaphash_context_t * p_tcap_context=NULL;
3745
0
  struct tcap_private_t *p_tcap_private = (struct tcap_private_t*)actx->value_ptr;
3746
3747
  /*
3748
   * ok lets look at the oid and ssn and try and find a dissector, otherwise lets decode it.
3749
   */
3750
3751
  /*
3752
   * Handle The TCAP Service Response Time
3753
   */
3754
0
  if (!tcap_subdissector_used) {
3755
0
    p_tcap_context=tcapsrt_call_matching(tvb, actx->pinfo, tcap_stat_tree, gp_tcapsrt_info);
3756
0
    tcap_subdissector_used=false;
3757
0
    gp_tcap_context=p_tcap_context;
3758
0
    p_tcap_private->context=p_tcap_context;
3759
0
  } else {
3760
    /* Take the last TCAP context */
3761
0
    p_tcap_context = gp_tcap_context;
3762
0
    p_tcap_private->context=p_tcap_context;
3763
0
  }
3764
0
  if (p_tcap_context) {
3765
0
      if (cur_oid) {
3766
0
          if (p_tcap_context->oid_present) {
3767
              /* We have already an Application Context, check if we have
3768
                 to fallback to a lower version */
3769
0
              if (strncmp(p_tcap_context->oid, cur_oid, sizeof(p_tcap_context->oid)) != 0) {
3770
                  /* ACN, changed, Fallback to lower version
3771
                   * and update the subdissector (purely formal)
3772
                   */
3773
0
                  (void) g_strlcpy(p_tcap_context->oid, cur_oid, sizeof(p_tcap_context->oid));
3774
0
                  if ((subdissector_handle = dissector_get_string_handle(ber_oid_dissector_table, cur_oid))) {
3775
0
                      p_tcap_context->subdissector_handle = subdissector_handle;
3776
0
                      p_tcap_context->subdissector_present = true;
3777
0
                  }
3778
0
              }
3779
0
          } else {
3780
              /* We do not have the OID in the TCAP context, so store it */
3781
0
              (void) g_strlcpy(p_tcap_context->oid, cur_oid, sizeof(p_tcap_context->oid));
3782
0
              p_tcap_context->oid_present = true;
3783
              /* Try to find a subdissector according to OID */
3784
0
              if ((subdissector_handle
3785
0
                  = dissector_get_string_handle(ber_oid_dissector_table, cur_oid))) {
3786
0
                  p_tcap_context->subdissector_handle = subdissector_handle;
3787
0
                  p_tcap_context->subdissector_present = true;
3788
0
              } else {
3789
                  /* Not found, so try to find a subdissector according to SSN */
3790
0
                  if ((subdissector_handle = get_itu_tcap_subdissector(actx->pinfo->match_uint))) {
3791
                      /* Found according to SSN */
3792
0
                      p_tcap_context->subdissector_handle = subdissector_handle;
3793
0
                      p_tcap_context->subdissector_present = true;
3794
0
                  }
3795
0
              }
3796
0
          } /* context OID */
3797
0
      } else {
3798
          /* Copy the OID from the TCAP context to the current oid */
3799
0
          if (p_tcap_context->oid_present) {
3800
0
              p_tcap_private->oid = (void*)p_tcap_context->oid;
3801
0
              p_tcap_private->acv = true;
3802
0
          }
3803
0
      } /* no OID */
3804
0
  } /* no TCAP context */
3805
3806
3807
0
  if (p_tcap_context
3808
0
      && p_tcap_context->subdissector_present) {
3809
      /* Take the subdissector from the context */
3810
0
      subdissector_handle = p_tcap_context->subdissector_handle;
3811
0
      is_subdissector = true;
3812
0
  }
3813
3814
  /* Have SccpUsersTable protocol taking precedence over sccp.ssn table */
3815
0
  if (!is_subdissector && requested_subdissector_handle) {
3816
0
      is_subdissector = true;
3817
0
      subdissector_handle = requested_subdissector_handle;
3818
0
  }
3819
3820
0
  if (!is_subdissector) {
3821
      /*
3822
       * If we do not currently know the subdissector, we have to find it
3823
       * - first, according to the OID
3824
       * - then according to the SSN
3825
       * - and at least, take the default Data handler
3826
       */
3827
0
      if (ber_oid_dissector_table && cur_oid) {
3828
          /* Search if we can find the sub protocol according to the A.C.N */
3829
0
          if ((subdissector_handle
3830
0
              = dissector_get_string_handle(ber_oid_dissector_table, cur_oid))) {
3831
              /* found */
3832
0
              is_subdissector = true;
3833
0
          } else {
3834
              /* Search if we can found the sub protocol according to the SSN table */
3835
0
              if ((subdissector_handle
3836
0
                  = get_itu_tcap_subdissector(actx->pinfo->match_uint))) {
3837
                  /* Found according to SSN */
3838
0
                  is_subdissector = true;
3839
0
              } else {
3840
                  /* Nothing found, take the Data handler */
3841
0
                  subdissector_handle = data_handle;
3842
0
                  is_subdissector = true;
3843
0
              } /* SSN */
3844
0
          } /* ACN */
3845
0
      } else {
3846
          /* There is no A.C.N for this transaction, so search in the SSN table */
3847
0
          if ((subdissector_handle = get_itu_tcap_subdissector(actx->pinfo->match_uint))) {
3848
              /* Found according to SSN */
3849
0
              is_subdissector = true;
3850
0
          } else {
3851
0
              subdissector_handle = data_handle;
3852
0
              is_subdissector = true;
3853
0
          }
3854
0
      } /* OID */
3855
0
  } else {
3856
      /* We have it already */
3857
0
  }
3858
3859
  /* Call the sub dissector if present, and not already called */
3860
0
  if (is_subdissector) {
3861
0
      bool is_active = call_dissector_only(subdissector_handle, tvb, actx->pinfo, tree, actx->value_ptr);
3862
0
      col_set_fence(actx->pinfo->cinfo, COL_INFO);
3863
0
      if(!is_active){
3864
0
          return false;
3865
0
    }
3866
0
  }
3867
0
  return true;
3868
0
}
3869
3870
void
3871
call_tcap_dissector(dissector_handle_t handle, tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree)
3872
0
{
3873
0
  requested_subdissector_handle = handle;
3874
3875
0
  TRY {
3876
0
    dissect_tcap(tvb, pinfo, tree, NULL);
3877
0
  } CATCH_ALL {
3878
0
    requested_subdissector_handle = NULL;
3879
0
    RETHROW;
3880
0
  } ENDTRY;
3881
3882
0
  requested_subdissector_handle = NULL;
3883
0
}
3884
3885
/*
3886
 * Editor modelines
3887
 *
3888
 * Local Variables:
3889
 * c-basic-offset: 2
3890
 * tab-width: 8
3891
 * indent-tabs-mode: nil
3892
 * End:
3893
 *
3894
 * ex: set shiftwidth=2 tabstop=8 expandtab:
3895
 * :indentSize=2:tabSize=8:noTabs=true:
3896
 */