Coverage Report

Created: 2026-01-02 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-tcap.c
Line
Count
Source
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
void proto_reg_handoff_tcap(void);
41
void proto_register_tcap(void);
42
43
/* Initialize the protocol and registered fields */
44
static int proto_tcap;
45
static int hf_tcap_tag;
46
static int hf_tcap_length;
47
static int hf_tcap_data;
48
static int hf_tcap_tid;
49
static int hf_tcap_constructor_eoc;
50
51
int hf_tcapsrt_SessionId;
52
int hf_tcapsrt_Duplicate;
53
int hf_tcapsrt_BeginSession;
54
int hf_tcapsrt_EndSession;
55
int hf_tcapsrt_SessionTime;
56
57
static int hf_tcap_UniDialoguePDU_PDU;            /* UniDialoguePDU */
58
static int hf_tcap_DialoguePDU_PDU;               /* DialoguePDU */
59
static int hf_tcap_oid;                           /* OBJECT_IDENTIFIER */
60
static int hf_tcap_dialog;                        /* Dialog1 */
61
static int hf_tcap_unidirectional;                /* Unidirectional */
62
static int hf_tcap_begin;                         /* Begin */
63
static int hf_tcap_end;                           /* End */
64
static int hf_tcap_continue;                      /* Continue */
65
static int hf_tcap_abort;                         /* Abort */
66
static int hf_tcap_dialoguePortion;               /* DialoguePortion */
67
static int hf_tcap_components;                    /* ComponentPortion */
68
static int hf_tcap_otid;                          /* OrigTransactionID */
69
static int hf_tcap_dtid;                          /* DestTransactionID */
70
static int hf_tcap_reason;                        /* Reason */
71
static int hf_tcap_p_abortCause;                  /* P_AbortCause */
72
static int hf_tcap_u_abortCause;                  /* DialoguePortion */
73
static int hf_tcap__untag_item;                   /* Component */
74
static int hf_tcap_invoke;                        /* Invoke */
75
static int hf_tcap_returnResultLast;              /* ReturnResult */
76
static int hf_tcap_returnError;                   /* ReturnError */
77
static int hf_tcap_reject;                        /* Reject */
78
static int hf_tcap_returnResultNotLast;           /* ReturnResult */
79
static int hf_tcap_invokeID;                      /* InvokeIdType */
80
static int hf_tcap_linkedID;                      /* InvokeIdType */
81
static int hf_tcap_opCode;                        /* OPERATION */
82
static int hf_tcap_parameter;                     /* Parameter */
83
static int hf_tcap_resultretres;                  /* T_resultretres */
84
static int hf_tcap_errorCode;                     /* ErrorCode */
85
static int hf_tcap_invokeIDRej;                   /* T_invokeIDRej */
86
static int hf_tcap_derivable;                     /* InvokeIdType */
87
static int hf_tcap_not_derivable;                 /* NULL */
88
static int hf_tcap_problem;                       /* T_problem */
89
static int hf_tcap_generalProblem;                /* GeneralProblem */
90
static int hf_tcap_invokeProblem;                 /* InvokeProblem */
91
static int hf_tcap_returnResultProblem;           /* ReturnResultProblem */
92
static int hf_tcap_returnErrorProblem;            /* ReturnErrorProblem */
93
static int hf_tcap_localValue;                    /* INTEGER */
94
static int hf_tcap_globalValue;                   /* OBJECT_IDENTIFIER */
95
static int hf_tcap_nationaler;                    /* INTEGER_M32768_32767 */
96
static int hf_tcap_privateer;                     /* INTEGER */
97
static int hf_tcap_unidialoguePDU;                /* AUDT_apdu */
98
static int hf_tcap_audt_protocol_version;         /* AUDT_protocol_version */
99
static int hf_tcap_audt_application_context_name;  /* AUDT_application_context_name */
100
static int hf_tcap_audt_user_information;         /* AUDT_user_information */
101
static int hf_tcap_audt_user_information_item;    /* EXTERNAL */
102
static int hf_tcap_dialogueRequest;               /* AARQ_apdu */
103
static int hf_tcap_dialogueResponse;              /* AARE_apdu */
104
static int hf_tcap_dialogueAbort;                 /* ABRT_apdu */
105
static int hf_tcap_aarq_protocol_version;         /* AARQ_protocol_version */
106
static int hf_tcap_aarq_application_context_name;  /* AARQ_application_context_name */
107
static int hf_tcap_aarq_user_information;         /* AARQ_user_information */
108
static int hf_tcap_aarq_user_information_item;    /* EXTERNAL */
109
static int hf_tcap_aare_protocol_version;         /* AARE_protocol_version */
110
static int hf_tcap_aare_application_context_name;  /* AARE_application_context_name */
111
static int hf_tcap_result;                        /* Associate_result */
112
static int hf_tcap_result_source_diagnostic;      /* Associate_source_diagnostic */
113
static int hf_tcap_aare_user_information;         /* AARE_user_information */
114
static int hf_tcap_aare_user_information_item;    /* EXTERNAL */
115
static int hf_tcap_abort_source;                  /* ABRT_source */
116
static int hf_tcap_abrt_user_information;         /* ABRT_user_information */
117
static int hf_tcap_abrt_user_information_item;    /* EXTERNAL */
118
static int hf_tcap_dialogue_service_user;         /* T_dialogue_service_user */
119
static int hf_tcap_dialogue_service_provider;     /* T_dialogue_service_provider */
120
/* named bits */
121
static int hf_tcap_AUDT_protocol_version_version1;
122
static int hf_tcap_AARQ_protocol_version_version1;
123
static int hf_tcap_AARE_protocol_version_version1;
124
125
/* Initialize the subtree pointers */
126
static int ett_tcap;
127
static int ett_param;
128
129
static int ett_otid;
130
static int ett_dtid;
131
int ett_tcap_stat;
132
133
static struct tcapsrt_info_t * gp_tcapsrt_info;
134
static bool tcap_subdissector_used=false;
135
static dissector_handle_t requested_subdissector_handle;
136
137
static int ss7pc_address_type = -1;
138
139
static struct tcaphash_context_t * gp_tcap_context;
140
141
static int ett_tcap_ExternalPDU_U;
142
static int ett_tcap_TCMessage;
143
static int ett_tcap_Unidirectional;
144
static int ett_tcap_Begin;
145
static int ett_tcap_End;
146
static int ett_tcap_Continue;
147
static int ett_tcap_Abort;
148
static int ett_tcap_Reason;
149
static int ett_tcap_SEQUENCE_SIZE_1_MAX_OF_Component;
150
static int ett_tcap_Component;
151
static int ett_tcap_Invoke;
152
static int ett_tcap_ReturnResult;
153
static int ett_tcap_T_resultretres;
154
static int ett_tcap_ReturnError;
155
static int ett_tcap_Reject;
156
static int ett_tcap_T_invokeIDRej;
157
static int ett_tcap_T_problem;
158
static int ett_tcap_OPERATION;
159
static int ett_tcap_ErrorCode;
160
static int ett_tcap_UniDialoguePDU;
161
static int ett_tcap_AUDT_apdu_U;
162
static int ett_tcap_AUDT_protocol_version;
163
static int ett_tcap_AUDT_user_information;
164
static int ett_tcap_DialoguePDU;
165
static int ett_tcap_AARQ_apdu_U;
166
static int ett_tcap_AARQ_protocol_version;
167
static int ett_tcap_AARQ_user_information;
168
static int ett_tcap_AARE_apdu_U;
169
static int ett_tcap_AARE_protocol_version;
170
static int ett_tcap_AARE_user_information;
171
static int ett_tcap_ABRT_apdu_U;
172
static int ett_tcap_ABRT_user_information;
173
static int ett_tcap_Associate_source_diagnostic;
174
175
/* When several Tcap components are received in a single TCAP message,
176
   we have to use several buffers for the stored parameters
177
   because else this data are erased during TAP dissector call */
178
53
#define MAX_TCAP_INSTANCE 10
179
static int tcapsrt_global_current=0;
180
static struct tcapsrt_info_t tcapsrt_global_info[MAX_TCAP_INSTANCE];
181
182
28
#define MAX_SSN 254
183
static range_t *global_ssn_range;
184
static range_t *ssn_range;
185
186
/* These two timeout (in second) are used when some message are lost,
187
   or when the same TCAP transcation identifier is reused */
188
static unsigned gtcap_RepetitionTimeout = 10;
189
static unsigned gtcap_LostTimeout = 30;
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
69
dissector_handle_t get_itu_tcap_subdissector(uint32_t ssn) {
242
69
  return dissector_get_uint_handle(itu_sub_dissectors, ssn);
243
69
}
244
245
246
247
static unsigned
248
0
dissect_tcap_OBJECT_IDENTIFIER(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
257
0
dissect_tcap_Dialog1(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
273
0
dissect_tcap_ExternalPDU_U(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
283
0
dissect_tcap_ExternalPDU(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
296
0
dissect_tcap_DialogueOC(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
307
0
dissect_tcap_DialoguePortion(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
317
0
dissect_tcap_InvokeIdType(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
318
0
  offset = dissect_ber_constrained_integer(implicit_tag, actx, tree, tvb, offset,
319
0
                                                            -128, 127U, hf_index, NULL);
320
321
0
  return offset;
322
0
}
323
324
325
326
static unsigned
327
0
dissect_tcap_INTEGER(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
348
0
dissect_tcap_OPERATION(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
359
0
dissect_tcap_Parameter(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
377
0
dissect_tcap_Invoke(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
392
0
dissect_tcap_T_resultretres(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
407
0
dissect_tcap_ReturnResult(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
417
0
dissect_tcap_INTEGER_M32768_32767(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
418
0
  offset = dissect_ber_constrained_integer(implicit_tag, actx, tree, tvb, offset,
419
0
                                                            -32768, 32767U, hf_index, 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 unsigned
438
0
dissect_tcap_ErrorCode(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
455
0
dissect_tcap_ReturnError(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
465
0
dissect_tcap_NULL(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
485
0
dissect_tcap_T_invokeIDRej(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
503
0
dissect_tcap_GeneralProblem(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
525
0
dissect_tcap_InvokeProblem(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
542
0
dissect_tcap_ReturnResultProblem(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
561
0
dissect_tcap_ReturnErrorProblem(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
586
0
dissect_tcap_T_problem(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
602
0
dissect_tcap_Reject(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
629
0
dissect_tcap_Component(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
673
0
dissect_tcap_SEQUENCE_SIZE_1_MAX_OF_Component(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
674
0
  offset = dissect_ber_constrained_sequence_of(implicit_tag, actx, tree, tvb, offset,
675
0
                                                  1, NO_BOUND, 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 unsigned
683
0
dissect_tcap_ComponentPortion(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
698
1
dissect_tcap_Unidirectional(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
699
1
  offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
700
1
                                   Unidirectional_sequence, hf_index, ett_tcap_Unidirectional);
701
702
1
  return offset;
703
1
}
704
705
706
707
static unsigned
708
0
dissect_tcap_OCTET_STRING_SIZE_1_4(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
709
0
  offset = dissect_ber_constrained_octet_string(implicit_tag, actx, tree, tvb, offset,
710
0
                                                   1, 4, hf_index, NULL);
711
712
0
  return offset;
713
0
}
714
715
716
717
static unsigned
718
0
dissect_tcap_OrigTransactionID(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
781
1
dissect_tcap_Begin(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
782
1
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
1
  col_set_str(actx->pinfo->cinfo, COL_INFO, "Begin ");
792
1
  offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
793
1
                                   Begin_sequence, hf_index, ett_tcap_Begin);
794
795
1
  return offset;
796
1
}
797
798
799
800
static unsigned
801
0
dissect_tcap_DestTransactionID(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
863
1
dissect_tcap_End(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
864
1
gp_tcapsrt_info->ope=TC_END;
865
866
1
  col_set_str(actx->pinfo->cinfo, COL_INFO, "End ");
867
1
  offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
868
1
                                   End_sequence, hf_index, ett_tcap_End);
869
870
1
  return offset;
871
1
}
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 unsigned
883
0
dissect_tcap_Continue(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
905
0
dissect_tcap_P_AbortCause_U(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
906
0
  offset = dissect_ber_constrained_integer(implicit_tag, actx, tree, tvb, offset,
907
0
                                                            0U, 127U, hf_index, NULL);
908
909
0
  return offset;
910
0
}
911
912
913
914
static unsigned
915
0
dissect_tcap_P_AbortCause(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
936
0
dissect_tcap_Reason(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
952
1
dissect_tcap_Abort(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
953
1
gp_tcapsrt_info->ope=TC_ABORT;
954
955
1
  col_set_str(actx->pinfo->cinfo, COL_INFO, "Abort ");
956
1
  offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
957
1
                                   Abort_sequence, hf_index, ett_tcap_Abort);
958
959
1
  return offset;
960
1
}
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 unsigned
973
49
dissect_tcap_TCMessage(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
974
49
  offset = dissect_ber_choice(actx, tree, tvb, offset,
975
49
                                 TCMessage_choice, hf_index, ett_tcap_TCMessage,
976
49
                                 NULL);
977
978
49
  return offset;
979
49
}
980
981
982
static int * const AUDT_protocol_version_bits[] = {
983
  &hf_tcap_AUDT_protocol_version_version1,
984
  NULL
985
};
986
987
static unsigned
988
0
dissect_tcap_AUDT_protocol_version(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
999
0
dissect_tcap_AUDT_application_context_name(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
1014
0
dissect_tcap_EXTERNAL(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
1026
0
dissect_tcap_AUDT_user_information(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
1042
0
dissect_tcap_AUDT_apdu_U(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
1052
0
dissect_tcap_AUDT_apdu(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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
unsigned
1071
0
dissect_tcap_UniDialoguePDU(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
1086
0
dissect_tcap_AARQ_protocol_version(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
1097
0
dissect_tcap_AARQ_application_context_name(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
1115
0
dissect_tcap_AARQ_user_information(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
1131
0
dissect_tcap_AARQ_apdu_U(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
1141
0
dissect_tcap_AARQ_apdu(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
1155
0
dissect_tcap_AARE_protocol_version(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
1166
0
dissect_tcap_AARE_application_context_name(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
1187
0
dissect_tcap_Associate_result(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
1204
0
dissect_tcap_T_dialogue_service_user(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
1221
0
dissect_tcap_T_dialogue_service_provider(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
1242
0
dissect_tcap_Associate_source_diagnostic(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
1256
0
dissect_tcap_AARE_user_information(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
1274
0
dissect_tcap_AARE_apdu_U(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
1284
0
dissect_tcap_AARE_apdu(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
1300
0
dissect_tcap_ABRT_source(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
1313
0
dissect_tcap_ABRT_user_information(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
1328
0
dissect_tcap_ABRT_apdu_U(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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 unsigned
1338
0
dissect_tcap_ABRT_apdu(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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
unsigned
1361
0
dissect_tcap_DialoguePDU(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned 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
  unsigned 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
  unsigned 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
1
{
1445
1
  const struct tcaphash_begin_info_key_t *key = (const struct tcaphash_begin_info_key_t *) k;
1446
1
  unsigned hashkey;
1447
  /* hashkey = key->opc_hash<<16 + key->dpc_hash<<8 + key->src_tid; */
1448
1
  hashkey = key->tid;
1449
1
  return hashkey;
1450
1
}
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
1
{
1506
1
  const struct tcaphash_end_info_key_t *key = (const struct tcaphash_end_info_key_t *) k;
1507
1
  unsigned hashkey;
1508
1
  hashkey = key->tid;
1509
1
  return hashkey;
1510
1
}
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
1
{
1704
1
  struct tcaphash_begincall_t *p_tcaphash_begincall = NULL;
1705
1
  p_tcaphash_begincall = (struct tcaphash_begincall_t *)wmem_map_lookup(tcaphash_begin, p_tcaphash_begin_key);
1706
1707
1
  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
1
  } else {
1738
#ifdef DEBUG_TCAPSRT
1739
    dbg(23,"Not in Bhash ");
1740
#endif
1741
1
  }
1742
1
  return NULL;
1743
1
}
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
1
{
1790
1
  struct tcaphash_endcall_t *p_tcaphash_endcall = NULL;
1791
1
  p_tcaphash_endcall = (struct tcaphash_endcall_t *)wmem_map_lookup(tcaphash_end, p_tcaphash_end_key);
1792
1793
1
  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
1
  } else {
1825
#ifdef DEBUG_TCAPSRT
1826
    dbg(23,"Not in Ehash ");
1827
#endif
1828
1
  }
1829
1
  return NULL;
1830
1
}
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 identifying 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
            stat_tree = proto_tree_add_subtree(tree, tvb, 0, -1, ett_tcap_stat, &stat_item, "Stat");
2189
0
            proto_item_set_generated(stat_item);
2190
0
            pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_Duplicate, tvb, 0, 0,
2191
0
                                              p_tcaphash_context->first_frame,
2192
0
                                              "Duplicate with session %u in frame %u",
2193
0
                                              p_tcaphash_context->session_id,p_tcaphash_context->first_frame);
2194
0
            proto_item_set_generated(pi);
2195
2196
0
            return p_tcaphash_context;
2197
0
          } /* Previous session closed */
2198
0
        } /* test with Timeout or message Lost */
2199
0
        break;
2200
0
      } /* Next call is NULL */
2201
      /* Repeat the tests for the next record with the same transaction identifier */
2202
0
      p_tcaphash_begincall = p_tcaphash_begincall->next_begincall;
2203
0
    } while (p_tcaphash_begincall != NULL );
2204
    /*
2205
     * End of analyze for the list be TC_BEGIN with same transaction ID
2206
     */
2207
0
  } else { /* p_tcaphash_begincall has not been found */
2208
    /*
2209
     * Create a new TCAP context
2210
     */
2211
#ifdef DEBUG_TCAPSRT
2212
    dbg(10,"New key %lx ",tcaphash_begin_key.hashKey);
2213
#endif
2214
2215
0
    tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
2216
0
    p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
2217
0
    p_tcaphash_begincall = new_tcaphash_begin(&tcaphash_begin_key, p_tcaphash_context);
2218
2219
#ifdef DEBUG_TCAPSRT
2220
    dbg(11,"Update key %lx ",tcaphash_begin_key.hashKey);
2221
    dbg(11,"Frame reqlink #%u ", pinfo->num);
2222
#endif
2223
0
    update_tcaphash_begincall(p_tcaphash_begincall, pinfo);
2224
0
  }
2225
2226
  /* display tcap session, if available */
2227
0
  if ( p_tcaphash_context &&
2228
0
       p_tcaphash_context->session_id) {
2229
0
    stat_tree = proto_tree_add_subtree(tree, tvb, 0, 0, ett_tcap_stat, &stat_item, "Stat");
2230
0
    proto_item_set_generated(stat_item);
2231
0
    pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
2232
0
    proto_item_set_generated(pi);
2233
2234
    /* add link to response frame, if available */
2235
    /* p_tcaphash_begincall->context->last_frame) */
2236
0
    if( p_tcaphash_context->last_frame != 0 ){
2237
#ifdef DEBUG_TCAPSRT
2238
      dbg(20,"Display_frameRsplink %d ",p_tcaphash_context->last_frame);
2239
#endif
2240
0
      pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_BeginSession, tvb, 0, 0,
2241
0
                                      p_tcaphash_context->last_frame,
2242
0
                                      "End of session in frame %u",
2243
0
                                      p_tcaphash_context->last_frame);
2244
0
      proto_item_set_generated(pi);
2245
0
    }
2246
0
  }
2247
0
  return p_tcaphash_context;
2248
0
}
2249
2250
/*
2251
* Try to find a TCAP session according to the source and destination
2252
* Identifier given in the TC_CONT
2253
* If nothing is found, it is probably a session in opening state, so try to find
2254
* a tcap session registered with a TC_BEGIN "key", matching the destination Id of the TC_CONT
2255
* Then associate the TC_CONT "key" to the TCAP context, and create a TC_END "key"
2256
* and display the available info for the TCAP context
2257
*/
2258
static struct tcaphash_context_t *
2259
tcaphash_cont_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2260
                       struct tcapsrt_info_t *p_tcapsrt_info)
2261
0
{
2262
0
  struct tcaphash_context_t *p_tcaphash_context=NULL;
2263
0
  struct tcaphash_contcall_t *p_tcaphash_contcall;
2264
0
  struct tcaphash_cont_info_key_t tcaphash_cont_key;
2265
0
  struct tcaphash_begin_info_key_t tcaphash_begin_key;
2266
0
  struct tcaphash_begincall_t *p_tcaphash_begincall;
2267
0
  struct tcaphash_end_info_key_t tcaphash_end_key;
2268
0
  proto_item *pi;
2269
0
  proto_item *stat_item=NULL;
2270
0
  proto_tree *stat_tree=NULL;
2271
0
  bool use_dst = false;
2272
2273
#ifdef DEBUG_TCAPSRT
2274
  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);
2275
  dbg(10,"\n Hcont #%u ", pinfo->num);
2276
#endif
2277
2278
  /* look only for matching request, if matching conversation is available. */
2279
0
  tcaphash_cont_key.src_tid = p_tcapsrt_info->src_tid;
2280
0
  tcaphash_cont_key.dst_tid = p_tcapsrt_info->dst_tid;
2281
0
  if (pinfo->src.type == ss7pc_address_type && pinfo->dst.type == ss7pc_address_type)
2282
0
  {
2283
    /* We have MTP3 PCs (so we can safely do this cast) */
2284
0
    tcaphash_cont_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
2285
0
    tcaphash_cont_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
2286
0
  } else {
2287
    /* Don't have MTP3 PCs (have SCCP GT ?) */
2288
0
    tcaphash_cont_key.opc_hash = g_str_hash(address_to_str(pinfo->pool, &pinfo->src));
2289
0
    tcaphash_cont_key.dpc_hash = g_str_hash(address_to_str(pinfo->pool, &pinfo->dst));
2290
0
  }
2291
0
  tcaphash_cont_key.hashKey=tcaphash_cont_calchash(&tcaphash_cont_key);
2292
2293
#ifdef DEBUG_TCAPSRT
2294
  dbg(11,"Ckey %lx ", tcaphash_cont_key.hashKey);
2295
  dbg(51,"addr %s %s ", address_to_str(pinfo->pool, &pinfo->src), address_to_str(pinfo->pool, &pinfo->dst));
2296
  dbg(51,"Tid %lx %lx \n",tcaphash_cont_key.src_tid, tcaphash_cont_key.dst_tid);
2297
#endif
2298
0
  p_tcaphash_contcall = find_tcaphash_cont(&tcaphash_cont_key, pinfo);
2299
0
  if(p_tcaphash_contcall) {
2300
#ifdef DEBUG_TCAPSRT
2301
    dbg(12,"CFound ");
2302
#endif
2303
0
    p_tcaphash_context=p_tcaphash_contcall->context;
2304
0
  } else { /* cont not found */
2305
#ifdef DEBUG_TCAPSRT
2306
    dbg(12,"CnotFound ");
2307
#endif
2308
    /* Find the TCAP transaction according to the TC_BEGIN (from dtid,dst) */
2309
0
    tcaphash_begin_key.tid = p_tcapsrt_info->dst_tid;
2310
0
    if (pinfo->src.type == ss7pc_address_type && pinfo->dst.type == ss7pc_address_type)
2311
0
    {
2312
      /* We have MTP3 PCs (so we can safely do this cast) */
2313
0
      tcaphash_begin_key.pc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
2314
0
    } else {
2315
      /* Don't have MTP3 PCs (have SCCP GT ?) */
2316
0
      tcaphash_begin_key.pc_hash = g_str_hash(address_to_str(pinfo->pool, &pinfo->dst));
2317
0
    }
2318
0
    tcaphash_begin_key.hashKey=tcaphash_begin_calchash(&tcaphash_begin_key);
2319
2320
#ifdef DEBUG_TCAPSRT
2321
    dbg(11,"Bkey %lx ", tcaphash_begin_key.hashKey);
2322
    dbg(51,"addr %s ", address_to_str(pinfo->pool, &pinfo->dst));
2323
    dbg(51,"Tid %lx \n",tcaphash_begin_key.tid);
2324
#endif
2325
0
    p_tcaphash_begincall = find_tcaphash_begin(&tcaphash_begin_key, pinfo, false);
2326
0
    if(!p_tcaphash_begincall){
2327
0
      try_src:
2328
/* can this actually happen? */
2329
#ifdef DEBUG_TCAPSRT
2330
        dbg(12,"BNotFound trying stid,src");
2331
#endif
2332
        /* Do we have a continue from the same source? (stid,src) */
2333
0
        use_dst = true;
2334
0
        tcaphash_begin_key.tid = p_tcapsrt_info->src_tid;
2335
0
        if (pinfo->src.type == ss7pc_address_type && pinfo->dst.type == ss7pc_address_type)
2336
0
        {
2337
          /* We have MTP3 PCs (so we can safely do this cast) */
2338
0
          tcaphash_begin_key.pc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
2339
0
        } else {
2340
          /* Don't have MTP3 PCs (have SCCP GT ?) */
2341
0
          tcaphash_begin_key.pc_hash = g_str_hash(address_to_str(pinfo->pool, &pinfo->src));
2342
0
        }
2343
0
        tcaphash_begin_key.hashKey=tcaphash_begin_calchash(&tcaphash_begin_key);
2344
#ifdef DEBUG_TCAPSRT
2345
        dbg(11,"Bkey %lx ", tcaphash_begin_key.hashKey);
2346
        dbg(51,"addr %s ", address_to_str(pinfo->pool, &pinfo->src));
2347
        dbg(51,"Tid %lx \n",tcaphash_begin_key.tid);
2348
#endif
2349
0
        p_tcaphash_begincall = find_tcaphash_begin(&tcaphash_begin_key, pinfo,false);
2350
0
    }
2351
0
    if(p_tcaphash_begincall &&
2352
0
       !p_tcaphash_begincall->context->contcall ) {
2353
#ifdef DEBUG_TCAPSRT
2354
      dbg(12,"BFound \n");
2355
#endif
2356
0
      p_tcaphash_context=p_tcaphash_begincall->context;
2357
0
      p_tcaphash_context->responded=true;
2358
2359
#ifdef DEBUG_TCAPSRT
2360
      dbg(10,"New Ckey %lx ",tcaphash_cont_key.hashKey);
2361
      dbg(11,"Frame reqlink #%u \n", pinfo->num);
2362
#endif
2363
0
      create_tcaphash_cont(&tcaphash_cont_key,
2364
0
                           p_tcaphash_begincall->context);
2365
2366
      /* Create END for (stid,src) or (dtid,dst) */
2367
0
      tcaphash_end_key.tid = use_dst ? p_tcapsrt_info->dst_tid : p_tcapsrt_info->src_tid;
2368
0
      if (pinfo->src.type == ss7pc_address_type && pinfo->dst.type == ss7pc_address_type)
2369
0
      {
2370
        /* We have MTP3 PCs (so we can safely do this cast) */
2371
0
        tcaphash_end_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)(use_dst ? pinfo->dst.data : pinfo->src.data));
2372
0
        tcaphash_end_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)(use_dst ? pinfo->src.data : pinfo->dst.data));
2373
0
    } else {
2374
        /* Don't have MTP3 PCs (have SCCP GT ?) */
2375
0
        tcaphash_end_key.dpc_hash = g_str_hash(address_to_str(pinfo->pool, use_dst ? &pinfo->dst : &pinfo->src));
2376
0
        tcaphash_end_key.opc_hash = g_str_hash(address_to_str(pinfo->pool, use_dst ? &pinfo->src : &pinfo->dst));
2377
0
    }
2378
0
      tcaphash_end_key.hashKey=tcaphash_end_calchash(&tcaphash_end_key);
2379
2380
#ifdef DEBUG_TCAPSRT
2381
      dbg(10,"New Ekey %lx ",tcaphash_end_key.hashKey);
2382
      dbg(51,"addr %s ", address_to_str(pinfo->pool, use_dst ? &pinfo->dst : &pinfo->src));
2383
      dbg(51,"Tid %lx ",tcaphash_end_key.tid);
2384
      dbg(11,"Frame reqlink #%u ", pinfo->num);
2385
#endif
2386
0
      create_tcaphash_end(&tcaphash_end_key,
2387
0
                          p_tcaphash_begincall->context);
2388
2389
0
    } else { /* Begin not found */
2390
#ifdef DEBUG_TCAPSRT
2391
      dbg(12,"BnotFound ");
2392
#endif
2393
0
      if (!use_dst) {
2394
        /* make another try with src tid / address */
2395
0
        goto try_src;
2396
0
      }
2397
0
    } /* begin found */
2398
0
  } /* cont found */
2399
    /* display tcap session, if available */
2400
0
  if (p_tcaphash_context &&
2401
0
      p_tcaphash_context->session_id) {
2402
0
    stat_tree = proto_tree_add_subtree(tree, tvb, 0, -1, ett_tcap_stat, &stat_item, "Stat");
2403
0
    proto_item_set_generated(stat_item);
2404
0
    pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
2405
0
    proto_item_set_generated(pi);
2406
0
  }
2407
2408
0
  return p_tcaphash_context;
2409
0
}
2410
2411
/*
2412
* Try to find a TCAP session according to the destination Identifier given in the TC_END/TC_ABORT
2413
* If nothing is found,
2414
* - either it is a session in opening state,
2415
* - or the session is closed/aborted by the remote, ( so we switch the src and dst tid )
2416
* so try to find a tcap session registered with a TC_BEGIN "key",
2417
* matching the destination Id of the TC_END
2418
* Then associate the TC_CONT "key" to the TCAP context
2419
* and display the available info for the TCAP context
2420
*/
2421
2422
static struct tcaphash_context_t *
2423
tcaphash_end_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2424
                      struct tcapsrt_info_t *p_tcapsrt_info)
2425
1
{
2426
1
  struct tcaphash_context_t *p_tcaphash_context=NULL;
2427
2428
1
  struct tcaphash_end_info_key_t tcaphash_end_key;
2429
1
  struct tcaphash_endcall_t *p_tcaphash_endcall=NULL;
2430
2431
1
  struct tcaphash_begin_info_key_t tcaphash_begin_key;
2432
1
  struct tcaphash_begincall_t *p_tcaphash_begincall=NULL;
2433
1
  proto_item *pi;
2434
1
  nstime_t delta;
2435
1
  proto_item *stat_item=NULL;
2436
1
  proto_tree *stat_tree=NULL;
2437
2438
#ifdef DEBUG_TCAPSRT
2439
  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);
2440
  dbg(10,"\n Hend #%u ", pinfo->num);
2441
#endif
2442
  /* look only for matching request, if matching conversation is available. */
2443
1
  tcaphash_end_key.tid = p_tcapsrt_info->dst_tid;
2444
1
  if (pinfo->src.type == ss7pc_address_type && pinfo->dst.type == ss7pc_address_type)
2445
1
  {
2446
    /* We have MTP3 PCs (so we can safely do this cast) */
2447
1
    tcaphash_end_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
2448
1
    tcaphash_end_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
2449
1
  } else {
2450
    /* Don't have MTP3 PCs (have SCCP GT ?) */
2451
0
    tcaphash_end_key.opc_hash = g_str_hash(address_to_str(pinfo->pool, &pinfo->src));
2452
0
    tcaphash_end_key.dpc_hash = g_str_hash(address_to_str(pinfo->pool, &pinfo->dst));
2453
0
}
2454
1
  tcaphash_end_key.hashKey=tcaphash_end_calchash(&tcaphash_end_key);
2455
2456
#ifdef DEBUG_TCAPSRT
2457
  dbg(11,"Ekey %lx ",tcaphash_end_key.hashKey);
2458
  dbg(11,"addr %s ", address_to_str(pinfo->pool, &pinfo->dst));
2459
  dbg(51,"Tid %lx ",tcaphash_end_key.tid);
2460
#endif
2461
1
  p_tcaphash_endcall = find_tcaphash_end(&tcaphash_end_key, pinfo,true);
2462
2463
1
  if(!p_tcaphash_endcall) {
2464
#ifdef DEBUG_TCAPSRT
2465
    dbg(12,"EnotFound ");
2466
#endif
2467
1
    tcaphash_begin_key.tid = p_tcapsrt_info->dst_tid;
2468
1
    if (pinfo->src.type == ss7pc_address_type && pinfo->dst.type == ss7pc_address_type)
2469
1
    {
2470
      /* We have MTP3 PCs (so we can safely do this cast) */
2471
1
      tcaphash_begin_key.pc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
2472
1
    } else {
2473
      /* Don't have MTP3 PCs (have SCCP GT ?) */
2474
0
      tcaphash_begin_key.pc_hash = g_str_hash(address_to_str(pinfo->pool, &pinfo->dst));
2475
0
    }
2476
1
    tcaphash_begin_key.hashKey=tcaphash_begin_calchash(&tcaphash_begin_key);
2477
2478
#ifdef DEBUG_TCAPSRT
2479
    dbg(11,"Bkey %lx ", tcaphash_begin_key.hashKey);
2480
    dbg(51,"addr %s ", address_to_str(pinfo->pool, &pinfo->dst));
2481
    dbg(51,"Tid %lx ",tcaphash_begin_key.tid);
2482
#endif
2483
1
    p_tcaphash_begincall = find_tcaphash_begin(&tcaphash_begin_key, pinfo,false);
2484
1
    if(!p_tcaphash_begincall) {
2485
#ifdef DEBUG_TCAPSRT
2486
      dbg(12,"BnotFound ");
2487
#endif
2488
1
    }
2489
1
  }
2490
1
  if (p_tcaphash_endcall) {
2491
    /* Use the TC_BEGIN Destination reference */
2492
0
    p_tcaphash_context=p_tcaphash_endcall->context;
2493
1
  } else if (p_tcaphash_begincall) {
2494
    /* Use the TC_BEGIN Source reference */
2495
0
    p_tcaphash_context=p_tcaphash_begincall->context;
2496
0
  }
2497
2498
1
  if (p_tcaphash_context) {
2499
2500
#ifdef DEBUG_TCAPSRT
2501
    dbg(12,"Found, req=%d ",p_tcaphash_context->first_frame);
2502
#endif
2503
2504
0
    stat_tree = proto_tree_add_subtree(tree, tvb, 0, -1, ett_tcap_stat, &stat_item, "Stat");
2505
0
    proto_item_set_generated(stat_item);
2506
2507
0
    pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
2508
0
    proto_item_set_generated(pi);
2509
2510
#ifdef DEBUG_TCAPSRT
2511
    dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
2512
#endif
2513
    /* Indicate the frame to which this is a reply. */
2514
0
    pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
2515
0
                                      p_tcaphash_context->first_frame,
2516
0
                                      "Begin of session in frame %u",
2517
0
                                      p_tcaphash_context->first_frame);
2518
0
    proto_item_set_generated(pi);
2519
    /* Calculate Service Response Time */
2520
0
    nstime_delta(&delta, &pinfo->abs_ts, &p_tcaphash_context->begin_time);
2521
2522
    /* display Service Response Time and make it filterable */
2523
0
    pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
2524
0
    proto_item_set_generated(pi);
2525
2526
    /* Close the context and remove it (if needed) */
2527
0
    tcapsrt_close(p_tcaphash_context,pinfo);
2528
2529
1
  } else {/* context present */
2530
#ifdef DEBUG_TCAPSRT
2531
    dbg(12,"Context notFound ");
2532
#endif
2533
1
  }
2534
1
  return p_tcaphash_context;
2535
1
}
2536
2537
/*
2538
 * ANSI PART
2539
 * Create the record identifying the TCAP transaction
2540
 * When the identifier for the transaction is reused, check
2541
 * the following criteria before to append a new record:
2542
 * - a timeout corresponding to a message retransmission is detected,
2543
 * - a message hast been lost
2544
 * - or the previous transaction has been  be closed
2545
 */
2546
static struct tcaphash_context_t *
2547
tcaphash_ansi_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2548
                       struct tcapsrt_info_t *p_tcapsrt_info)
2549
0
{
2550
0
  struct tcaphash_context_t *p_tcaphash_context=NULL;
2551
0
  struct tcaphash_context_key_t tcaphash_context_key;
2552
0
  struct tcaphash_ansicall_t *p_tcaphash_ansicall, *p_new_tcaphash_ansicall;
2553
0
  struct tcaphash_ansi_info_key_t tcaphash_ansi_key;
2554
0
  proto_item *pi;
2555
0
  nstime_t delta;
2556
0
  bool isResponse=false;
2557
0
  proto_tree * stat_tree=NULL;
2558
0
  proto_item * stat_item=NULL;
2559
2560
  /* prepare the key data */
2561
0
  tcaphash_ansi_key.tid = p_tcapsrt_info->src_tid;
2562
0
  if (pinfo->src.type == ss7pc_address_type && pinfo->dst.type == ss7pc_address_type)
2563
0
  {
2564
    /* We have MTP3 PCs (so we can safely do this cast) */
2565
0
    tcaphash_ansi_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
2566
0
    tcaphash_ansi_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
2567
0
  } else {
2568
    /* Don't have MTP3 PCs (have SCCP GT ?) */
2569
0
    tcaphash_ansi_key.opc_hash = g_str_hash(address_to_str(pinfo->pool, &pinfo->src));
2570
0
    tcaphash_ansi_key.dpc_hash = g_str_hash(address_to_str(pinfo->pool, &pinfo->dst));
2571
0
  }
2572
0
  tcaphash_ansi_key.hashKey=tcaphash_ansi_calchash(&tcaphash_ansi_key);
2573
2574
  /* look up the request */
2575
#ifdef DEBUG_TCAPSRT
2576
  dbg(10,"\n Hansi #%u ", pinfo->num);
2577
  dbg(11,"key %lx ",tcaphash_ansi_key.hashKey);
2578
  dbg(51,"PC %s %s ",address_to_str(pinfo->pool, &pinfo->src), address_to_str(pinfo->pool, &pinfo->dst));
2579
  dbg(51,"Tid %lx ",tcaphash_ansi_key.tid);
2580
#endif
2581
0
  p_tcaphash_ansicall = (struct tcaphash_ansicall_t *)
2582
0
    wmem_map_lookup(tcaphash_ansi, &tcaphash_ansi_key);
2583
2584
0
  if (p_tcaphash_ansicall) {
2585
    /* Walk through list of transaction with identical keys */
2586
0
    do {
2587
      /* Check if the request with this reqSeqNum has been seen */
2588
0
      if (pinfo->num == p_tcaphash_ansicall->context->first_frame) {
2589
        /* We have seen this request before -> do nothing */
2590
#ifdef DEBUG_TCAPSRT
2591
        dbg(22,"Request already seen ");
2592
#endif
2593
0
        isResponse=false;
2594
0
        p_tcaphash_context=p_tcaphash_ansicall->context;
2595
0
        break;
2596
0
      }
2597
2598
      /* Check if the response with this reqSeqNum has been seen */
2599
0
      if (pinfo->num == p_tcaphash_ansicall->context->last_frame) {
2600
        /* We have seen this response before -> do nothing */
2601
#ifdef DEBUG_TCAPSRT
2602
        dbg(22,"Response already seen ");
2603
#endif
2604
0
        isResponse=true;
2605
0
        p_tcaphash_context=p_tcaphash_ansicall->context;
2606
0
        break;
2607
0
      }
2608
2609
      /* Check for the first Request without Response
2610
       received before this frame */
2611
0
      if ( pinfo->num > p_tcaphash_ansicall->context->first_frame &&
2612
0
           p_tcaphash_ansicall->context->last_frame==0 ) {
2613
        /* Take it, and update the context */
2614
2615
#ifdef DEBUG_TCAPSRT
2616
        dbg(12,"Update key %lx ",tcaphash_ansi_key.hashKey);
2617
#endif
2618
0
        p_tcaphash_ansicall->context->last_frame = pinfo->num;
2619
0
        p_tcaphash_ansicall->context->responded = true;
2620
0
        p_tcaphash_ansicall->context->closed = true;
2621
0
        p_tcaphash_context=p_tcaphash_ansicall->context;
2622
0
        isResponse=true;
2623
2624
0
        stat_tree = proto_tree_add_subtree(tree, tvb, 0, -1, ett_tcap_stat, &stat_item, "Stat");
2625
0
        proto_item_set_generated(stat_item);
2626
2627
0
        pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
2628
0
        proto_item_set_generated(pi);
2629
2630
#ifdef DEBUG_TCAPSRT
2631
        dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
2632
#endif
2633
        /* Indicate the frame to which this is a reply. */
2634
0
        pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
2635
0
                                          p_tcaphash_context->first_frame,
2636
0
                                          "Begin of session in frame %u",
2637
0
                                          p_tcaphash_context->first_frame);
2638
0
        proto_item_set_generated(pi);
2639
        /* Calculate Service Response Time */
2640
0
        nstime_delta(&delta, &pinfo->abs_ts, &p_tcaphash_context->begin_time);
2641
2642
        /* display Service Response Time and make it filterable */
2643
0
        pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
2644
0
        proto_item_set_generated(pi);
2645
2646
0
        break;
2647
0
      } /* Lastframe=0, so take it */
2648
2649
2650
      /* If the last record for Tcap transaction with identifier has been reached */
2651
0
      if (!p_tcaphash_ansicall->next_ansicall) {
2652
        /* check if we have to create a new record or not */
2653
        /* if last request has been responded (response number in known)
2654
           and this request appears after last response (has bigger frame number)
2655
           and last request occurred after the timeout for repetition,
2656
           or
2657
           if last request hasn't been responded (so number unknown)
2658
           and this request appears after last request (has bigger frame number)
2659
           and this request occurred after the timeout for message lost */
2660
0
        if ( ( p_tcaphash_ansicall->context->last_frame != 0
2661
0
               && pinfo->num > p_tcaphash_ansicall->context->first_frame
2662
0
               && (unsigned) pinfo->abs_ts.secs > (unsigned)(p_tcaphash_ansicall->context->begin_time.secs + gtcap_RepetitionTimeout)
2663
0
               ) ||
2664
0
             ( p_tcaphash_ansicall->context->last_frame == 0
2665
0
               && pinfo->num > p_tcaphash_ansicall->context->first_frame
2666
0
               && (unsigned)pinfo->abs_ts.secs > (unsigned)(p_tcaphash_ansicall->context->begin_time.secs + gtcap_LostTimeout)
2667
0
               )
2668
0
             )
2669
0
          {
2670
            /* we decide that we have a new request */
2671
            /* Append new record to the list */
2672
#ifdef DEBUG_TCAPSRT
2673
            dbg(12,"(timeout) Append key %lx ",tcaphash_ansi_key.hashKey);
2674
            dbg(12,"Frame %u rsp %u ",pinfo->num,p_tcaphash_ansicall->context->last_frame );
2675
#endif
2676
0
            tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
2677
0
            p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
2678
0
            p_new_tcaphash_ansicall = append_tcaphash_ansicall(p_tcaphash_ansicall,
2679
0
                                                                 p_tcaphash_context,
2680
0
                                                                 pinfo);
2681
2682
#ifdef DEBUG_TCAPSRT
2683
            dbg(12,"Update key %lx ",tcaphash_ansi_key.hashKey);
2684
#endif
2685
0
            update_tcaphash_ansicall(p_new_tcaphash_ansicall, pinfo);
2686
0
            p_tcaphash_ansicall=p_new_tcaphash_ansicall;
2687
0
          } else {
2688
2689
          /* If the Tid is reused for a closed Transaction */
2690
0
          if ( p_tcaphash_ansicall->context->closed) {
2691
#ifdef DEBUG_TCAPSRT
2692
            dbg(12,"(closed) Append key %lu ",tcaphash_ansi_key.hashKey);
2693
            dbg(12,"Frame %u rsp %u ",pinfo->num,p_tcaphash_ansicall->context->last_frame );
2694
#endif
2695
0
            tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
2696
0
            p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
2697
0
            p_new_tcaphash_ansicall = append_tcaphash_ansicall(p_tcaphash_ansicall,
2698
0
                                                                 p_tcaphash_context,
2699
0
                                                                 pinfo);
2700
2701
#ifdef DEBUG_TCAPSRT
2702
            dbg(12,"Update key %lu ",tcaphash_ansi_key.hashKey);
2703
#endif
2704
0
            update_tcaphash_ansicall(p_new_tcaphash_ansicall, pinfo);
2705
0
            p_tcaphash_ansicall=p_new_tcaphash_ansicall;
2706
2707
0
          } else {
2708
            /* the Tid is reused for an opened Transaction */
2709
            /* so, this is the reply to the request of our context */
2710
0
            p_tcaphash_context=p_tcaphash_ansicall->context;
2711
#ifdef DEBUG_TCAPSRT
2712
            dbg(12,"Found, req=%d ",p_tcaphash_context->first_frame);
2713
#endif
2714
2715
0
            stat_tree = proto_tree_add_subtree(tree, tvb, 0, -1, ett_tcap_stat, &stat_item, "Stat");
2716
0
            proto_item_set_generated(stat_item);
2717
2718
0
            pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
2719
0
            proto_item_set_generated(pi);
2720
2721
#ifdef DEBUG_TCAPSRT
2722
            dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
2723
#endif
2724
            /* Indicate the frame to which this is a reply. */
2725
0
            pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
2726
0
                                              p_tcaphash_context->first_frame,
2727
0
                                              "Begin of session in frame %u",
2728
0
                                              p_tcaphash_context->first_frame);
2729
0
            proto_item_set_generated(pi);
2730
            /* Calculate Service Response Time */
2731
0
            nstime_delta(&delta, &pinfo->abs_ts, &p_tcaphash_context->begin_time);
2732
2733
            /* display Service Response Time and make it filterable */
2734
0
            pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
2735
0
            proto_item_set_generated(pi);
2736
2737
0
            p_tcaphash_context=p_tcaphash_ansicall->context;
2738
0
          } /* test with Timeout */
2739
0
        } /* closed */
2740
0
        break;
2741
0
      } /* Next call is NULL */
2742
0
      p_tcaphash_ansicall = p_tcaphash_ansicall->next_ansicall;
2743
0
    } while (p_tcaphash_ansicall != NULL );
2744
    /*
2745
     * New TCAP context
2746
     */
2747
0
  } else { /* p_tcaphash_ansicall has not been found */
2748
#ifdef DEBUG_TCAPSRT
2749
    dbg(10,"New key %lx ",tcaphash_ansi_key.hashKey);
2750
#endif
2751
2752
0
    tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
2753
0
    p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
2754
0
    p_tcaphash_ansicall = new_tcaphash_ansi(&tcaphash_ansi_key, p_tcaphash_context);
2755
2756
#ifdef DEBUG_TCAPSRT
2757
    dbg(11,"Update key %lx ",tcaphash_ansi_key.hashKey);
2758
    dbg(11,"Frame reqlink #%u ", pinfo->num);
2759
#endif
2760
0
    update_tcaphash_ansicall(p_tcaphash_ansicall, pinfo);
2761
0
  }
2762
2763
  /* display tcap session, if available */
2764
0
  if ( p_tcaphash_context &&
2765
0
       p_tcaphash_context->session_id) {
2766
0
    stat_tree = proto_tree_add_subtree(tree, tvb, 0, -1, ett_tcap_stat, &stat_item, "Stat");
2767
0
    proto_item_set_generated(stat_item);
2768
0
    pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
2769
0
    proto_item_set_generated(pi);
2770
0
  }
2771
2772
2773
  /* add link to response frame, if available */
2774
0
  if ( p_tcaphash_ansicall->context->last_frame != 0){
2775
0
    if (!isResponse) { /* Request */
2776
#ifdef DEBUG_TCAPSRT
2777
      dbg(20,"Display_frameRsplink %d ",p_tcaphash_ansicall->context->last_frame);
2778
#endif
2779
0
      pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_BeginSession, tvb, 0, 0,
2780
0
                                      p_tcaphash_ansicall->context->last_frame,
2781
0
                                      "End of session in frame %u",
2782
0
                                      p_tcaphash_ansicall->context->last_frame);
2783
0
      proto_item_set_generated(pi);
2784
0
    } else { /* Response */
2785
#ifdef DEBUG_TCAPSRT
2786
      dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
2787
#endif
2788
      /* Indicate the frame to which this is a reply. */
2789
0
      pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
2790
0
                                        p_tcaphash_context->first_frame,
2791
0
                                        "Begin of session in frame %u",
2792
0
                                        p_tcaphash_context->first_frame);
2793
0
      proto_item_set_generated(pi);
2794
      /* Calculate Service Response Time */
2795
0
      nstime_delta(&delta, &pinfo->abs_ts, &p_tcaphash_context->begin_time);
2796
2797
      /* display Service Response Time and make it filterable */
2798
0
      pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
2799
0
      proto_item_set_generated(pi);
2800
0
    } /* Request or Response */
2801
0
  }
2802
0
  return p_tcaphash_context;
2803
0
}
2804
2805
/*
2806
 * Service Response Time analyze
2807
 * Called just after dissector call
2808
 * Associate a TCAP context to a tcap session and display session related information
2809
 * like the first frame, the last, the session duration,
2810
 * and a uniq session identifier for the filtering
2811
 *
2812
 * For ETSI tcap, the TCAP context can be reached through three keys
2813
 * - a key (BEGIN) identifying the session according to the tcap source identifier
2814
 * - a key (CONT) identifying the established session (src_id and dst_id)
2815
 * - a key (END) identifying the session according to the tcap destination identifier
2816
 *
2817
 * For ANSI tcap, the TCAP context is reached through a uniq key
2818
 * - a key (ANSI) identifying the session according to the tcap identifier
2819
*/
2820
struct tcaphash_context_t *
2821
tcapsrt_call_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2822
                      struct tcapsrt_info_t *p_tcapsrt_info)
2823
44
{
2824
44
  struct tcaphash_context_t *tcap_context=NULL;
2825
2826
  /* if this packet isn't loaded because of a read filter, don't output anything */
2827
44
  if(pinfo == NULL || pinfo->num == 0) {
2828
0
    return NULL;
2829
0
  }
2830
2831
44
  switch (p_tcapsrt_info->ope) {
2832
2833
0
  case TC_BEGIN:
2834
#ifdef DEBUG_TCAPSRT
2835
    dbg(1,"\nTC_BEGIN ");
2836
#endif
2837
0
    tcap_context=tcaphash_begin_matching(tvb, pinfo, tree, p_tcapsrt_info);
2838
0
    break;
2839
2840
0
  case TC_CONT:
2841
#ifdef DEBUG_TCAPSRT
2842
    dbg(1,"\nTC_CONT ");
2843
#endif
2844
0
    tcap_context=tcaphash_cont_matching(tvb, pinfo, tree, p_tcapsrt_info);
2845
0
    break;
2846
2847
1
  case TC_ABORT:
2848
#ifdef DEBUG_TCAPSRT
2849
    dbg(1,"\nTC_ABORT ");
2850
#endif
2851
1
    tcap_context=tcaphash_end_matching(tvb, pinfo, tree, p_tcapsrt_info);
2852
1
    break;
2853
2854
0
  case TC_END:
2855
#ifdef DEBUG_TCAPSRT
2856
    dbg(1,"\nTC_END ");
2857
#endif
2858
0
    tcap_context=tcaphash_end_matching(tvb, pinfo, tree, p_tcapsrt_info);
2859
0
    break;
2860
2861
0
  case TC_ANSI_ALL:
2862
0
  case TC_ANSI_ABORT:
2863
#ifdef DEBUG_TCAPSRT
2864
    dbg(1,"\nTC_ANSI ");
2865
#endif
2866
0
    tcap_context=tcaphash_ansi_matching(tvb, pinfo, tree, p_tcapsrt_info);
2867
0
    break;
2868
2869
43
  default:
2870
#ifdef DEBUG_TCAPSRT
2871
    dbg(1,"\nUnknown %d ", p_tcapsrt_info->ope);
2872
#endif
2873
43
    break;
2874
44
  } /* switch tcapop */
2875
#ifdef DEBUG_TCAPSRT
2876
  if (tcap_context)
2877
    dbg(1,"session %d ", tcap_context->session_id);
2878
#endif
2879
44
  return tcap_context;
2880
44
}
2881
2882
/*
2883
 * Initialize the Message Info used by the main dissector
2884
 * Data are linked to a TCAP transaction
2885
 */
2886
struct tcapsrt_info_t *
2887
tcapsrt_razinfo(void)
2888
53
{
2889
53
  struct tcapsrt_info_t *p_tcapsrt_info ;
2890
2891
  /* Global buffer for packet extraction */
2892
53
  tcapsrt_global_current++;
2893
53
  if(tcapsrt_global_current==MAX_TCAP_INSTANCE){
2894
5
    tcapsrt_global_current=0;
2895
5
  }
2896
2897
53
  p_tcapsrt_info=&tcapsrt_global_info[tcapsrt_global_current];
2898
53
  memset(p_tcapsrt_info,0,sizeof(struct tcapsrt_info_t));
2899
2900
53
  return p_tcapsrt_info;
2901
53
}
2902
2903
void
2904
tcapsrt_close(struct tcaphash_context_t *p_tcaphash_context,
2905
              packet_info *pinfo)
2906
0
{
2907
#ifdef DEBUG_TCAPSRT
2908
  dbg(60,"Force close ");
2909
#endif
2910
0
  if (p_tcaphash_context) {
2911
0
    p_tcaphash_context->responded=true;
2912
0
    p_tcaphash_context->last_frame = pinfo->num;
2913
0
    p_tcaphash_context->end_time = pinfo->abs_ts;
2914
0
    p_tcaphash_context->closed=true;
2915
0
  }
2916
0
}
2917
2918
const value_string tcap_component_type_str[] = {
2919
  { TCAP_COMP_INVOKE, "Invoke" },
2920
  { TCAP_COMP_RRL,    "Return Result(L)" },
2921
  { TCAP_COMP_RE,     "Return Error" },
2922
  { TCAP_COMP_REJECT, "Reject" },
2923
  { TCAP_COMP_RRN,    "Return Result(NL)" },
2924
  { 0,                NULL }
2925
};
2926
2927
static int
2928
dissect_tcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data _U_)
2929
57
{
2930
57
  proto_item *item=NULL;
2931
57
  proto_tree *tree=NULL;
2932
2933
57
  struct tcaphash_context_t * p_tcap_context;
2934
57
  dissector_handle_t subdissector_handle;
2935
57
  asn1_ctx_t asn1_ctx;
2936
57
  int8_t ber_class;
2937
57
  bool pc;
2938
57
  int tag;
2939
57
  struct tcap_private_t *p_tcap_private;
2940
2941
  /* Check if ANSI TCAP and call the ANSI TCAP dissector if that's the case
2942
   * PackageType ::= CHOICE { unidirectional            [PRIVATE 1] IMPLICIT UniTransactionPDU,
2943
   *                          queryWithPerm             [PRIVATE 2] IMPLICIT TransactionPDU,
2944
   *                          queryWithoutPerm          [PRIVATE 3] IMPLICIT TransactionPDU,
2945
   *                          response                  [PRIVATE 4] IMPLICIT TransactionPDU,
2946
   *                          conversationWithPerm      [PRIVATE 5] IMPLICIT TransactionPDU,
2947
   *                          conversationWithoutPerm   [PRIVATE 6] IMPLICIT TransactionPDU,
2948
   *                          abort                     [PRIVATE 22] IMPLICIT Abort
2949
   *                          }
2950
   *
2951
   *
2952
   */
2953
57
  get_ber_identifier(tvb, 0, &ber_class, &pc, &tag);
2954
2955
57
  if(ber_class == BER_CLASS_PRI){
2956
8
    switch (tag){
2957
2958
0
    case 1:
2959
0
    case 2:
2960
2
    case 3:
2961
4
    case 4:
2962
4
    case 5:
2963
4
    case 6:
2964
4
    case 22:
2965
4
      return call_dissector(ansi_tcap_handle, tvb, pinfo, parent_tree);
2966
2967
4
    default:
2968
4
      return tvb_captured_length(tvb);
2969
8
    }
2970
8
  }
2971
2972
  /* ITU TCAP */
2973
49
  asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, true, pinfo);
2974
2975
49
  tcap_top_tree = parent_tree;
2976
49
  tcap_stat_tree = NULL;
2977
2978
49
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCAP");
2979
2980
  /* create display subtree for the protocol */
2981
49
  if(parent_tree){
2982
49
    item = proto_tree_add_item(parent_tree, proto_tcap, tvb, 0, -1, ENC_NA);
2983
49
    tree = proto_item_add_subtree(item, ett_tcap);
2984
49
    tcap_stat_tree=tree;
2985
49
  }
2986
49
  cur_oid = NULL;
2987
49
  tcapext_oid = NULL;
2988
2989
49
  p_tcap_private = wmem_new0(pinfo->pool, struct tcap_private_t);
2990
49
  asn1_ctx.value_ptr = p_tcap_private;
2991
49
  gp_tcapsrt_info=tcapsrt_razinfo();
2992
49
  tcap_subdissector_used=false;
2993
49
  gp_tcap_context=NULL;
2994
49
  dissect_tcap_TCMessage(false, tvb, 0, &asn1_ctx, tree, -1);
2995
2996
49
  if (!tcap_subdissector_used ) {
2997
44
    p_tcap_context=tcapsrt_call_matching(tvb, pinfo, tcap_stat_tree, gp_tcapsrt_info);
2998
44
    p_tcap_private->context=p_tcap_context;
2999
3000
    /* If the current message is TCAP only,
3001
     * save the Application Context Name for the next messages
3002
     */
3003
44
    if ( p_tcap_context && cur_oid && !p_tcap_context->oid_present ) {
3004
      /* Save the application context and the sub dissector */
3005
0
      (void) g_strlcpy(p_tcap_context->oid, cur_oid, sizeof(p_tcap_context->oid));
3006
0
      p_tcap_context->oid_present=true;
3007
0
      if ( (subdissector_handle = dissector_get_string_handle(ber_oid_dissector_table, cur_oid)) ) {
3008
0
        p_tcap_context->subdissector_handle=subdissector_handle;
3009
0
        p_tcap_context->subdissector_present=true;
3010
0
      }
3011
0
    }
3012
44
    if (p_tcap_context && p_tcap_context->callback) {
3013
      /* Callback function for the upper layer */
3014
0
      (p_tcap_context->callback)(tvb, pinfo, tcap_stat_tree, p_tcap_context);
3015
0
    }
3016
44
  }
3017
49
  return tvb_captured_length(tvb);
3018
57
}
3019
3020
void
3021
proto_reg_handoff_tcap(void)
3022
14
{
3023
3024
14
  data_handle = find_dissector("data");
3025
14
  ansi_tcap_handle = find_dissector_add_dependency("ansi_tcap", proto_tcap);
3026
14
  ber_oid_dissector_table = find_dissector_table("ber.oid");
3027
3028
14
  ss7pc_address_type = address_type_get_by_name("AT_SS7PC");
3029
3030
14
  register_ber_oid_dissector("0.0.17.773.1.1.1", dissect_DialoguePDU_PDU, proto_tcap, "id-as-dialogue");
3031
14
  register_ber_oid_dissector("0.0.17.773.1.2.1", dissect_UniDialoguePDU_PDU, proto_tcap, "id-as-uniDialogue");
3032
3033
14
}
3034
3035
static void init_tcap(void);
3036
static void cleanup_tcap(void);
3037
3038
void
3039
proto_register_tcap(void)
3040
14
{
3041
3042
/* Setup list of header fields  See Section 1.6.1 for details*/
3043
14
  static hf_register_info hf[] = {
3044
14
    { &hf_tcap_tag,
3045
14
      { "Tag",
3046
14
        "tcap.msgtype",
3047
14
        FT_UINT8, BASE_HEX, NULL, 0,
3048
14
        NULL, HFILL }
3049
14
    },
3050
14
    { &hf_tcap_length,
3051
14
      { "Length",
3052
14
        "tcap.len",
3053
14
        FT_UINT8, BASE_DEC, NULL, 0,
3054
14
        NULL, HFILL }
3055
14
    },
3056
14
    { &hf_tcap_data,
3057
14
      { "Data",
3058
14
        "tcap.data",
3059
14
        FT_BYTES, BASE_NONE, NULL, 0,
3060
14
        NULL, HFILL }
3061
14
    },
3062
14
    { &hf_tcap_tid,
3063
14
      { "Transaction Id",
3064
14
         "tcap.tid",
3065
14
        FT_BYTES, BASE_NONE, NULL, 0,
3066
14
        NULL, HFILL }
3067
14
    },
3068
14
    { &hf_tcap_constructor_eoc,
3069
14
      { "CONSTRUCTOR EOC",
3070
14
         "tcap.constructor_eoc",
3071
14
        FT_UINT16, BASE_HEX, NULL, 0,
3072
14
        NULL, HFILL }
3073
14
    },
3074
    /* Tcap Service Response Time */
3075
14
    { &hf_tcapsrt_SessionId,
3076
14
      { "Session Id",
3077
14
        "tcap.srt.session_id",
3078
14
        FT_UINT32, BASE_DEC, NULL, 0x0,
3079
14
        NULL, HFILL }
3080
14
    },
3081
14
    { &hf_tcapsrt_BeginSession,
3082
14
      { "Begin Session",
3083
14
        "tcap.srt.begin",
3084
14
        FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3085
14
        "SRT Begin of Session", HFILL }
3086
14
    },
3087
14
    { &hf_tcapsrt_EndSession,
3088
14
      { "End Session",
3089
14
        "tcap.srt.end",
3090
14
        FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3091
14
        "SRT End of Session", HFILL }
3092
14
    },
3093
14
    { &hf_tcapsrt_SessionTime,
3094
14
      { "Session duration",
3095
14
        "tcap.srt.sessiontime",
3096
14
        FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
3097
14
        "Duration of the TCAP session", HFILL }
3098
14
    },
3099
14
    { &hf_tcapsrt_Duplicate,
3100
14
      { "Session Duplicate",
3101
14
        "tcap.srt.duplicate",
3102
14
        FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3103
14
        "SRT Duplicated with Session", HFILL }
3104
14
    },
3105
14
    { &hf_tcap_UniDialoguePDU_PDU,
3106
14
      { "UniDialoguePDU", "tcap.UniDialoguePDU",
3107
14
        FT_UINT32, BASE_DEC, VALS(tcap_UniDialoguePDU_vals), 0,
3108
14
        NULL, HFILL }},
3109
14
    { &hf_tcap_DialoguePDU_PDU,
3110
14
      { "DialoguePDU", "tcap.DialoguePDU",
3111
14
        FT_UINT32, BASE_DEC, VALS(tcap_DialoguePDU_vals), 0,
3112
14
        NULL, HFILL }},
3113
14
    { &hf_tcap_oid,
3114
14
      { "oid", "tcap.oid",
3115
14
        FT_OID, BASE_NONE, NULL, 0,
3116
14
        "OBJECT_IDENTIFIER", HFILL }},
3117
14
    { &hf_tcap_dialog,
3118
14
      { "dialog", "tcap.dialog",
3119
14
        FT_BYTES, BASE_NONE, NULL, 0,
3120
14
        "Dialog1", HFILL }},
3121
14
    { &hf_tcap_unidirectional,
3122
14
      { "unidirectional", "tcap.unidirectional_element",
3123
14
        FT_NONE, BASE_NONE, NULL, 0,
3124
14
        NULL, HFILL }},
3125
14
    { &hf_tcap_begin,
3126
14
      { "begin", "tcap.begin_element",
3127
14
        FT_NONE, BASE_NONE, NULL, 0,
3128
14
        NULL, HFILL }},
3129
14
    { &hf_tcap_end,
3130
14
      { "end", "tcap.end_element",
3131
14
        FT_NONE, BASE_NONE, NULL, 0,
3132
14
        NULL, HFILL }},
3133
14
    { &hf_tcap_continue,
3134
14
      { "continue", "tcap.continue_element",
3135
14
        FT_NONE, BASE_NONE, NULL, 0,
3136
14
        NULL, HFILL }},
3137
14
    { &hf_tcap_abort,
3138
14
      { "abort", "tcap.abort_element",
3139
14
        FT_NONE, BASE_NONE, NULL, 0,
3140
14
        NULL, HFILL }},
3141
14
    { &hf_tcap_dialoguePortion,
3142
14
      { "dialoguePortion", "tcap.dialoguePortion",
3143
14
        FT_BYTES, BASE_NONE, NULL, 0,
3144
14
        NULL, HFILL }},
3145
14
    { &hf_tcap_components,
3146
14
      { "components", "tcap.components",
3147
14
        FT_UINT32, BASE_DEC, NULL, 0,
3148
14
        "ComponentPortion", HFILL }},
3149
14
    { &hf_tcap_otid,
3150
14
      { "otid", "tcap.otid",
3151
14
        FT_BYTES, BASE_NONE, NULL, 0,
3152
14
        "OrigTransactionID", HFILL }},
3153
14
    { &hf_tcap_dtid,
3154
14
      { "dtid", "tcap.dtid",
3155
14
        FT_BYTES, BASE_NONE, NULL, 0,
3156
14
        "DestTransactionID", HFILL }},
3157
14
    { &hf_tcap_reason,
3158
14
      { "reason", "tcap.reason",
3159
14
        FT_UINT32, BASE_DEC, VALS(tcap_Reason_vals), 0,
3160
14
        NULL, HFILL }},
3161
14
    { &hf_tcap_p_abortCause,
3162
14
      { "p-abortCause", "tcap.p_abortCause",
3163
14
        FT_UINT32, BASE_DEC, VALS(tcap_P_AbortCause_U_vals), 0,
3164
14
        NULL, HFILL }},
3165
14
    { &hf_tcap_u_abortCause,
3166
14
      { "u-abortCause", "tcap.u_abortCause",
3167
14
        FT_BYTES, BASE_NONE, NULL, 0,
3168
14
        "DialoguePortion", HFILL }},
3169
14
    { &hf_tcap__untag_item,
3170
14
      { "Component", "tcap.Component",
3171
14
        FT_UINT32, BASE_DEC, VALS(tcap_Component_vals), 0,
3172
14
        NULL, HFILL }},
3173
14
    { &hf_tcap_invoke,
3174
14
      { "invoke", "tcap.invoke_element",
3175
14
        FT_NONE, BASE_NONE, NULL, 0,
3176
14
        NULL, HFILL }},
3177
14
    { &hf_tcap_returnResultLast,
3178
14
      { "returnResultLast", "tcap.returnResultLast_element",
3179
14
        FT_NONE, BASE_NONE, NULL, 0,
3180
14
        "ReturnResult", HFILL }},
3181
14
    { &hf_tcap_returnError,
3182
14
      { "returnError", "tcap.returnError_element",
3183
14
        FT_NONE, BASE_NONE, NULL, 0,
3184
14
        NULL, HFILL }},
3185
14
    { &hf_tcap_reject,
3186
14
      { "reject", "tcap.reject_element",
3187
14
        FT_NONE, BASE_NONE, NULL, 0,
3188
14
        NULL, HFILL }},
3189
14
    { &hf_tcap_returnResultNotLast,
3190
14
      { "returnResultNotLast", "tcap.returnResultNotLast_element",
3191
14
        FT_NONE, BASE_NONE, NULL, 0,
3192
14
        "ReturnResult", HFILL }},
3193
14
    { &hf_tcap_invokeID,
3194
14
      { "invokeID", "tcap.invokeID",
3195
14
        FT_INT32, BASE_DEC, NULL, 0,
3196
14
        "InvokeIdType", HFILL }},
3197
14
    { &hf_tcap_linkedID,
3198
14
      { "linkedID", "tcap.linkedID",
3199
14
        FT_INT32, BASE_DEC, NULL, 0,
3200
14
        "InvokeIdType", HFILL }},
3201
14
    { &hf_tcap_opCode,
3202
14
      { "opCode", "tcap.opCode",
3203
14
        FT_UINT32, BASE_DEC, VALS(tcap_OPERATION_vals), 0,
3204
14
        "OPERATION", HFILL }},
3205
14
    { &hf_tcap_parameter,
3206
14
      { "parameter", "tcap.parameter_element",
3207
14
        FT_NONE, BASE_NONE, NULL, 0,
3208
14
        NULL, HFILL }},
3209
14
    { &hf_tcap_resultretres,
3210
14
      { "resultretres", "tcap.resultretres_element",
3211
14
        FT_NONE, BASE_NONE, NULL, 0,
3212
14
        NULL, HFILL }},
3213
14
    { &hf_tcap_errorCode,
3214
14
      { "errorCode", "tcap.errorCode",
3215
14
        FT_UINT32, BASE_DEC, VALS(tcap_ErrorCode_vals), 0,
3216
14
        NULL, HFILL }},
3217
14
    { &hf_tcap_invokeIDRej,
3218
14
      { "invokeIDRej", "tcap.invokeIDRej",
3219
14
        FT_UINT32, BASE_DEC, VALS(tcap_T_invokeIDRej_vals), 0,
3220
14
        NULL, HFILL }},
3221
14
    { &hf_tcap_derivable,
3222
14
      { "derivable", "tcap.derivable",
3223
14
        FT_INT32, BASE_DEC, NULL, 0,
3224
14
        "InvokeIdType", HFILL }},
3225
14
    { &hf_tcap_not_derivable,
3226
14
      { "not-derivable", "tcap.not_derivable_element",
3227
14
        FT_NONE, BASE_NONE, NULL, 0,
3228
14
        NULL, HFILL }},
3229
14
    { &hf_tcap_problem,
3230
14
      { "problem", "tcap.problem",
3231
14
        FT_UINT32, BASE_DEC, VALS(tcap_T_problem_vals), 0,
3232
14
        NULL, HFILL }},
3233
14
    { &hf_tcap_generalProblem,
3234
14
      { "generalProblem", "tcap.generalProblem",
3235
14
        FT_INT32, BASE_DEC, VALS(tcap_GeneralProblem_vals), 0,
3236
14
        NULL, HFILL }},
3237
14
    { &hf_tcap_invokeProblem,
3238
14
      { "invokeProblem", "tcap.invokeProblem",
3239
14
        FT_INT32, BASE_DEC, VALS(tcap_InvokeProblem_vals), 0,
3240
14
        NULL, HFILL }},
3241
14
    { &hf_tcap_returnResultProblem,
3242
14
      { "returnResultProblem", "tcap.returnResultProblem",
3243
14
        FT_INT32, BASE_DEC, VALS(tcap_ReturnResultProblem_vals), 0,
3244
14
        NULL, HFILL }},
3245
14
    { &hf_tcap_returnErrorProblem,
3246
14
      { "returnErrorProblem", "tcap.returnErrorProblem",
3247
14
        FT_INT32, BASE_DEC, VALS(tcap_ReturnErrorProblem_vals), 0,
3248
14
        NULL, HFILL }},
3249
14
    { &hf_tcap_localValue,
3250
14
      { "localValue", "tcap.localValue",
3251
14
        FT_INT32, BASE_DEC, NULL, 0,
3252
14
        "INTEGER", HFILL }},
3253
14
    { &hf_tcap_globalValue,
3254
14
      { "globalValue", "tcap.globalValue",
3255
14
        FT_OID, BASE_NONE, NULL, 0,
3256
14
        "OBJECT_IDENTIFIER", HFILL }},
3257
14
    { &hf_tcap_nationaler,
3258
14
      { "nationaler", "tcap.nationaler",
3259
14
        FT_INT32, BASE_DEC, NULL, 0,
3260
14
        "INTEGER_M32768_32767", HFILL }},
3261
14
    { &hf_tcap_privateer,
3262
14
      { "privateer", "tcap.privateer",
3263
14
        FT_INT32, BASE_DEC, NULL, 0,
3264
14
        "INTEGER", HFILL }},
3265
14
    { &hf_tcap_unidialoguePDU,
3266
14
      { "unidialoguePDU", "tcap.unidialoguePDU_element",
3267
14
        FT_NONE, BASE_NONE, NULL, 0,
3268
14
        "AUDT_apdu", HFILL }},
3269
14
    { &hf_tcap_audt_protocol_version,
3270
14
      { "protocol-version", "tcap.audt_protocol_version",
3271
14
        FT_BYTES, BASE_NONE, NULL, 0,
3272
14
        "AUDT_protocol_version", HFILL }},
3273
14
    { &hf_tcap_audt_application_context_name,
3274
14
      { "application-context-name", "tcap.audt_application_context_name",
3275
14
        FT_OID, BASE_NONE, NULL, 0,
3276
14
        "AUDT_application_context_name", HFILL }},
3277
14
    { &hf_tcap_audt_user_information,
3278
14
      { "user-information", "tcap.audt_user_information",
3279
14
        FT_UINT32, BASE_DEC, NULL, 0,
3280
14
        "AUDT_user_information", HFILL }},
3281
14
    { &hf_tcap_audt_user_information_item,
3282
14
      { "user-information item", "tcap.audt_user_information_item_element",
3283
14
        FT_NONE, BASE_NONE, NULL, 0,
3284
14
        "EXTERNAL", HFILL }},
3285
14
    { &hf_tcap_dialogueRequest,
3286
14
      { "dialogueRequest", "tcap.dialogueRequest_element",
3287
14
        FT_NONE, BASE_NONE, NULL, 0,
3288
14
        "AARQ_apdu", HFILL }},
3289
14
    { &hf_tcap_dialogueResponse,
3290
14
      { "dialogueResponse", "tcap.dialogueResponse_element",
3291
14
        FT_NONE, BASE_NONE, NULL, 0,
3292
14
        "AARE_apdu", HFILL }},
3293
14
    { &hf_tcap_dialogueAbort,
3294
14
      { "dialogueAbort", "tcap.dialogueAbort_element",
3295
14
        FT_NONE, BASE_NONE, NULL, 0,
3296
14
        "ABRT_apdu", HFILL }},
3297
14
    { &hf_tcap_aarq_protocol_version,
3298
14
      { "protocol-version", "tcap.aarq_protocol_version",
3299
14
        FT_BYTES, BASE_NONE, NULL, 0,
3300
14
        "AARQ_protocol_version", HFILL }},
3301
14
    { &hf_tcap_aarq_application_context_name,
3302
14
      { "application-context-name", "tcap.aarq_application_context_name",
3303
14
        FT_OID, BASE_NONE, NULL, 0,
3304
14
        "AARQ_application_context_name", HFILL }},
3305
14
    { &hf_tcap_aarq_user_information,
3306
14
      { "user-information", "tcap.aarq_user_information",
3307
14
        FT_UINT32, BASE_DEC, NULL, 0,
3308
14
        "AARQ_user_information", HFILL }},
3309
14
    { &hf_tcap_aarq_user_information_item,
3310
14
      { "user-information item", "tcap.aarq_user_information_item_element",
3311
14
        FT_NONE, BASE_NONE, NULL, 0,
3312
14
        "EXTERNAL", HFILL }},
3313
14
    { &hf_tcap_aare_protocol_version,
3314
14
      { "protocol-version", "tcap.aare_protocol_version",
3315
14
        FT_BYTES, BASE_NONE, NULL, 0,
3316
14
        "AARE_protocol_version", HFILL }},
3317
14
    { &hf_tcap_aare_application_context_name,
3318
14
      { "application-context-name", "tcap.aare_application_context_name",
3319
14
        FT_OID, BASE_NONE, NULL, 0,
3320
14
        "AARE_application_context_name", HFILL }},
3321
14
    { &hf_tcap_result,
3322
14
      { "result", "tcap.result",
3323
14
        FT_INT32, BASE_DEC, VALS(tcap_Associate_result_vals), 0,
3324
14
        "Associate_result", HFILL }},
3325
14
    { &hf_tcap_result_source_diagnostic,
3326
14
      { "result-source-diagnostic", "tcap.result_source_diagnostic",
3327
14
        FT_UINT32, BASE_DEC, VALS(tcap_Associate_source_diagnostic_vals), 0,
3328
14
        "Associate_source_diagnostic", HFILL }},
3329
14
    { &hf_tcap_aare_user_information,
3330
14
      { "user-information", "tcap.aare_user_information",
3331
14
        FT_UINT32, BASE_DEC, NULL, 0,
3332
14
        "AARE_user_information", HFILL }},
3333
14
    { &hf_tcap_aare_user_information_item,
3334
14
      { "user-information item", "tcap.aare_user_information_item_element",
3335
14
        FT_NONE, BASE_NONE, NULL, 0,
3336
14
        "EXTERNAL", HFILL }},
3337
14
    { &hf_tcap_abort_source,
3338
14
      { "abort-source", "tcap.abort_source",
3339
14
        FT_INT32, BASE_DEC, VALS(tcap_ABRT_source_vals), 0,
3340
14
        "ABRT_source", HFILL }},
3341
14
    { &hf_tcap_abrt_user_information,
3342
14
      { "user-information", "tcap.abrt_user_information",
3343
14
        FT_UINT32, BASE_DEC, NULL, 0,
3344
14
        "ABRT_user_information", HFILL }},
3345
14
    { &hf_tcap_abrt_user_information_item,
3346
14
      { "user-information item", "tcap.abrt_user_information_item_element",
3347
14
        FT_NONE, BASE_NONE, NULL, 0,
3348
14
        "EXTERNAL", HFILL }},
3349
14
    { &hf_tcap_dialogue_service_user,
3350
14
      { "dialogue-service-user", "tcap.dialogue_service_user",
3351
14
        FT_INT32, BASE_DEC, VALS(tcap_T_dialogue_service_user_vals), 0,
3352
14
        NULL, HFILL }},
3353
14
    { &hf_tcap_dialogue_service_provider,
3354
14
      { "dialogue-service-provider", "tcap.dialogue_service_provider",
3355
14
        FT_INT32, BASE_DEC, VALS(tcap_T_dialogue_service_provider_vals), 0,
3356
14
        NULL, HFILL }},
3357
14
    { &hf_tcap_AUDT_protocol_version_version1,
3358
14
      { "version1", "tcap.AUDT.protocol.version.version1",
3359
14
        FT_BOOLEAN, 8, NULL, 0x80,
3360
14
        NULL, HFILL }},
3361
14
    { &hf_tcap_AARQ_protocol_version_version1,
3362
14
      { "version1", "tcap.AARQ.protocol.version.version1",
3363
14
        FT_BOOLEAN, 8, NULL, 0x80,
3364
14
        NULL, HFILL }},
3365
14
    { &hf_tcap_AARE_protocol_version_version1,
3366
14
      { "version1", "tcap.AARE.protocol.version.version1",
3367
14
        FT_BOOLEAN, 8, NULL, 0x80,
3368
14
        NULL, HFILL }},
3369
14
  };
3370
3371
/* Setup protocol subtree array */
3372
14
  static int *ett[] = {
3373
14
    &ett_tcap,
3374
14
    &ett_param,
3375
14
    &ett_otid,
3376
14
    &ett_dtid,
3377
14
    &ett_tcap_stat,
3378
14
    &ett_tcap_ExternalPDU_U,
3379
14
    &ett_tcap_TCMessage,
3380
14
    &ett_tcap_Unidirectional,
3381
14
    &ett_tcap_Begin,
3382
14
    &ett_tcap_End,
3383
14
    &ett_tcap_Continue,
3384
14
    &ett_tcap_Abort,
3385
14
    &ett_tcap_Reason,
3386
14
    &ett_tcap_SEQUENCE_SIZE_1_MAX_OF_Component,
3387
14
    &ett_tcap_Component,
3388
14
    &ett_tcap_Invoke,
3389
14
    &ett_tcap_ReturnResult,
3390
14
    &ett_tcap_T_resultretres,
3391
14
    &ett_tcap_ReturnError,
3392
14
    &ett_tcap_Reject,
3393
14
    &ett_tcap_T_invokeIDRej,
3394
14
    &ett_tcap_T_problem,
3395
14
    &ett_tcap_OPERATION,
3396
14
    &ett_tcap_ErrorCode,
3397
14
    &ett_tcap_UniDialoguePDU,
3398
14
    &ett_tcap_AUDT_apdu_U,
3399
14
    &ett_tcap_AUDT_protocol_version,
3400
14
    &ett_tcap_AUDT_user_information,
3401
14
    &ett_tcap_DialoguePDU,
3402
14
    &ett_tcap_AARQ_apdu_U,
3403
14
    &ett_tcap_AARQ_protocol_version,
3404
14
    &ett_tcap_AARQ_user_information,
3405
14
    &ett_tcap_AARE_apdu_U,
3406
14
    &ett_tcap_AARE_protocol_version,
3407
14
    &ett_tcap_AARE_user_information,
3408
14
    &ett_tcap_ABRT_apdu_U,
3409
14
    &ett_tcap_ABRT_user_information,
3410
14
    &ett_tcap_Associate_source_diagnostic,
3411
14
  };
3412
3413
  /*static enum_val_t tcap_options[] = {
3414
    { "itu", "ITU",  ITU_TCAP_STANDARD },
3415
    { "ansi", "ANSI", ANSI_TCAP_STANDARD },
3416
    { NULL, NULL, 0 }
3417
  };*/
3418
3419
14
  module_t *tcap_module;
3420
3421
/* Register the protocol name and description */
3422
14
  proto_tcap = proto_register_protocol(PNAME, PSNAME, PFNAME);
3423
3424
/* Required function calls to register the header fields and subtrees used */
3425
14
  proto_register_field_array(proto_tcap, hf, array_length(hf));
3426
14
  proto_register_subtree_array(ett, array_length(ett));
3427
3428
14
  ansi_sub_dissectors = register_dissector_table("ansi_tcap.ssn", "ANSI SSN", proto_tcap, FT_UINT8, BASE_DEC);
3429
14
  itu_sub_dissectors = register_dissector_table("itu_tcap.ssn", "ITU SSN", proto_tcap, FT_UINT8, BASE_DEC);
3430
3431
14
  tcap_module = prefs_register_protocol(proto_tcap, NULL);
3432
3433
#if 0
3434
  prefs_register_enum_preference(tcap_module, "standard", "ITU TCAP standard",
3435
                                 "The SS7 standard used in ITU TCAP packets",
3436
                                 &tcap_standard, tcap_options, false);
3437
#else
3438
14
  prefs_register_obsolete_preference(tcap_module, "standard");
3439
14
#endif
3440
3441
#if 0
3442
  prefs_register_bool_preference(tcap_module, "lock_info_col", "Lock Info column",
3443
                                 "Always show TCAP in Info column",
3444
                                 &lock_info_col);
3445
#else
3446
14
  prefs_register_obsolete_preference(tcap_module, "lock_info_col");
3447
14
#endif
3448
3449
  /* Set default SSNs */
3450
14
  range_convert_str(wmem_epan_scope(), &global_ssn_range, "", MAX_SSN);
3451
3452
14
  prefs_register_range_preference(tcap_module, "ssn", "SCCP SSNs",
3453
14
                                  "SCCP (and SUA) SSNs to decode as TCAP",
3454
14
                                  &global_ssn_range, MAX_SSN);
3455
3456
14
  prefs_register_obsolete_preference(tcap_module, "srt");
3457
3458
14
  prefs_register_obsolete_preference(tcap_module, "persistentsrt");
3459
3460
14
  prefs_register_uint_preference(tcap_module, "repetitiontimeout",
3461
14
                                 "Repetition timeout",
3462
14
                                 "Maximal delay for message repetition",
3463
14
                                 10, &gtcap_RepetitionTimeout);
3464
3465
14
  prefs_register_uint_preference(tcap_module, "losttimeout",
3466
14
                                 "Lost timeout",
3467
14
                                 "Maximal delay for message lost",
3468
14
                                 10, &gtcap_LostTimeout);
3469
3470
  /* 'globally' register dissector */
3471
14
  tcap_handle = register_dissector("tcap", dissect_tcap, proto_tcap);
3472
3473
  /* hash-tables for SRT */
3474
14
  tcaphash_context = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), tcaphash_context_calchash, tcaphash_context_equal);
3475
14
  tcaphash_begin   = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), tcaphash_begin_calchash, tcaphash_begin_equal);
3476
14
  tcaphash_cont    = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), tcaphash_cont_calchash, tcaphash_cont_equal);
3477
14
  tcaphash_end     = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), tcaphash_end_calchash, tcaphash_end_equal);
3478
14
  tcaphash_ansi    = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), tcaphash_ansi_calchash, tcaphash_ansi_equal);
3479
3480
14
  register_init_routine(&init_tcap);
3481
14
  register_cleanup_routine(&cleanup_tcap);
3482
14
}
3483
3484
3485
static void range_delete_callback(uint32_t ssn, void *ptr _U_)
3486
0
{
3487
0
  if ( ssn && !get_ansi_tcap_subdissector(ssn) && !get_itu_tcap_subdissector(ssn) ) {
3488
0
    dissector_delete_uint("sccp.ssn", ssn, tcap_handle);
3489
0
  }
3490
0
}
3491
3492
static void range_add_callback(uint32_t ssn, void *ptr _U_)
3493
0
{
3494
0
  if (ssn && !get_ansi_tcap_subdissector(ssn) && !get_itu_tcap_subdissector(ssn) ) {
3495
0
    dissector_add_uint("sccp.ssn", ssn, tcap_handle);
3496
0
  }
3497
0
}
3498
3499
3500
static void init_tcap(void)
3501
14
{
3502
14
  ssn_range = range_copy(wmem_epan_scope(), global_ssn_range);
3503
14
  range_foreach(ssn_range, range_add_callback, NULL);
3504
3505
  /* Reset the session counter */
3506
14
  tcapsrt_global_SessionId=1;
3507
14
}
3508
3509
static void cleanup_tcap(void)
3510
0
{
3511
0
  range_foreach(ssn_range, range_delete_callback, NULL);
3512
0
  wmem_free(wmem_epan_scope(), ssn_range);
3513
0
}
3514
3515
static int
3516
// NOLINTNEXTLINE(misc-no-recursion)
3517
dissect_tcap_param(asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset)
3518
0
{
3519
0
  int tag_offset, saved_offset, len_offset;
3520
0
  tvbuff_t *next_tvb;
3521
0
  proto_tree *subtree;
3522
0
  int8_t ber_class;
3523
0
  bool pc;
3524
0
  int32_t tag;
3525
0
  uint32_t len;
3526
0
  uint32_t tag_length;
3527
0
  uint32_t len_length;
3528
0
  bool ind_field;
3529
3530
0
  while (tvb_reported_length_remaining(tvb, offset) > 0)
3531
0
  {
3532
0
    saved_offset = offset;
3533
3534
0
    offset = get_ber_identifier(tvb, offset, &ber_class, &pc, &tag);
3535
0
    tag_offset = offset;
3536
0
    offset = get_ber_length(tvb, offset, &len, &ind_field);
3537
0
    len_offset = offset;
3538
3539
0
    tag_length = tag_offset - saved_offset;
3540
0
    len_length = len_offset - tag_offset;
3541
3542
0
    if (pc)
3543
0
    {
3544
0
      subtree = proto_tree_add_subtree(tree, tvb, saved_offset,
3545
0
        len + (len_offset - saved_offset), ett_param, NULL,
3546
0
        "CONSTRUCTOR");
3547
0
      proto_tree_add_uint_format(subtree, hf_tcap_tag, tvb,
3548
0
        saved_offset, tag_length, tag,
3549
0
        "CONSTRUCTOR Tag");
3550
0
      proto_tree_add_uint(subtree, hf_tcap_tag, tvb, saved_offset,
3551
0
        tag_length, ber_class);
3552
3553
0
      proto_tree_add_uint(subtree, hf_tcap_length, tvb, tag_offset,
3554
0
        len_length, len);
3555
3556
0
      if (len - (ind_field ? 2 : 0)) /*should always be positive unless we get an empty constructor pointless? */
3557
0
      {
3558
0
        next_tvb = tvb_new_subset_length(tvb, offset, len - (ind_field ? 2 : 0));
3559
0
        increment_dissection_depth(actx->pinfo);
3560
0
        dissect_tcap_param(actx, subtree,next_tvb,0);
3561
0
        decrement_dissection_depth(actx->pinfo);
3562
0
      }
3563
3564
0
      if (ind_field)
3565
0
        proto_tree_add_item(subtree, hf_tcap_constructor_eoc, tvb, offset+len-2, 2, ENC_BIG_ENDIAN);
3566
3567
0
      offset += len;
3568
0
    }
3569
0
    else
3570
0
    {
3571
0
      subtree = proto_tree_add_subtree_format(tree, tvb, saved_offset,
3572
0
        len + (len_offset - saved_offset), ett_param, NULL,
3573
0
        "Parameter (0x%.2x)", tag);
3574
3575
0
      proto_tree_add_uint(subtree, hf_tcap_tag, tvb, saved_offset,
3576
0
        tag_length, tag);
3577
3578
0
      proto_tree_add_uint(subtree, hf_tcap_length, tvb,
3579
0
        saved_offset+tag_length, len_length, len);
3580
3581
0
      if (len) /* check for NULLS */
3582
0
      {
3583
0
        next_tvb = tvb_new_subset_length(tvb, offset, len);
3584
0
        dissect_ber_octet_string(true, actx, tree, next_tvb, 0,
3585
0
          hf_tcap_data, NULL);
3586
0
      }
3587
3588
0
      offset += len;
3589
0
    }
3590
0
  }
3591
0
  return offset;
3592
0
}
3593
3594
/*
3595
 * Call ITU Subdissector to decode the Tcap Component
3596
 */
3597
static bool
3598
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_)
3599
0
{
3600
0
  dissector_handle_t subdissector_handle=NULL;
3601
0
  bool is_subdissector=false;
3602
0
  struct tcaphash_context_t * p_tcap_context=NULL;
3603
0
  struct tcap_private_t *p_tcap_private = (struct tcap_private_t*)actx->value_ptr;
3604
3605
  /*
3606
   * ok lets look at the oid and ssn and try and find a dissector, otherwise lets decode it.
3607
   */
3608
3609
  /*
3610
   * Handle The TCAP Service Response Time
3611
   */
3612
0
  if (!tcap_subdissector_used) {
3613
0
    p_tcap_context=tcapsrt_call_matching(tvb, actx->pinfo, tcap_stat_tree, gp_tcapsrt_info);
3614
0
    tcap_subdissector_used=false;
3615
0
    gp_tcap_context=p_tcap_context;
3616
0
    p_tcap_private->context=p_tcap_context;
3617
0
  } else {
3618
    /* Take the last TCAP context */
3619
0
    p_tcap_context = gp_tcap_context;
3620
0
    p_tcap_private->context=p_tcap_context;
3621
0
  }
3622
0
  if (p_tcap_context) {
3623
0
      if (cur_oid) {
3624
0
          if (p_tcap_context->oid_present) {
3625
              /* We have already an Application Context, check if we have
3626
                 to fallback to a lower version */
3627
0
              if (strncmp(p_tcap_context->oid, cur_oid, sizeof(p_tcap_context->oid)) != 0) {
3628
                  /* ACN, changed, Fallback to lower version
3629
                   * and update the subdissector (purely formal)
3630
                   */
3631
0
                  (void) g_strlcpy(p_tcap_context->oid, cur_oid, sizeof(p_tcap_context->oid));
3632
0
                  if ((subdissector_handle = dissector_get_string_handle(ber_oid_dissector_table, cur_oid))) {
3633
0
                      p_tcap_context->subdissector_handle = subdissector_handle;
3634
0
                      p_tcap_context->subdissector_present = true;
3635
0
                  }
3636
0
              }
3637
0
          } else {
3638
              /* We do not have the OID in the TCAP context, so store it */
3639
0
              (void) g_strlcpy(p_tcap_context->oid, cur_oid, sizeof(p_tcap_context->oid));
3640
0
              p_tcap_context->oid_present = true;
3641
              /* Try to find a subdissector according to OID */
3642
0
              if ((subdissector_handle
3643
0
                  = dissector_get_string_handle(ber_oid_dissector_table, cur_oid))) {
3644
0
                  p_tcap_context->subdissector_handle = subdissector_handle;
3645
0
                  p_tcap_context->subdissector_present = true;
3646
0
              } else {
3647
                  /* Not found, so try to find a subdissector according to SSN */
3648
0
                  if ((subdissector_handle = get_itu_tcap_subdissector(actx->pinfo->match_uint))) {
3649
                      /* Found according to SSN */
3650
0
                      p_tcap_context->subdissector_handle = subdissector_handle;
3651
0
                      p_tcap_context->subdissector_present = true;
3652
0
                  }
3653
0
              }
3654
0
          } /* context OID */
3655
0
      } else {
3656
          /* Copy the OID from the TCAP context to the current oid */
3657
0
          if (p_tcap_context->oid_present) {
3658
0
              p_tcap_private->oid = (void*)p_tcap_context->oid;
3659
0
              p_tcap_private->acv = true;
3660
0
          }
3661
0
      } /* no OID */
3662
0
  } /* no TCAP context */
3663
3664
3665
0
  if (p_tcap_context
3666
0
      && p_tcap_context->subdissector_present) {
3667
      /* Take the subdissector from the context */
3668
0
      subdissector_handle = p_tcap_context->subdissector_handle;
3669
0
      is_subdissector = true;
3670
0
  }
3671
3672
  /* Have SccpUsersTable protocol taking precedence over sccp.ssn table */
3673
0
  if (!is_subdissector && requested_subdissector_handle) {
3674
0
      is_subdissector = true;
3675
0
      subdissector_handle = requested_subdissector_handle;
3676
0
  }
3677
3678
0
  if (!is_subdissector) {
3679
      /*
3680
       * If we do not currently know the subdissector, we have to find it
3681
       * - first, according to the OID
3682
       * - then according to the SSN
3683
       * - and at least, take the default Data handler
3684
       */
3685
0
      if (ber_oid_dissector_table && cur_oid) {
3686
          /* Search if we can find the sub protocol according to the A.C.N */
3687
0
          if ((subdissector_handle
3688
0
              = dissector_get_string_handle(ber_oid_dissector_table, cur_oid))) {
3689
              /* found */
3690
0
              is_subdissector = true;
3691
0
          } else {
3692
              /* Search if we can found the sub protocol according to the SSN table */
3693
0
              if ((subdissector_handle
3694
0
                  = get_itu_tcap_subdissector(actx->pinfo->match_uint))) {
3695
                  /* Found according to SSN */
3696
0
                  is_subdissector = true;
3697
0
              } else {
3698
                  /* Nothing found, take the Data handler */
3699
0
                  subdissector_handle = data_handle;
3700
0
                  is_subdissector = true;
3701
0
              } /* SSN */
3702
0
          } /* ACN */
3703
0
      } else {
3704
          /* There is no A.C.N for this transaction, so search in the SSN table */
3705
0
          if ((subdissector_handle = get_itu_tcap_subdissector(actx->pinfo->match_uint))) {
3706
              /* Found according to SSN */
3707
0
              is_subdissector = true;
3708
0
          } else {
3709
0
              subdissector_handle = data_handle;
3710
0
              is_subdissector = true;
3711
0
          }
3712
0
      } /* OID */
3713
0
  } else {
3714
      /* We have it already */
3715
0
  }
3716
3717
  /* Call the sub dissector if present, and not already called */
3718
0
  if (is_subdissector) {
3719
0
      bool is_active = call_dissector_only(subdissector_handle, tvb, actx->pinfo, tree, actx->value_ptr);
3720
0
      col_set_fence(actx->pinfo->cinfo, COL_INFO);
3721
0
      if(!is_active){
3722
0
          return false;
3723
0
    }
3724
0
  }
3725
0
  return true;
3726
0
}
3727
3728
void
3729
call_tcap_dissector(dissector_handle_t handle, tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree)
3730
0
{
3731
0
  requested_subdissector_handle = handle;
3732
3733
0
  TRY {
3734
0
    dissect_tcap(tvb, pinfo, tree, NULL);
3735
0
  } CATCH_ALL {
3736
0
    requested_subdissector_handle = NULL;
3737
0
    RETHROW;
3738
0
  } ENDTRY;
3739
3740
  requested_subdissector_handle = NULL;
3741
0
}
3742
3743
/*
3744
 * Editor modelines
3745
 *
3746
 * Local Variables:
3747
 * c-basic-offset: 2
3748
 * tab-width: 8
3749
 * indent-tabs-mode: nil
3750
 * End:
3751
 *
3752
 * ex: set shiftwidth=2 tabstop=8 expandtab:
3753
 * :indentSize=2:tabSize=8:noTabs=true:
3754
 */