2 * tcap-persistentdata.c
3 * Source for lists and hash tables used in wireshark's tcap dissector
4 * for calculation of delays in tcap-calls
5 * Copyright 2006 Florent Drouin (based on h225-persistentdata.c from Lars Roland)
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 #include <epan/emem.h>
34 #include <epan/packet.h>
35 #include <epan/asn1.h>
36 #include <epan/tcap-persistentdata.h>
37 #include <epan/dissectors/packet-tcap.h>
38 #include <epan/dissectors/packet-mtp3.h>
40 static gint tcaphash_context_equal(gconstpointer k1, gconstpointer k2);
41 static guint tcaphash_context_calchash(gconstpointer k);
42 static gint tcaphash_begin_equal(gconstpointer k1, gconstpointer k2);
43 static guint tcaphash_begin_calchash(gconstpointer k);
44 static gint tcaphash_cont_equal(gconstpointer k1, gconstpointer k2);
45 static guint tcaphash_cont_calchash(gconstpointer k);
46 static gint tcaphash_end_equal(gconstpointer k1, gconstpointer k2);
47 static guint tcaphash_end_calchash(gconstpointer k);
48 static gint tcaphash_ansi_equal(gconstpointer k1, gconstpointer k2);
49 static guint tcaphash_ansi_calchash(gconstpointer k);
51 static void update_tcaphash_begincall(struct tcaphash_begincall_t *p_tcaphash_begincall,
54 static struct tcaphash_begincall_t *append_tcaphash_begincall(struct tcaphash_begincall_t *prev_begincall,
55 struct tcaphash_context_t *p_tcaphash_context,
59 static struct tcaphash_begincall_t *find_tcaphash_begin(struct tcaphash_begin_info_key_t *p_tcaphash_begin_key,
64 static struct tcaphash_contcall_t *find_tcaphash_cont(struct tcaphash_cont_info_key_t *p_tcaphash_cont_key,
67 static struct tcaphash_endcall_t *find_tcaphash_end(struct tcaphash_end_info_key_t *p_tcaphash_end_key,
71 static struct tcaphash_context_t *new_tcaphash_context(struct tcaphash_context_key_t *p_tcaphash_context_key,
74 static struct tcaphash_begincall_t *new_tcaphash_begin(struct tcaphash_begin_info_key_t *p_tcaphash_begin_key,
75 struct tcaphash_context_t *p_tcaphash_context);
77 static struct tcaphash_contcall_t *new_tcaphash_cont(struct tcaphash_cont_info_key_t *p_tcaphash_cont_key,
78 struct tcaphash_context_t *p_tcaphash_context);
80 static struct tcaphash_endcall_t *new_tcaphash_end(struct tcaphash_end_info_key_t *p_tcaphash_end_key,
81 struct tcaphash_context_t *p_tcaphash_context);
83 static struct tcaphash_context_t *tcaphash_begin_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
84 struct tcapsrt_info_t *p_tcapsrt_info);
86 static struct tcaphash_context_t *tcaphash_cont_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
87 struct tcapsrt_info_t *p_tcapsrt_info);
89 static struct tcaphash_context_t *tcaphash_end_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
90 struct tcapsrt_info_t *p_tcapsrt_info);
92 static struct tcaphash_context_t *tcaphash_ansi_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
93 struct tcapsrt_info_t *p_tcapsrt_info);
95 struct tcapsrt_info_t *tcapsrt_razinfo(void);
97 /* When several Tcap components are received in a single TCAP message,
98 we have to use several buffers for the stored parameters
99 because else this data are erased during TAP dissector call */
100 #define MAX_TCAP_INSTANCE 10
101 int tcapsrt_global_current=0;
102 struct tcapsrt_info_t tcapsrt_global_info[MAX_TCAP_INSTANCE];
104 /* These two timeout (in second) are used when some message are lost,
105 or when the same TCAP transcation identifier is reused */
106 guint gtcap_RepetitionTimeout = 10;
107 guint gtcap_LostTimeout = 30;
108 extern gboolean gtcap_HandleSRT;
109 gboolean gtcap_PersistentSRT=FALSE;
110 gboolean gtcap_DisplaySRT=FALSE;
111 gboolean gtcap_StatSRT=FALSE;
113 extern gint ett_tcap_stat;
115 extern int hf_tcapsrt_SessionId;
116 extern int hf_tcapsrt_Duplicate;
117 extern int hf_tcapsrt_BeginSession;
118 extern int hf_tcapsrt_EndSession;
119 extern int hf_tcapsrt_SessionTime;
121 /* Global hash tables*/
122 static GHashTable *tcaphash_context = NULL;
123 static GHashTable *tcaphash_begin = NULL;
124 static GHashTable *tcaphash_cont = NULL;
125 static GHashTable *tcaphash_end = NULL;
126 static GHashTable *tcaphash_ansi = NULL;
128 guint32 tcapsrt_global_SessionId=1;
134 /* #define MEM_TCAPSRT */
137 /* #define DEBUG_TCAPSRT */
142 static guint debug_level = 99;
145 dbg(guint level, char* fmt, ...)
149 if (level > debug_level) return;
151 vfprintf(stderr, fmt, ap);
157 tcaphash_context_equal(gconstpointer k1, gconstpointer k2)
159 const struct tcaphash_context_key_t *key1 = (const struct tcaphash_context_key_t *) k1;
160 const struct tcaphash_context_key_t *key2 = (const struct tcaphash_context_key_t *) k2;
162 return (key1->session_id == key2->session_id);
165 /* calculate a hash key */
167 tcaphash_context_calchash(gconstpointer k)
169 const struct tcaphash_context_key_t *key = (const struct tcaphash_context_key_t *) k;
170 return key->session_id;
175 tcaphash_begin_equal(gconstpointer k1, gconstpointer k2)
177 const struct tcaphash_begin_info_key_t *key1 = (const struct tcaphash_begin_info_key_t *) k1;
178 const struct tcaphash_begin_info_key_t *key2 = (const struct tcaphash_begin_info_key_t *) k2;
180 if (key1->hashKey == key2->hashKey) {
182 if ( ( (key1->opc_hash == key2->opc_hash) &&
183 (key1->dpc_hash == key2->dpc_hash) &&
184 (key1->tid == key2->tid) )
186 ( (key1->opc_hash == key2->dpc_hash) &&
187 (key1->dpc_hash == key2->opc_hash) &&
188 (key1->tid == key2->tid) )
195 /* calculate a hash key */
197 tcaphash_begin_calchash(gconstpointer k)
199 const struct tcaphash_begin_info_key_t *key = (const struct tcaphash_begin_info_key_t *) k;
201 /* hashkey = key->opc_hash<<16 + key->dpc_hash<<8 + key->src_tid; */
207 tcaphash_cont_equal(gconstpointer k1, gconstpointer k2)
209 const struct tcaphash_cont_info_key_t *key1 = (const struct tcaphash_cont_info_key_t *) k1;
210 const struct tcaphash_cont_info_key_t *key2 = (const struct tcaphash_cont_info_key_t *) k2;
212 if (key1->hashKey == key2->hashKey) {
214 if ( (key1->opc_hash == key2->opc_hash) &&
215 (key1->dpc_hash == key2->dpc_hash) &&
216 (key1->src_tid == key2->src_tid) &&
217 (key1->dst_tid == key2->dst_tid) ) {
220 else if ( (key1->opc_hash == key2->dpc_hash) &&
221 (key1->dpc_hash == key2->opc_hash) &&
222 (key1->src_tid == key2->dst_tid) &&
223 (key1->dst_tid == key2->src_tid) ) {
230 /* calculate a hash key */
232 tcaphash_cont_calchash(gconstpointer k)
234 const struct tcaphash_cont_info_key_t *key = (const struct tcaphash_cont_info_key_t *) k;
236 hashkey = key->src_tid + key->dst_tid;
242 tcaphash_end_equal(gconstpointer k1, gconstpointer k2)
244 const struct tcaphash_end_info_key_t *key1 = (const struct tcaphash_end_info_key_t *) k1;
245 const struct tcaphash_end_info_key_t *key2 = (const struct tcaphash_end_info_key_t *) k2;
247 if (key1->hashKey == key2->hashKey) {
248 if ( ( (key1->opc_hash == key2->opc_hash) &&
249 (key1->dpc_hash == key2->dpc_hash) &&
250 (key1->tid == key2->tid) )
252 ( (key1->opc_hash == key2->dpc_hash) &&
253 (key1->dpc_hash == key2->opc_hash) &&
254 (key1->tid == key2->tid) ) )
260 /* calculate a hash key */
262 tcaphash_end_calchash(gconstpointer k)
264 const struct tcaphash_end_info_key_t *key = (const struct tcaphash_end_info_key_t *) k;
271 tcaphash_ansi_equal(gconstpointer k1, gconstpointer k2)
273 const struct tcaphash_ansi_info_key_t *key1 = (const struct tcaphash_ansi_info_key_t *) k1;
274 const struct tcaphash_ansi_info_key_t *key2 = (const struct tcaphash_ansi_info_key_t *) k2;
276 if (key1->hashKey == key2->hashKey) {
278 if ( ( (key1->opc_hash == key2->opc_hash) &&
279 (key1->dpc_hash == key2->dpc_hash) &&
280 (key1->tid == key2->tid) )
282 ( (key1->opc_hash == key2->dpc_hash) &&
283 (key1->dpc_hash == key2->opc_hash) &&
284 (key1->tid == key2->tid) )
291 /* calculate a hash key */
293 tcaphash_ansi_calchash(gconstpointer k)
295 const struct tcaphash_ansi_info_key_t *key = (const struct tcaphash_ansi_info_key_t *) k;
297 /* hashkey = key->opc_hash<<16 + key->dpc_hash<<8 + key->src_tid; */
303 * Update a record with the data of the Request
306 update_tcaphash_begincall(struct tcaphash_begincall_t *p_tcaphash_begincall,
309 p_tcaphash_begincall->context->first_frame = pinfo->fd->num;
310 p_tcaphash_begincall->context->last_frame = 0;
311 p_tcaphash_begincall->context->responded = FALSE;
312 p_tcaphash_begincall->context->begin_time = pinfo->fd->abs_ts;
316 * Append a new dialogue, using the same Key, to the chained list
317 * The time is stored too
319 static struct tcaphash_begincall_t *
320 append_tcaphash_begincall(struct tcaphash_begincall_t *prev_begincall,
321 struct tcaphash_context_t *p_tcaphash_context,
324 struct tcaphash_begincall_t *p_new_tcaphash_begincall = NULL;
326 /* Append the transaction to the list, when the same key is found
327 This should append when the tcap-transaction Id is reused */
330 p_new_tcaphash_begincall = (struct tcaphash_begincall_t *)g_malloc0(sizeof(struct tcaphash_begincall_t));
332 p_new_tcaphash_begincall = se_new0(struct tcaphash_begincall_t);
334 p_new_tcaphash_begincall->context=p_tcaphash_context;
335 p_tcaphash_context->begincall=p_new_tcaphash_begincall;
336 p_new_tcaphash_begincall->beginkey=prev_begincall->beginkey;
337 p_new_tcaphash_begincall->context->first_frame = pinfo->fd->num;
338 p_new_tcaphash_begincall->next_begincall=NULL;
339 p_new_tcaphash_begincall->previous_begincall=prev_begincall;
340 p_new_tcaphash_begincall->father=FALSE;
343 dbg(10,"+B%d ", p_new_tcaphash_begincall->context->session_id);
345 /* Insert in the chained list */
346 prev_begincall->next_begincall = p_new_tcaphash_begincall;
347 if (prev_begincall->context->last_frame == 0) {
351 prev_begincall->context->last_frame = pinfo->fd->num-1;
353 return p_new_tcaphash_begincall;
357 * Update a record with the data of the Request
360 update_tcaphash_ansicall(struct tcaphash_ansicall_t *p_tcaphash_ansicall,
363 p_tcaphash_ansicall->context->first_frame = pinfo->fd->num;
364 p_tcaphash_ansicall->context->last_frame = 0;
365 p_tcaphash_ansicall->context->responded = FALSE;
366 p_tcaphash_ansicall->context->begin_time = pinfo->fd->abs_ts;
370 * Append a new dialogue, using the same Key, to the chained list
371 * The time is stored too
373 static struct tcaphash_ansicall_t *
374 append_tcaphash_ansicall(struct tcaphash_ansicall_t *prev_ansicall,
375 struct tcaphash_context_t *p_tcaphash_context,
378 struct tcaphash_ansicall_t *p_new_tcaphash_ansicall = NULL;
380 /* Append the transaction to the list, when the same key is found
381 This should append when the tcap-transaction Id is reused */
384 p_new_tcaphash_ansicall = (struct tcaphash_ansicall_t *)g_malloc0(sizeof(struct tcaphash_ansicall_t));
386 p_new_tcaphash_ansicall = se_new0(struct tcaphash_ansicall_t);
388 p_new_tcaphash_ansicall->context=p_tcaphash_context;
389 p_tcaphash_context->ansicall=p_new_tcaphash_ansicall;
390 p_new_tcaphash_ansicall->ansikey=prev_ansicall->ansikey;
391 p_new_tcaphash_ansicall->context->first_frame = pinfo->fd->num;
392 p_new_tcaphash_ansicall->next_ansicall=NULL;
393 p_new_tcaphash_ansicall->previous_ansicall=prev_ansicall;
394 p_new_tcaphash_ansicall->father=FALSE;
397 dbg(10,"+A%d ", p_new_tcaphash_ansicall->context->session_id);
399 /* Insert in the chained list */
400 prev_ansicall->next_ansicall = p_new_tcaphash_ansicall;
401 if (prev_ansicall->context->last_frame == 0) {
405 prev_ansicall->context->last_frame = pinfo->fd->num-1;
407 return p_new_tcaphash_ansicall;
411 static struct tcaphash_contcall_t *
412 append_tcaphash_contcall(struct tcaphash_contcall_t *prev_contcall,
413 struct tcaphash_context_t *p_tcaphash_context)
415 struct tcaphash_contcall_t *p_new_tcaphash_contcall = NULL;
417 /* Append the transaction to the list, when the same key is found
418 This should append when the tcap-transaction Id is reused */
421 p_new_tcaphash_contcall = (struct tcaphash_contcall_t *)g_malloc0(sizeof(struct tcaphash_contcall_t));
423 p_new_tcaphash_contcall = se_new0(struct tcaphash_contcall_t);
425 p_new_tcaphash_contcall->context=p_tcaphash_context;
426 p_tcaphash_context->contcall=p_new_tcaphash_contcall;
427 p_new_tcaphash_contcall->contkey=prev_contcall->contkey;
428 p_new_tcaphash_contcall->next_contcall=NULL;
429 p_new_tcaphash_contcall->previous_contcall=prev_contcall;
430 p_new_tcaphash_contcall->father=FALSE;
433 dbg(10,"+C%d ", p_new_tcaphash_contcall->context->session_id);
435 /* Insert in the chained list */
436 prev_contcall->next_contcall = p_new_tcaphash_contcall;
437 return p_new_tcaphash_contcall;
441 static struct tcaphash_endcall_t *
442 append_tcaphash_endcall(struct tcaphash_endcall_t *prev_endcall,
443 struct tcaphash_context_t *p_tcaphash_context)
445 struct tcaphash_endcall_t *p_new_tcaphash_endcall = NULL;
447 /* Append the transaction to the list, when the same key is found
448 This should append when the tcap-transaction Id is reused */
451 p_new_tcaphash_endcall = (struct tcaphas_endcall_t *)g_malloc0(sizeof(struct tcaphash_endcall_t));
453 p_new_tcaphash_endcall = se_new0(struct tcaphash_endcall_t);
455 p_new_tcaphash_endcall->context=p_tcaphash_context;
456 p_tcaphash_context->endcall=p_new_tcaphash_endcall;
457 p_new_tcaphash_endcall->endkey=prev_endcall->endkey;
458 p_new_tcaphash_endcall->next_endcall=NULL;
459 p_new_tcaphash_endcall->previous_endcall=prev_endcall;
460 p_new_tcaphash_endcall->father=FALSE;
463 dbg(10,"+E%d ", p_new_tcaphash_endcall->context->session_id);
465 /* Insert in the chained list */
466 prev_endcall->next_endcall = p_new_tcaphash_endcall;
467 return p_new_tcaphash_endcall;
472 * Find the dialog by Key and Time
474 static struct tcaphash_begincall_t *
475 find_tcaphash_begin(struct tcaphash_begin_info_key_t *p_tcaphash_begin_key,
476 packet_info *pinfo, gboolean isBegin)
478 struct tcaphash_begincall_t *p_tcaphash_begincall = NULL;
479 p_tcaphash_begincall = (struct tcaphash_begincall_t *)g_hash_table_lookup(tcaphash_begin, p_tcaphash_begin_key);
481 if(p_tcaphash_begincall) {
483 if ( p_tcaphash_begincall->context ) {
485 pinfo->fd->num == p_tcaphash_begincall->context->first_frame )
488 pinfo->fd->num >= p_tcaphash_begincall->context->first_frame &&
489 ( p_tcaphash_begincall->context->last_frame?pinfo->fd->num <= p_tcaphash_begincall->context->last_frame:1 )
492 /* We have a dialogue, with this key, opened before this request */
494 dbg(10,"B%d ", p_tcaphash_begincall->context->session_id);
496 return p_tcaphash_begincall;
499 dbg(60,"[B%d] ", p_tcaphash_begincall->context->session_id);
502 /* Break when list end is reached */
503 if(p_tcaphash_begincall->next_begincall == NULL) {
505 dbg(23,"End of Blist ");
509 p_tcaphash_begincall = p_tcaphash_begincall->next_begincall;
510 } while (p_tcaphash_begincall != NULL) ;
513 dbg(23,"Not in Bhash ");
521 static struct tcaphash_contcall_t *
522 find_tcaphash_cont(struct tcaphash_cont_info_key_t *p_tcaphash_cont_key,
525 struct tcaphash_contcall_t *p_tcaphash_contcall = NULL;
526 p_tcaphash_contcall = (struct tcaphash_contcall_t *)g_hash_table_lookup(tcaphash_cont, p_tcaphash_cont_key);
528 if(p_tcaphash_contcall) {
530 if ( p_tcaphash_contcall->context ) {
531 if (pinfo->fd->num >= p_tcaphash_contcall->context->first_frame &&
532 (p_tcaphash_contcall->context->last_frame?pinfo->fd->num <= p_tcaphash_contcall->context->last_frame:1) ) {
533 /* We have a dialogue, with this key, opened before this request */
535 dbg(10,"C%d ", p_tcaphash_contcall->context->session_id);
537 return p_tcaphash_contcall;
540 dbg(60,"[C%d] ", p_tcaphash_contcall->context->session_id);
543 /* Break when list end is reached */
544 if(p_tcaphash_contcall->next_contcall == NULL) {
546 dbg(23,"End of Clist ");
550 p_tcaphash_contcall = p_tcaphash_contcall->next_contcall;
551 } while (p_tcaphash_contcall != NULL) ;
554 dbg(23,"Not in Chash ");
560 static struct tcaphash_endcall_t *
561 find_tcaphash_end(struct tcaphash_end_info_key_t *p_tcaphash_end_key,
562 packet_info *pinfo, gboolean isEnd)
564 struct tcaphash_endcall_t *p_tcaphash_endcall = NULL;
565 p_tcaphash_endcall = (struct tcaphash_endcall_t *)g_hash_table_lookup(tcaphash_end, p_tcaphash_end_key);
567 if(p_tcaphash_endcall) {
569 if ( p_tcaphash_endcall->context ) {
571 (p_tcaphash_endcall->context->last_frame?pinfo->fd->num == p_tcaphash_endcall->context->last_frame:1)
575 pinfo->fd->num >= p_tcaphash_endcall->context->first_frame &&
576 (p_tcaphash_endcall->context->last_frame?pinfo->fd->num <= p_tcaphash_endcall->context->last_frame:1)
579 /* We have a dialogue, with this key, opened before this request */
581 dbg(10,"E%d ", p_tcaphash_endcall->context->session_id);
583 return p_tcaphash_endcall;
586 dbg(60,"[E%d] ", p_tcaphash_endcall->context->session_id);
589 /* Break when list end is reached */
590 if(p_tcaphash_endcall->next_endcall == NULL) {
592 dbg(23,"End of Elist ");
596 p_tcaphash_endcall = p_tcaphash_endcall->next_endcall;
597 } while (p_tcaphash_endcall != NULL) ;
600 dbg(23,"Not in Ehash ");
607 * New record to create, to identify a new transaction
609 static struct tcaphash_context_t *
610 new_tcaphash_context(struct tcaphash_context_key_t *p_tcaphash_context_key,
613 struct tcaphash_context_key_t *p_new_tcaphash_context_key;
614 struct tcaphash_context_t *p_new_tcaphash_context = NULL;
616 /* Register the transaction in the hash table
617 with the tcap transaction Id as Main Key
618 Once created, this entry will be updated later */
621 p_new_tcaphash_context_key = (struct tcaphash_context_key_t *)g_malloc(sizeof(struct tcaphash_context_key_t));
623 p_new_tcaphash_context_key = se_new(struct tcaphash_context_key_t);
625 p_new_tcaphash_context_key->session_id = p_tcaphash_context_key->session_id;
628 p_new_tcaphash_context = (struct tcaphash_context_t *)g_malloc0(sizeof(struct tcaphash_context_t));
630 p_new_tcaphash_context = se_new0(struct tcaphash_context_t);
632 p_new_tcaphash_context->key = p_new_tcaphash_context_key;
633 p_new_tcaphash_context->session_id = p_tcaphash_context_key->session_id;
634 p_new_tcaphash_context->first_frame = pinfo->fd->num;
636 dbg(10,"S%d ", p_new_tcaphash_context->session_id);
639 g_hash_table_insert(tcaphash_context, p_new_tcaphash_context_key, p_new_tcaphash_context);
640 return p_new_tcaphash_context;
644 * New record to create, to identify a new transaction
646 static struct tcaphash_begincall_t *
647 new_tcaphash_begin(struct tcaphash_begin_info_key_t *p_tcaphash_begin_key,
648 struct tcaphash_context_t *p_tcaphash_context)
650 struct tcaphash_begin_info_key_t *p_new_tcaphash_begin_key;
651 struct tcaphash_begincall_t *p_new_tcaphash_begincall = NULL;
653 /* Register the transaction in the hash table
654 with the tcap transaction Id as Main Key
655 Once created, this entry will be updated later */
658 p_new_tcaphash_begin_key = (struct tcaphash_begin_info_key_t *)g_malloc(sizeof(struct tcaphash_begin_info_key_t));
660 p_new_tcaphash_begin_key = se_new(struct tcaphash_begin_info_key_t);
662 p_new_tcaphash_begin_key->hashKey = p_tcaphash_begin_key->hashKey;
663 p_new_tcaphash_begin_key->tid = p_tcaphash_begin_key->tid;
664 p_new_tcaphash_begin_key->opc_hash = p_tcaphash_begin_key->opc_hash;
665 p_new_tcaphash_begin_key->dpc_hash = p_tcaphash_begin_key->dpc_hash;
668 p_new_tcaphash_begincall = (struct tcaphash_begincall_t *)g_malloc0(sizeof(struct tcaphash_begincall_t));
670 p_new_tcaphash_begincall = se_new0(struct tcaphash_begincall_t);
672 p_new_tcaphash_begincall->beginkey=p_new_tcaphash_begin_key;
673 p_new_tcaphash_begincall->context=p_tcaphash_context;
674 p_tcaphash_context->begincall=p_new_tcaphash_begincall;
675 p_new_tcaphash_begincall->father=TRUE;
676 p_new_tcaphash_begincall->next_begincall=NULL;
677 p_new_tcaphash_begincall->previous_begincall=NULL;
680 dbg(10,"B%d ", p_new_tcaphash_begincall->context->session_id);
683 g_hash_table_insert(tcaphash_begin, p_new_tcaphash_begin_key, p_new_tcaphash_begincall);
684 return p_new_tcaphash_begincall;
690 * New record to create, to identify a new transaction
692 static struct tcaphash_contcall_t *
693 new_tcaphash_cont(struct tcaphash_cont_info_key_t *p_tcaphash_cont_key,
694 struct tcaphash_context_t *p_tcaphash_context)
696 struct tcaphash_cont_info_key_t *p_new_tcaphash_cont_key;
697 struct tcaphash_contcall_t *p_new_tcaphash_contcall = NULL;
699 /* Register the transaction in the hash table
700 with the tcap transaction Id as Main Key
701 Once created, this entry will be updated later */
704 p_new_tcaphash_cont_key = (struct tcaphash_cont_info_key_t *)g_malloc(sizeof(struct tcaphash_cont_info_key_t));
706 p_new_tcaphash_cont_key = se_new(struct tcaphash_cont_info_key_t);
708 p_new_tcaphash_cont_key->hashKey = p_tcaphash_cont_key->hashKey;
709 p_new_tcaphash_cont_key->src_tid = p_tcaphash_cont_key->src_tid;
710 p_new_tcaphash_cont_key->dst_tid = p_tcaphash_cont_key->dst_tid;
711 p_new_tcaphash_cont_key->opc_hash = p_tcaphash_cont_key->opc_hash;
712 p_new_tcaphash_cont_key->dpc_hash = p_tcaphash_cont_key->dpc_hash;
715 p_new_tcaphash_contcall = (struct tcaphash_contcall_t *)g_malloc0(sizeof(struct tcaphash_contcall_t));
717 p_new_tcaphash_contcall = se_new0(struct tcaphash_contcall_t);
719 p_new_tcaphash_contcall->contkey=p_new_tcaphash_cont_key;
720 p_new_tcaphash_contcall->context=p_tcaphash_context;
721 p_tcaphash_context->contcall=p_new_tcaphash_contcall;
722 p_new_tcaphash_contcall->father=TRUE;
723 p_new_tcaphash_contcall->next_contcall=NULL;
724 p_new_tcaphash_contcall->previous_contcall=NULL;
727 dbg(10,"C%d ", p_new_tcaphash_contcall->context->session_id);
730 g_hash_table_insert(tcaphash_cont, p_new_tcaphash_cont_key, p_new_tcaphash_contcall);
731 return p_new_tcaphash_contcall;
736 * New record to create, to identify a new transaction
738 static struct tcaphash_endcall_t *
739 new_tcaphash_end(struct tcaphash_end_info_key_t *p_tcaphash_end_key,
740 struct tcaphash_context_t *p_tcaphash_context)
742 struct tcaphash_end_info_key_t *p_new_tcaphash_end_key;
743 struct tcaphash_endcall_t *p_new_tcaphash_endcall = NULL;
745 /* Register the transaction in the hash table
746 with the tcap transaction Id as Main Key
747 Once created, this entry will be updated later */
750 p_new_tcaphash_end_key = (struct tcaphash_end_info_key_t *)g_malloc(sizeof(struct tcaphash_end_info_key_t));
752 p_new_tcaphash_end_key = se_new(struct tcaphash_end_info_key_t);
754 p_new_tcaphash_end_key->hashKey = p_tcaphash_end_key->hashKey;
755 p_new_tcaphash_end_key->tid = p_tcaphash_end_key->tid;
756 p_new_tcaphash_end_key->opc_hash = p_tcaphash_end_key->opc_hash;
757 p_new_tcaphash_end_key->dpc_hash = p_tcaphash_end_key->dpc_hash;
760 p_new_tcaphash_endcall = (struct tcaphash_endcall_t *)g_malloc0(sizeof(struct tcaphash_endcall_t));
762 p_new_tcaphash_endcall = se_new0(struct tcaphash_endcall_t);
764 p_new_tcaphash_endcall->endkey=p_new_tcaphash_end_key;
765 p_new_tcaphash_endcall->context=p_tcaphash_context;
766 p_tcaphash_context->endcall=p_new_tcaphash_endcall;
767 p_new_tcaphash_endcall->father=TRUE;
768 p_new_tcaphash_endcall->next_endcall=NULL;
769 p_new_tcaphash_endcall->previous_endcall=NULL;
772 dbg(10,"E%d ", p_new_tcaphash_endcall->context->session_id);
775 g_hash_table_insert(tcaphash_end, p_new_tcaphash_end_key, p_new_tcaphash_endcall);
776 return p_new_tcaphash_endcall;
779 * New record to create, to identify a new transaction
781 static struct tcaphash_ansicall_t *
782 new_tcaphash_ansi(struct tcaphash_ansi_info_key_t *p_tcaphash_ansi_key,
783 struct tcaphash_context_t *p_tcaphash_context)
785 struct tcaphash_ansi_info_key_t *p_new_tcaphash_ansi_key;
786 struct tcaphash_ansicall_t *p_new_tcaphash_ansicall = NULL;
788 /* Register the transaction in the hash table
789 with the tcap transaction Id as Main Key
790 Once created, this entry will be updated later */
793 p_new_tcaphash_ansi_key = (struct tcaphash_ansi_info_key_t *)g_malloc(sizeof(struct tcaphash_ansi_info_key_t));
795 p_new_tcaphash_ansi_key = se_new(struct tcaphash_ansi_info_key_t);
797 p_new_tcaphash_ansi_key->hashKey = p_tcaphash_ansi_key->hashKey;
798 p_new_tcaphash_ansi_key->tid = p_tcaphash_ansi_key->tid;
799 p_new_tcaphash_ansi_key->opc_hash = p_tcaphash_ansi_key->opc_hash;
800 p_new_tcaphash_ansi_key->dpc_hash = p_tcaphash_ansi_key->dpc_hash;
803 p_new_tcaphash_ansicall = (struct tcaphash_ansicall_t *)g_malloc0(sizeof(struct tcaphash_ansicall_t));
805 p_new_tcaphash_ansicall = se_new0(struct tcaphash_ansicall_t);
807 p_new_tcaphash_ansicall->ansikey=p_new_tcaphash_ansi_key;
808 p_new_tcaphash_ansicall->context=p_tcaphash_context;
809 p_tcaphash_context->ansicall=p_new_tcaphash_ansicall;
810 p_new_tcaphash_ansicall->father=TRUE;
811 p_new_tcaphash_ansicall->next_ansicall=NULL;
812 p_new_tcaphash_ansicall->previous_ansicall=NULL;
815 dbg(10,"A%d ", p_new_tcaphash_ansicall->context->session_id);
818 g_hash_table_insert(tcaphash_ansi, p_new_tcaphash_ansi_key, p_new_tcaphash_ansicall);
819 return p_new_tcaphash_ansicall;
822 static struct tcaphash_contcall_t *
823 create_tcaphash_cont(struct tcaphash_cont_info_key_t *p_tcaphash_cont_key,
824 struct tcaphash_context_t *p_tcaphash_context)
826 struct tcaphash_contcall_t *p_tcaphash_contcall1 = NULL;
827 struct tcaphash_contcall_t *p_tcaphash_contcall = NULL;
829 p_tcaphash_contcall1 = (struct tcaphash_contcall_t *)
830 g_hash_table_lookup(tcaphash_cont, p_tcaphash_cont_key);
832 if (p_tcaphash_contcall1) {
833 /* Walk through list of transaction with identical keys */
834 /* go the the end to insert new record */
836 if (!p_tcaphash_contcall1->next_contcall) {
837 p_tcaphash_contcall=append_tcaphash_contcall(p_tcaphash_contcall1,
841 p_tcaphash_contcall1 = p_tcaphash_contcall1->next_contcall;
842 } while (p_tcaphash_contcall1 != NULL );
844 p_tcaphash_contcall = new_tcaphash_cont(p_tcaphash_cont_key,
847 return p_tcaphash_contcall;
851 static struct tcaphash_endcall_t *
852 create_tcaphash_end(struct tcaphash_end_info_key_t *p_tcaphash_end_key,
853 struct tcaphash_context_t *p_tcaphash_context)
855 struct tcaphash_endcall_t *p_tcaphash_endcall1 = NULL;
856 struct tcaphash_endcall_t *p_tcaphash_endcall = NULL;
858 p_tcaphash_endcall1 = (struct tcaphash_endcall_t *)
859 g_hash_table_lookup(tcaphash_end, p_tcaphash_end_key);
861 if (p_tcaphash_endcall1) {
862 /* Walk through list of transaction with identical keys */
863 /* go the the end to insert new record */
865 if (!p_tcaphash_endcall1->next_endcall) {
866 p_tcaphash_endcall=append_tcaphash_endcall(p_tcaphash_endcall1,
870 p_tcaphash_endcall1 = p_tcaphash_endcall1->next_endcall;
871 } while (p_tcaphash_endcall1 != NULL );
873 p_tcaphash_endcall = new_tcaphash_end(p_tcaphash_end_key,
876 return p_tcaphash_endcall;
881 * Routine called when the TAP is initialized.
882 * so hash table are (re)created
885 tcapsrt_init_routine(void)
888 /* free hash-table for SRT */
889 if (tcaphash_context != NULL) {
891 dbg(16,"Destroy hash_context \n");
893 g_hash_table_destroy(tcaphash_context);
896 if (tcaphash_begin != NULL) {
898 dbg(16,"Destroy hash_begin \n");
900 g_hash_table_destroy(tcaphash_begin);
903 if (tcaphash_cont != NULL) {
905 dbg(16,"Destroy hash_cont \n");
907 g_hash_table_destroy(tcaphash_cont);
910 if (tcaphash_end != NULL) {
912 dbg(16,"Destroy hash_end \n");
914 g_hash_table_destroy(tcaphash_end);
917 if (tcaphash_ansi != NULL) {
919 dbg(16,"Destroy hash_ansi \n");
921 g_hash_table_destroy(tcaphash_ansi);
925 dbg(16,"Create hash \n");
927 /* create new hash-tables for SRT */
928 tcaphash_context = g_hash_table_new(tcaphash_context_calchash, tcaphash_context_equal);
929 tcaphash_begin = g_hash_table_new(tcaphash_begin_calchash, tcaphash_begin_equal);
930 tcaphash_cont = g_hash_table_new(tcaphash_cont_calchash, tcaphash_cont_equal);
931 tcaphash_end = g_hash_table_new(tcaphash_end_calchash, tcaphash_end_equal);
932 tcaphash_ansi = g_hash_table_new(tcaphash_ansi_calchash, tcaphash_ansi_equal);
934 /* Reset the session counter */
935 tcapsrt_global_SessionId=1;
937 /* Display of SRT only if Persistent Stat */
938 gtcap_DisplaySRT=gtcap_PersistentSRT || gtcap_HandleSRT>cap_StatSRT;
942 * Service Response Time analyze
943 * Called just after dissector call
944 * Associate a TCAP context to a tcap session and display session related infomations
945 * like the first frame, the last, the session duration,
946 * and a uniq session identifier for the filtering
948 * For ETSI tcap, the TCAP context can be reached through three keys
949 * - a key (BEGIN) identifying the session according to the tcap source identifier
950 * - a key (CONT) identifying the established session (src_id and dst_id)
951 * - a key (END) identifying the session according to the tcap destination identifier
953 * For ANSI tcap, the TCAP context is reached through a uniq key
954 * - a key (ANSI) identifying the session according to the tcap identifier
956 struct tcaphash_context_t *
957 tcapsrt_call_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
958 struct tcapsrt_info_t *p_tcapsrt_info)
960 struct tcaphash_context_t *tcap_context=NULL;
962 /* if this packet isn't loaded because of a read filter, don't output anything */
963 if(pinfo == NULL || pinfo->fd->num == 0) {
967 switch (p_tcapsrt_info->ope) {
971 dbg(1,"\nTC_BEGIN ");
973 tcap_context=tcaphash_begin_matching(tvb, pinfo, tree, p_tcapsrt_info);
980 tcap_context=tcaphash_cont_matching(tvb, pinfo, tree, p_tcapsrt_info);
985 dbg(1,"\nTC_ABORT ");
987 tcap_context=tcaphash_end_matching(tvb, pinfo, tree, p_tcapsrt_info);
994 tcap_context=tcaphash_end_matching(tvb, pinfo, tree, p_tcapsrt_info);
1000 dbg(1,"\nTC_ANSI ");
1002 tcap_context=tcaphash_ansi_matching(tvb, pinfo, tree, p_tcapsrt_info);
1006 #ifdef DEBUG_TCAPSRT
1007 dbg(1,"\nUnknown %d ", p_tcapsrt_info->ope);
1010 } /* switch tcapop */
1011 #ifdef DEBUG_TCAPSRT
1013 dbg(1,"session %d ", tcap_context->session_id);
1015 return tcap_context;
1020 * Create the record identifiying the TCAP transaction
1021 * When the identifier for the transaction is reused, check
1022 * the following criteria before to append a new record:
1023 * - a timeout corresponding to a message retransmission is detected,
1024 * - a message hast been lost
1025 * - or the previous transaction has been be closed
1027 static struct tcaphash_context_t *
1028 tcaphash_begin_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1029 struct tcapsrt_info_t *p_tcapsrt_info)
1031 struct tcaphash_context_t *p_tcaphash_context=NULL;
1032 struct tcaphash_context_key_t tcaphash_context_key;
1033 struct tcaphash_begincall_t *p_tcaphash_begincall, *p_new_tcaphash_begincall=NULL;
1034 struct tcaphash_begin_info_key_t tcaphash_begin_key;
1036 proto_item *stat_item=NULL;
1037 proto_tree *stat_tree=NULL;
1039 /* prepare the key data */
1040 tcaphash_begin_key.tid = p_tcapsrt_info->src_tid;
1041 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1043 /* We have MTP3 PCs (so we can safely do this cast) */
1044 tcaphash_begin_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1045 tcaphash_begin_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1047 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1048 tcaphash_begin_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1049 tcaphash_begin_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1051 tcaphash_begin_key.hashKey=tcaphash_begin_calchash(&tcaphash_begin_key);
1053 /* look up the request */
1054 #ifdef DEBUG_TCAPSRT
1055 dbg(10,"\n Hbegin #%u ", pinfo->fd->num);
1056 dbg(11,"key %lx ",tcaphash_begin_key.hashKey);
1057 dbg(51,"PC %s %s ",ep_address_to_str(&pinfo->src), ep_address_to_str(&pinfo->dst));
1058 dbg(51,"Tid %lx \n",tcaphash_begin_key.tid);
1061 p_tcaphash_begincall = (struct tcaphash_begincall_t *)
1062 g_hash_table_lookup(tcaphash_begin, &tcaphash_begin_key);
1064 if (p_tcaphash_begincall) {
1065 /* Walk through list of transaction with identical keys */
1067 /* Check if the request with this reqSeqNum has been seen, with the same Message Type */
1068 if (pinfo->fd->num == p_tcaphash_begincall->context->first_frame) {
1069 /* We have seen this request before -> do nothing */
1070 #ifdef DEBUG_TCAPSRT
1071 dbg(22,"Already seen ");
1073 p_tcaphash_context=p_tcaphash_begincall->context;
1076 /* If the last record for Tcap transaction with identifier has not been reached */
1077 if (!p_tcaphash_begincall->next_begincall) {
1078 /* check if we have to create a new record or not */
1079 /* if last request has been responded (response number is known)
1080 and this request appears after last response (has bigger frame number)
1081 and last request occurred after the timeout for repetition,
1083 if last request hasn't been responded (so number unknown)
1084 and this request appears after last request (has bigger frame number)
1085 and this request occurred after the timeout for message lost */
1086 if ( ( p_tcaphash_begincall->context->last_frame != 0
1087 && pinfo->fd->num > p_tcaphash_begincall->context->first_frame
1088 && (guint) pinfo->fd->abs_ts.secs > (guint)(p_tcaphash_begincall->context->begin_time.secs + gtcap_RepetitionTimeout)
1090 ( p_tcaphash_begincall->context->last_frame == 0
1091 && pinfo->fd->num > p_tcaphash_begincall->context->first_frame
1092 && (guint)pinfo->fd->abs_ts.secs > (guint)(p_tcaphash_begincall->context->begin_time.secs + gtcap_LostTimeout)
1096 /* we decide that we have a new request */
1097 /* Append new record to the list */
1098 #ifdef DEBUG_TCAPSRT
1099 dbg(12,"(timeout) Append key %lx ",tcaphash_begin_key.hashKey);
1100 dbg(12,"Frame %u rsp %u ",pinfo->fd->num,p_tcaphash_begincall->context->last_frame );
1102 tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
1103 p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
1105 p_new_tcaphash_begincall = append_tcaphash_begincall(p_tcaphash_begincall,
1108 #ifdef DEBUG_TCAPSRT
1109 dbg(12,"Update key %lx ",tcaphash_begin_key.hashKey);
1111 update_tcaphash_begincall(p_new_tcaphash_begincall, pinfo);
1112 } else { /* timeout or message lost */
1114 /* If the Tid is reused for a closed Transaction */
1115 /* Or if we received an TC_BEGIN for a Transaction marked as "closed" */
1116 /* (this is the case, for pre-arranged END, the transaction is marked as closed */
1117 /* by the upper layer, thank to a callback method close) */
1118 if ( p_tcaphash_begincall->context->closed) {
1119 #ifdef DEBUG_TCAPSRT
1120 dbg(12,"(closed) Append key %lu ",tcaphash_begin_key.hashKey);
1121 dbg(12,"Frame %u rsp %u ",pinfo->fd->num,p_tcaphash_begincall->context->last_frame );
1123 tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
1124 p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
1125 p_new_tcaphash_begincall = append_tcaphash_begincall(p_tcaphash_begincall,
1129 #ifdef DEBUG_TCAPSRT
1130 dbg(12,"Update key %lu ",tcaphash_begin_key.hashKey);
1132 update_tcaphash_begincall(p_new_tcaphash_begincall, pinfo);
1135 /* the TCAP session is not closed, so, either messages have been lost */
1136 /* or it's a duplicate request. Mark it as such. */
1137 #ifdef DEBUG_TCAPSRT
1138 dbg(21,"Display_duplicate %d ",p_tcaphash_begincall->context->first_frame);
1140 p_tcaphash_context=p_tcaphash_begincall->context;
1141 if (gtcap_DisplaySRT && tree) {
1142 stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
1143 PROTO_ITEM_SET_GENERATED(stat_item);
1144 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1145 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_Duplicate, tvb, 0, 0,
1146 p_tcaphash_context->first_frame,
1147 "Duplicate with session %u in frame %u",
1148 p_tcaphash_context->session_id,p_tcaphash_context->first_frame);
1149 PROTO_ITEM_SET_GENERATED(pi);
1151 return p_tcaphash_context;
1152 } /* Previous session closed */
1153 } /* test with Timeout or message Lost */
1155 } /* Next call is NULL */
1156 /* Repeat the tests for the next record with the same transaction identifier */
1157 p_tcaphash_begincall = p_tcaphash_begincall->next_begincall;
1158 } while (p_tcaphash_begincall != NULL );
1160 * End of analyze for the list be TC_BEGIN with same transaction ID
1162 } else { /* p_tcaphash_begincall has not been found */
1164 * Create a new TCAP context
1166 #ifdef DEBUG_TCAPSRT
1167 dbg(10,"New key %lx ",tcaphash_begin_key.hashKey);
1170 tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
1171 p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
1172 p_tcaphash_begincall = new_tcaphash_begin(&tcaphash_begin_key, p_tcaphash_context);
1174 #ifdef DEBUG_TCAPSRT
1175 dbg(11,"Update key %lx ",tcaphash_begin_key.hashKey);
1176 dbg(11,"Frame reqlink #%u ", pinfo->fd->num);
1178 update_tcaphash_begincall(p_tcaphash_begincall, pinfo);
1181 /* display tcap session, if available */
1182 if ( gtcap_DisplaySRT && tree &&
1183 p_tcaphash_context &&
1184 p_tcaphash_context->session_id) {
1185 stat_item = proto_tree_add_text(tree, tvb, 0, 0, "Stat");
1186 PROTO_ITEM_SET_GENERATED(stat_item);
1187 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1188 pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
1189 PROTO_ITEM_SET_GENERATED(pi);
1191 /* add link to response frame, if available */
1192 /* p_tcaphash_begincall->context->last_frame) */
1193 if( p_tcaphash_context->last_frame != 0 ){
1194 #ifdef DEBUG_TCAPSRT
1195 dbg(20,"Display_frameRsplink %d ",p_tcaphash_context->last_frame);
1197 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_BeginSession, tvb, 0, 0,
1198 p_tcaphash_context->last_frame,
1199 "End of session in frame %u",
1200 p_tcaphash_context->last_frame);
1201 PROTO_ITEM_SET_GENERATED(pi);
1204 return p_tcaphash_context;
1209 * Try to find a TCAP session according to the source and destination
1210 * Identifier given in the TC_CONT
1211 * If nothing is found, it is probably a session in opening state, so try to find
1212 * a tcap session registered with a TC_BEGIN "key", matching the destination Id of the TC_CONT
1213 * Then associate the TC_CONT "key" to the TCAP context, and create a TC_END "key"
1214 * and display the available info for the TCAP context
1216 static struct tcaphash_context_t *
1217 tcaphash_cont_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1218 struct tcapsrt_info_t *p_tcapsrt_info)
1220 struct tcaphash_context_t *p_tcaphash_context=NULL;
1221 struct tcaphash_contcall_t *p_tcaphash_contcall;
1222 struct tcaphash_cont_info_key_t tcaphash_cont_key;
1223 struct tcaphash_begin_info_key_t tcaphash_begin_key;
1224 struct tcaphash_begincall_t *p_tcaphash_begincall;
1225 struct tcaphash_end_info_key_t tcaphash_end_key;
1227 proto_item *stat_item=NULL;
1228 proto_tree *stat_tree=NULL;
1230 #ifdef DEBUG_TCAPSRT
1231 dbg(10,"\n Hcont #%u ", pinfo->fd->num);
1234 /* look only for matching request, if matching conversation is available. */
1235 tcaphash_cont_key.src_tid = p_tcapsrt_info->src_tid;
1236 tcaphash_cont_key.dst_tid = p_tcapsrt_info->dst_tid;
1237 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1239 /* We have MTP3 PCs (so we can safely do this cast) */
1240 tcaphash_cont_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1241 tcaphash_cont_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1243 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1244 tcaphash_cont_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1245 tcaphash_cont_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1247 tcaphash_cont_key.hashKey=tcaphash_cont_calchash(&tcaphash_cont_key);
1249 #ifdef DEBUG_TCAPSRT
1250 dbg(11,"Ckey %lx ", tcaphash_cont_key.hashKey);
1251 dbg(51,"PC %s %s ",ep_address_to_str(&pinfo->src), ep_address_to_str(&pinfo->dst));
1252 dbg(51,"Tid %lx %lx \n",tcaphash_cont_key.src_tid, tcaphash_cont_key.dst_tid);
1254 p_tcaphash_contcall = find_tcaphash_cont(&tcaphash_cont_key, pinfo);
1255 if(p_tcaphash_contcall) {
1256 #ifdef DEBUG_TCAPSRT
1259 p_tcaphash_context=p_tcaphash_contcall->context;
1260 } else { /* cont not found */
1261 #ifdef DEBUG_TCAPSRT
1262 dbg(12,"CnotFound ");
1264 /* Find the TCAP transaction according to the TC_BEGIN */
1265 tcaphash_begin_key.tid = p_tcapsrt_info->dst_tid;
1266 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1268 /* We have MTP3 PCs (so we can safely do this cast) */
1269 tcaphash_begin_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1270 tcaphash_begin_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1272 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1273 tcaphash_begin_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1274 tcaphash_begin_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1276 tcaphash_begin_key.hashKey=tcaphash_begin_calchash(&tcaphash_begin_key);
1278 #ifdef DEBUG_TCAPSRT
1279 dbg(11,"Bkey %lx ", tcaphash_begin_key.hashKey);
1280 dbg(51,"PC %s %s ",ep_address_to_str(&pinfo->src), ep_address_to_str(&pinfo->dst));
1281 dbg(51,"Tid %lx \n",tcaphash_begin_key.tid);
1283 p_tcaphash_begincall = find_tcaphash_begin(&tcaphash_begin_key, pinfo, FALSE);
1284 if(!p_tcaphash_begincall){
1285 /* Do we have a continue from the same source? */
1286 tcaphash_begin_key.tid = p_tcapsrt_info->src_tid;
1287 tcaphash_begin_key.hashKey=tcaphash_begin_calchash(&tcaphash_begin_key);
1288 p_tcaphash_begincall = find_tcaphash_begin(&tcaphash_begin_key, pinfo,FALSE);
1290 if(p_tcaphash_begincall &&
1291 !p_tcaphash_begincall->context->contcall ) {
1292 #ifdef DEBUG_TCAPSRT
1293 dbg(12,"BFound \n");
1295 p_tcaphash_context=p_tcaphash_begincall->context;
1296 p_tcaphash_context->responded=TRUE;
1298 #ifdef DEBUG_TCAPSRT
1299 dbg(10,"New Ckey %lx ",tcaphash_cont_key.hashKey);
1300 dbg(11,"Frame reqlink #%u \n", pinfo->fd->num);
1302 create_tcaphash_cont(&tcaphash_cont_key,
1303 p_tcaphash_begincall->context);
1305 tcaphash_end_key.tid = p_tcapsrt_info->src_tid;
1306 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1308 /* We have MTP3 PCs (so we can safely do this cast) */
1309 tcaphash_end_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1310 tcaphash_end_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1312 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1313 tcaphash_end_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1314 tcaphash_end_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1316 tcaphash_end_key.hashKey=tcaphash_end_calchash(&tcaphash_end_key);
1318 #ifdef DEBUG_TCAPSRT
1319 dbg(10,"New Ekey %lx ",tcaphash_end_key.hashKey);
1320 dbg(11,"Frame reqlink #%u ", pinfo->fd->num);
1322 create_tcaphash_end(&tcaphash_end_key,
1323 p_tcaphash_begincall->context);
1325 } else { /* Begin not found */
1326 #ifdef DEBUG_TCAPSRT
1327 dbg(12,"BnotFound ");
1331 /* display tcap session, if available */
1332 if (gtcap_DisplaySRT && tree &&
1333 p_tcaphash_context &&
1334 p_tcaphash_context->session_id) {
1335 stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
1336 PROTO_ITEM_SET_GENERATED(stat_item);
1337 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1338 pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
1339 PROTO_ITEM_SET_GENERATED(pi);
1342 return p_tcaphash_context;
1346 * Try to find a TCAP session according to the destination Identifier given in the TC_END/TC_ABORT
1347 * If nothing is found,
1348 * - either it is a session in opening state,
1349 * - or the session is closed/aborted by the remote, ( so we switch the src and dst tid )
1350 * so try to find a tcap session registered with a TC_BEGIN "key",
1351 * matching the destination Id of the TC_END
1352 * Then associate the TC_CONT "key" to the TCAP context
1353 * and display the available info for the TCAP context
1356 static struct tcaphash_context_t *
1357 tcaphash_end_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1358 struct tcapsrt_info_t *p_tcapsrt_info)
1360 struct tcaphash_context_t *p_tcaphash_context=NULL;
1362 struct tcaphash_end_info_key_t tcaphash_end_key;
1363 struct tcaphash_endcall_t *p_tcaphash_endcall=NULL;
1365 struct tcaphash_begin_info_key_t tcaphash_begin_key;
1366 struct tcaphash_begincall_t *p_tcaphash_begincall=NULL;
1369 proto_item *stat_item=NULL;
1370 proto_tree *stat_tree=NULL;
1372 #ifdef DEBUG_TCAPSRT
1373 dbg(10,"\n Hend #%u ", pinfo->fd->num);
1375 /* look only for matching request, if matching conversation is available. */
1376 tcaphash_end_key.tid = p_tcapsrt_info->dst_tid;
1377 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1379 /* We have MTP3 PCs (so we can safely do this cast) */
1380 tcaphash_end_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1381 tcaphash_end_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1383 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1384 tcaphash_end_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1385 tcaphash_end_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1387 tcaphash_end_key.hashKey=tcaphash_end_calchash(&tcaphash_end_key);
1389 #ifdef DEBUG_TCAPSRT
1390 dbg(11,"Ekey %lx ",tcaphash_end_key.hashKey);
1391 dbg(11,"PC %s %s ",ep_address_to_str(&pinfo->src), ep_address_to_str(&pinfo->dst));
1392 dbg(51,"Tid %lx ",tcaphash_end_key.tid);
1394 p_tcaphash_endcall = find_tcaphash_end(&tcaphash_end_key, pinfo,TRUE);
1396 if(!p_tcaphash_endcall) {
1397 #ifdef DEBUG_TCAPSRT
1398 dbg(12,"EnotFound ");
1400 tcaphash_begin_key.tid = p_tcapsrt_info->dst_tid;
1401 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1403 /* We have MTP3 PCs (so we can safely do this cast) */
1404 tcaphash_begin_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1405 tcaphash_begin_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1407 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1408 tcaphash_begin_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1409 tcaphash_begin_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1411 tcaphash_begin_key.hashKey=tcaphash_begin_calchash(&tcaphash_begin_key);
1413 #ifdef DEBUG_TCAPSRT
1414 dbg(11,"Bkey %lx ", tcaphash_begin_key.hashKey);
1415 dbg(51,"PC %s %s ",ep_address_to_str(&pinfo->src), ep_address_to_str(&pinfo->dst));
1416 dbg(51,"Tid %lx ",tcaphash_begin_key.tid);
1418 p_tcaphash_begincall = find_tcaphash_begin(&tcaphash_begin_key, pinfo,FALSE);
1419 if(!p_tcaphash_begincall) {
1420 #ifdef DEBUG_TCAPSRT
1421 dbg(12,"BnotFound ");
1425 if (p_tcaphash_endcall) {
1426 /* Use the TC_BEGIN Destination reference */
1427 p_tcaphash_context=p_tcaphash_endcall->context;
1428 } else if (p_tcaphash_begincall) {
1429 /* Use the TC_BEGIN Source reference */
1430 p_tcaphash_context=p_tcaphash_begincall->context;
1433 if (p_tcaphash_context) {
1435 #ifdef DEBUG_TCAPSRT
1436 dbg(12,"Found, req=%d ",p_tcaphash_context->first_frame);
1438 if (gtcap_DisplaySRT && tree) {
1439 stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
1440 PROTO_ITEM_SET_GENERATED(stat_item);
1441 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1443 pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
1444 PROTO_ITEM_SET_GENERATED(pi);
1447 #ifdef DEBUG_TCAPSRT
1448 dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
1450 /* Indicate the frame to which this is a reply. */
1451 if (gtcap_DisplaySRT && stat_tree) {
1452 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
1453 p_tcaphash_context->first_frame,
1454 "Begin of session in frame %u",
1455 p_tcaphash_context->first_frame);
1456 PROTO_ITEM_SET_GENERATED(pi);
1457 /* Calculate Service Response Time */
1458 nstime_delta(&delta, &pinfo->fd->abs_ts, &p_tcaphash_context->begin_time);
1460 /* display Service Response Time and make it filterable */
1461 pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
1462 PROTO_ITEM_SET_GENERATED(pi);
1464 /* Close the context and remove it (if needed) */
1465 tcapsrt_close(p_tcaphash_context,pinfo);
1467 } else {/* context present */
1468 #ifdef DEBUG_TCAPSRT
1469 dbg(12,"Context notFound ");
1472 return p_tcaphash_context;
1477 * Create the record identifiying the TCAP transaction
1478 * When the identifier for the transaction is reused, check
1479 * the following criteria before to append a new record:
1480 * - a timeout corresponding to a message retransmission is detected,
1481 * - a message hast been lost
1482 * - or the previous transaction has been be closed
1484 static struct tcaphash_context_t *
1485 tcaphash_ansi_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1486 struct tcapsrt_info_t *p_tcapsrt_info)
1488 struct tcaphash_context_t *p_tcaphash_context=NULL;
1489 struct tcaphash_context_key_t tcaphash_context_key;
1490 struct tcaphash_ansicall_t *p_tcaphash_ansicall, *p_new_tcaphash_ansicall;
1491 struct tcaphash_ansi_info_key_t tcaphash_ansi_key;
1494 gboolean isResponse=FALSE;
1495 proto_tree * stat_tree=NULL;
1496 proto_item * stat_item=NULL;
1498 /* prepare the key data */
1499 tcaphash_ansi_key.tid = p_tcapsrt_info->src_tid;
1500 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1502 /* We have MTP3 PCs (so we can safely do this cast) */
1503 tcaphash_ansi_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1504 tcaphash_ansi_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1506 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1507 tcaphash_ansi_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1508 tcaphash_ansi_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1510 tcaphash_ansi_key.hashKey=tcaphash_ansi_calchash(&tcaphash_ansi_key);
1512 /* look up the request */
1513 #ifdef DEBUG_TCAPSRT
1514 dbg(10,"\n Hansi #%u ", pinfo->fd->num);
1515 dbg(11,"key %lx ",tcaphash_ansi_key.hashKey);
1516 dbg(51,"PC %s %s ",ep_address_to_str(&pinfo->src), ep_address_to_str(&pinfo->dst));
1517 dbg(51,"Tid %lx ",tcaphash_ansi_key.tid);
1519 p_tcaphash_ansicall = (struct tcaphash_ansicall_t *)
1520 g_hash_table_lookup(tcaphash_ansi, &tcaphash_ansi_key);
1522 if (p_tcaphash_ansicall) {
1523 /* Walk through list of transaction with identical keys */
1525 /* Check if the request with this reqSeqNum has been seen */
1526 if (pinfo->fd->num == p_tcaphash_ansicall->context->first_frame) {
1527 /* We have seen this request before -> do nothing */
1528 #ifdef DEBUG_TCAPSRT
1529 dbg(22,"Request already seen ");
1532 p_tcaphash_context=p_tcaphash_ansicall->context;
1536 /* Check if the reponse with this reqSeqNum has been seen */
1537 if (pinfo->fd->num == p_tcaphash_ansicall->context->last_frame) {
1538 /* We have seen this response before -> do nothing */
1539 #ifdef DEBUG_TCAPSRT
1540 dbg(22,"Response already seen ");
1543 p_tcaphash_context=p_tcaphash_ansicall->context;
1547 /* Check for the first Request without Response
1548 received before this frame */
1549 if ( pinfo->fd->num > p_tcaphash_ansicall->context->first_frame &&
1550 p_tcaphash_ansicall->context->last_frame==0 ) {
1551 /* Take it, and update the context */
1553 #ifdef DEBUG_TCAPSRT
1554 dbg(12,"Update key %lx ",tcaphash_ansi_key.hashKey);
1556 p_tcaphash_ansicall->context->last_frame = pinfo->fd->num;
1557 p_tcaphash_ansicall->context->responded = TRUE;
1558 p_tcaphash_ansicall->context->closed = TRUE;
1559 p_tcaphash_context=p_tcaphash_ansicall->context;
1562 if (gtcap_DisplaySRT && tree) {
1563 stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
1564 PROTO_ITEM_SET_GENERATED(stat_item);
1565 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1567 pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
1568 PROTO_ITEM_SET_GENERATED(pi);
1570 #ifdef DEBUG_TCAPSRT
1571 dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
1573 /* Indicate the frame to which this is a reply. */
1574 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
1575 p_tcaphash_context->first_frame,
1576 "Begin of session in frame %u",
1577 p_tcaphash_context->first_frame);
1578 PROTO_ITEM_SET_GENERATED(pi);
1579 /* Calculate Service Response Time */
1580 nstime_delta(&delta, &pinfo->fd->abs_ts, &p_tcaphash_context->begin_time);
1582 /* display Service Response Time and make it filterable */
1583 pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
1584 PROTO_ITEM_SET_GENERATED(pi);
1587 } /* Lastframe=0, so take it */
1590 /* If the last record for Tcap transaction with identifier has been reached */
1591 if (!p_tcaphash_ansicall->next_ansicall) {
1592 /* check if we have to create a new record or not */
1593 /* if last request has been responded (response number in known)
1594 and this request appears after last response (has bigger frame number)
1595 and last request occurred after the timeout for repetition,
1597 if last request hasn't been responded (so number unknown)
1598 and this request appears after last request (has bigger frame number)
1599 and this request occurred after the timeout for message lost */
1600 if ( ( p_tcaphash_ansicall->context->last_frame != 0
1601 && pinfo->fd->num > p_tcaphash_ansicall->context->first_frame
1602 && (guint) pinfo->fd->abs_ts.secs > (guint)(p_tcaphash_ansicall->context->begin_time.secs + gtcap_RepetitionTimeout)
1604 ( p_tcaphash_ansicall->context->last_frame == 0
1605 && pinfo->fd->num > p_tcaphash_ansicall->context->first_frame
1606 && (guint)pinfo->fd->abs_ts.secs > (guint)(p_tcaphash_ansicall->context->begin_time.secs + gtcap_LostTimeout)
1610 /* we decide that we have a new request */
1611 /* Append new record to the list */
1612 #ifdef DEBUG_TCAPSRT
1613 dbg(12,"(timeout) Append key %lx ",tcaphash_ansi_key.hashKey);
1614 dbg(12,"Frame %u rsp %u ",pinfo->fd->num,p_tcaphash_ansicall->context->last_frame );
1616 tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
1617 p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
1618 p_new_tcaphash_ansicall = append_tcaphash_ansicall(p_tcaphash_ansicall,
1622 #ifdef DEBUG_TCAPSRT
1623 dbg(12,"Update key %lx ",tcaphash_ansi_key.hashKey);
1625 update_tcaphash_ansicall(p_new_tcaphash_ansicall, pinfo);
1626 p_tcaphash_ansicall=p_new_tcaphash_ansicall;
1629 /* If the Tid is reused for a closed Transaction */
1630 if ( p_tcaphash_ansicall->context->closed) {
1631 #ifdef DEBUG_TCAPSRT
1632 dbg(12,"(closed) Append key %lu ",tcaphash_ansi_key.hashKey);
1633 dbg(12,"Frame %u rsp %u ",pinfo->fd->num,p_tcaphash_ansicall->context->last_frame );
1635 tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
1636 p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
1637 p_new_tcaphash_ansicall = append_tcaphash_ansicall(p_tcaphash_ansicall,
1641 #ifdef DEBUG_TCAPSRT
1642 dbg(12,"Update key %lu ",tcaphash_ansi_key.hashKey);
1644 update_tcaphash_ansicall(p_new_tcaphash_ansicall, pinfo);
1645 p_tcaphash_ansicall=p_new_tcaphash_ansicall;
1648 /* the Tid is reused for an opened Transaction */
1649 /* so, this is the reply to the request of our context */
1650 p_tcaphash_context=p_tcaphash_ansicall->context;
1651 #ifdef DEBUG_TCAPSRT
1652 dbg(12,"Found, req=%d ",p_tcaphash_context->first_frame);
1655 if (gtcap_DisplaySRT && tree) {
1656 stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
1657 PROTO_ITEM_SET_GENERATED(stat_item);
1658 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1660 pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
1661 PROTO_ITEM_SET_GENERATED(pi);
1663 #ifdef DEBUG_TCAPSRT
1664 dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
1666 /* Indicate the frame to which this is a reply. */
1667 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
1668 p_tcaphash_context->first_frame,
1669 "Begin of session in frame %u",
1670 p_tcaphash_context->first_frame);
1671 PROTO_ITEM_SET_GENERATED(pi);
1672 /* Calculate Service Response Time */
1673 nstime_delta(&delta, &pinfo->fd->abs_ts, &p_tcaphash_context->begin_time);
1675 /* display Service Response Time and make it filterable */
1676 pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
1677 PROTO_ITEM_SET_GENERATED(pi);
1679 p_tcaphash_context=p_tcaphash_ansicall->context;
1680 } /* test with Timeout */
1683 } /* Next call is NULL */
1684 p_tcaphash_ansicall = p_tcaphash_ansicall->next_ansicall;
1685 } while (p_tcaphash_ansicall != NULL );
1689 } else { /* p_tcaphash_ansicall has not been found */
1690 #ifdef DEBUG_TCAPSRT
1691 dbg(10,"New key %lx ",tcaphash_ansi_key.hashKey);
1694 tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
1695 p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
1696 p_tcaphash_ansicall = new_tcaphash_ansi(&tcaphash_ansi_key, p_tcaphash_context);
1698 #ifdef DEBUG_TCAPSRT
1699 dbg(11,"Update key %lx ",tcaphash_ansi_key.hashKey);
1700 dbg(11,"Frame reqlink #%u ", pinfo->fd->num);
1702 update_tcaphash_ansicall(p_tcaphash_ansicall, pinfo);
1705 /* display tcap session, if available */
1706 if ( gtcap_DisplaySRT && tree &&
1707 p_tcaphash_context &&
1708 p_tcaphash_context->session_id) {
1709 stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
1710 PROTO_ITEM_SET_GENERATED(stat_item);
1711 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1712 pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
1713 PROTO_ITEM_SET_GENERATED(pi);
1717 /* add link to response frame, if available */
1718 if( gtcap_DisplaySRT && stat_tree &&
1719 p_tcaphash_ansicall->context->last_frame != 0){
1720 if (!isResponse) { /* Request */
1721 #ifdef DEBUG_TCAPSRT
1722 dbg(20,"Display_frameRsplink %d ",p_tcaphash_ansicall->context->last_frame);
1724 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_BeginSession, tvb, 0, 0,
1725 p_tcaphash_ansicall->context->last_frame,
1726 "End of session in frame %u",
1727 p_tcaphash_ansicall->context->last_frame);
1728 PROTO_ITEM_SET_GENERATED(pi);
1729 } else { /* Response */
1730 #ifdef DEBUG_TCAPSRT
1731 dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
1733 /* Indicate the frame to which this is a reply. */
1734 if (gtcap_DisplaySRT) {
1735 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
1736 p_tcaphash_context->first_frame,
1737 "Begin of session in frame %u",
1738 p_tcaphash_context->first_frame);
1739 PROTO_ITEM_SET_GENERATED(pi);
1740 /* Calculate Service Response Time */
1741 nstime_delta(&delta, &pinfo->fd->abs_ts, &p_tcaphash_context->begin_time);
1743 /* display Service Response Time and make it filterable */
1744 pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
1745 PROTO_ITEM_SET_GENERATED(pi);
1747 } /* Request or Response */
1749 return p_tcaphash_context;
1754 * Initialize the Message Info used by the main dissector
1755 * Data are linked to a TCAP transaction
1757 struct tcapsrt_info_t *
1758 tcapsrt_razinfo(void)
1760 struct tcapsrt_info_t *p_tcapsrt_info ;
1762 /* Global buffer for packet extraction */
1763 tcapsrt_global_current++;
1764 if(tcapsrt_global_current==MAX_TCAP_INSTANCE){
1765 tcapsrt_global_current=0;
1768 p_tcapsrt_info=&tcapsrt_global_info[tcapsrt_global_current];
1769 memset(p_tcapsrt_info,0,sizeof(struct tcapsrt_info_t));
1771 return p_tcapsrt_info;
1775 tcapsrt_close(struct tcaphash_context_t *p_tcaphash_context,
1778 #ifdef DEBUG_TCAPSRT
1779 dbg(60,"Force close ");
1781 if (p_tcaphash_context) {
1782 p_tcaphash_context->responded=TRUE;
1783 p_tcaphash_context->last_frame = pinfo->fd->num;
1784 p_tcaphash_context->end_time = pinfo->fd->abs_ts;
1785 p_tcaphash_context->closed=TRUE;
1787 /* If the endkey is present */
1788 if (p_tcaphash_context->endcall
1789 && !gtcap_PersistentSRT) {
1790 if (p_tcaphash_context->endcall->next_endcall) {
1791 if (p_tcaphash_context->endcall->previous_endcall ) {
1792 #ifdef DEBUG_TCAPSRT
1793 dbg(20,"deplace Ehash ");
1795 p_tcaphash_context->endcall->previous_endcall->next_endcall
1796 = p_tcaphash_context->endcall->next_endcall;
1797 p_tcaphash_context->endcall->next_endcall->previous_endcall
1798 = p_tcaphash_context->endcall->previous_endcall;
1799 g_hash_table_remove(tcaphash_end, p_tcaphash_context->endcall->endkey);
1801 g_free(p_tcaphash_context->endcall);
1804 /* cannot remove the father */
1805 #ifdef DEBUG_TCAPSRT
1806 dbg(20,"father Ehash ");
1808 } /* no previous link, so father */
1809 } else if (!gtcap_PersistentSRT) {
1810 #ifdef DEBUG_TCAPSRT
1811 dbg(20,"remove Ehash ");
1813 g_hash_table_remove(tcaphash_end, p_tcaphash_context->endcall->endkey);
1815 g_free(p_tcaphash_context->endcall->endkey);
1816 g_free(p_tcaphash_context->endcall);
1819 } /* endcall without chained string */
1823 /* If the contkey is present */
1824 if (p_tcaphash_context->contcall
1825 && !gtcap_PersistentSRT) {
1826 if (p_tcaphash_context->contcall->next_contcall) {
1827 if (p_tcaphash_context->contcall->previous_contcall ) {
1828 #ifdef DEBUG_TCAPSRT
1829 dbg(20,"deplace Chash ");
1831 p_tcaphash_context->contcall->previous_contcall->next_contcall
1832 = p_tcaphash_context->contcall->next_contcall;
1833 p_tcaphash_context->contcall->next_contcall->previous_contcall
1834 = p_tcaphash_context->contcall->previous_contcall;
1835 g_hash_table_remove(tcaphash_cont, p_tcaphash_context->contcall->contkey);
1837 g_free(p_tcaphash_context->contcall);
1840 /* cannot remove the father */
1841 #ifdef DEBUG_TCAPSRT
1842 dbg(20,"father Chash ");
1844 } /* no previous link, so father */
1845 } else if (!gtcap_PersistentSRT) {
1846 #ifdef DEBUG_TCAPSRT
1847 dbg(20,"remove Chash ");
1849 g_hash_table_remove(tcaphash_cont, p_tcaphash_context->contcall->contkey);
1851 g_free(p_tcaphash_context->contcall->contkey);
1852 g_free(p_tcaphash_context->contcall);
1854 } /* contcall without chained string */
1858 /* If the beginkey is present */
1859 if (p_tcaphash_context->begincall
1860 && !gtcap_PersistentSRT) {
1861 if (p_tcaphash_context->begincall->next_begincall) {
1862 if (p_tcaphash_context->begincall->previous_begincall ) {
1863 #ifdef DEBUG_TCAPSRT
1864 dbg(20,"deplace Bhash ");
1866 p_tcaphash_context->begincall->previous_begincall->next_begincall
1867 = p_tcaphash_context->begincall->next_begincall;
1868 p_tcaphash_context->begincall->next_begincall->previous_begincall
1869 = p_tcaphash_context->begincall->previous_begincall;
1870 g_hash_table_remove(tcaphash_begin, p_tcaphash_context->begincall->beginkey);
1872 g_free(p_tcaphash_context->begincall);
1875 /* cannot remove the father */
1876 #ifdef DEBUG_TCAPSRT
1877 dbg(20,"father Bhash ");
1880 } else if (!gtcap_PersistentSRT) {
1881 #ifdef DEBUG_TCAPSRT
1882 dbg(20,"remove Bhash ");
1884 g_hash_table_remove(tcaphash_begin, p_tcaphash_context->begincall->beginkey);
1886 g_free(p_tcaphash_context->begincall->beginkey);
1887 g_free(p_tcaphash_context->begincall);
1889 } /* begincall without chained string */
1890 } /* no begincall */
1892 /* If the ansikey is present */
1893 if (p_tcaphash_context->ansicall
1894 && !gtcap_PersistentSRT) {
1895 if (p_tcaphash_context->ansicall->next_ansicall) {
1896 if (p_tcaphash_context->ansicall->previous_ansicall ) {
1897 #ifdef DEBUG_TCAPSRT
1898 dbg(20,"deplace Ahash ");
1900 p_tcaphash_context->ansicall->previous_ansicall->next_ansicall
1901 = p_tcaphash_context->ansicall->next_ansicall;
1902 p_tcaphash_context->ansicall->next_ansicall->previous_ansicall
1903 = p_tcaphash_context->ansicall->previous_ansicall;
1904 g_hash_table_remove(tcaphash_ansi, p_tcaphash_context->ansicall->ansikey);
1906 g_free(p_tcaphash_context->ansicall);
1909 /* cannot remove the father */
1910 #ifdef DEBUG_TCAPSRT
1911 dbg(20,"father Ahash ");
1914 } else if (!gtcap_PersistentSRT) {
1915 #ifdef DEBUG_TCAPSRT
1916 dbg(20,"remove Ahash ");
1918 g_hash_table_remove(tcaphash_ansi, p_tcaphash_context->ansicall->ansikey);
1920 g_free(p_tcaphash_context->ansicall->ansikey);
1921 g_free(p_tcaphash_context->ansicall);
1923 } /* ansicall without chained string */
1926 if (!gtcap_PersistentSRT) {
1927 #ifdef DEBUG_TCAPSRT
1928 dbg(20,"remove context ");
1930 g_hash_table_remove(tcaphash_context, p_tcaphash_context->key);
1932 g_free(p_tcaphash_context->key);
1933 g_free(p_tcaphash_context);
1936 } else { /* no context */
1937 #ifdef DEBUG_TCAPSRT
1938 dbg(20,"No context to remove ");