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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
35 #include <epan/emem.h>
36 #include <epan/packet.h>
37 #include <epan/asn1.h>
38 #include <epan/tcap-persistentdata.h>
39 #include <epan/dissectors/packet-tcap.h>
40 #include <epan/dissectors/packet-mtp3.h>
42 static gint tcaphash_context_equal(gconstpointer k1, gconstpointer k2);
43 static guint tcaphash_context_calchash(gconstpointer k);
44 static gint tcaphash_begin_equal(gconstpointer k1, gconstpointer k2);
45 static guint tcaphash_begin_calchash(gconstpointer k);
46 static gint tcaphash_cont_equal(gconstpointer k1, gconstpointer k2);
47 static guint tcaphash_cont_calchash(gconstpointer k);
48 static gint tcaphash_end_equal(gconstpointer k1, gconstpointer k2);
49 static guint tcaphash_end_calchash(gconstpointer k);
50 static gint tcaphash_ansi_equal(gconstpointer k1, gconstpointer k2);
51 static guint tcaphash_ansi_calchash(gconstpointer k);
53 static void update_tcaphash_begincall(struct tcaphash_begincall_t *p_tcaphash_begincall,
56 static struct tcaphash_begincall_t *append_tcaphash_begincall(struct tcaphash_begincall_t *prev_begincall,
57 struct tcaphash_context_t *p_tcaphash_context,
61 static struct tcaphash_begincall_t *find_tcaphash_begin(struct tcaphash_begin_info_key_t *p_tcaphash_begin_key,
66 static struct tcaphash_contcall_t *find_tcaphash_cont(struct tcaphash_cont_info_key_t *p_tcaphash_cont_key,
69 static struct tcaphash_endcall_t *find_tcaphash_end(struct tcaphash_end_info_key_t *p_tcaphash_end_key,
73 static struct tcaphash_context_t *new_tcaphash_context(struct tcaphash_context_key_t *p_tcaphash_context_key,
76 static struct tcaphash_begincall_t *new_tcaphash_begin(struct tcaphash_begin_info_key_t *p_tcaphash_begin_key,
77 struct tcaphash_context_t *p_tcaphash_context);
79 static struct tcaphash_contcall_t *new_tcaphash_cont(struct tcaphash_cont_info_key_t *p_tcaphash_cont_key,
80 struct tcaphash_context_t *p_tcaphash_context);
82 static struct tcaphash_endcall_t *new_tcaphash_end(struct tcaphash_end_info_key_t *p_tcaphash_end_key,
83 struct tcaphash_context_t *p_tcaphash_context);
85 static struct tcaphash_context_t *tcaphash_begin_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
86 struct tcapsrt_info_t *p_tcapsrt_info);
88 static struct tcaphash_context_t *tcaphash_cont_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
89 struct tcapsrt_info_t *p_tcapsrt_info);
91 static struct tcaphash_context_t *tcaphash_end_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
92 struct tcapsrt_info_t *p_tcapsrt_info);
94 static struct tcaphash_context_t *tcaphash_ansi_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
95 struct tcapsrt_info_t *p_tcapsrt_info);
97 struct tcapsrt_info_t *tcapsrt_razinfo(void);
99 /* When several Tcap components are received in a single TCAP message,
100 we have to use several buffers for the stored parameters
101 because else this data are erased during TAP dissector call */
102 #define MAX_TCAP_INSTANCE 10
103 int tcapsrt_global_current=0;
104 struct tcapsrt_info_t tcapsrt_global_info[MAX_TCAP_INSTANCE];
106 /* These two timeout (in second) are used when some message are lost,
107 or when the same TCAP transcation identifier is reused */
108 guint gtcap_RepetitionTimeout = 10;
109 guint gtcap_LostTimeout = 30;
110 extern gboolean gtcap_HandleSRT;
111 gboolean gtcap_PersistentSRT=FALSE;
112 gboolean gtcap_DisplaySRT=FALSE;
113 gboolean gtcap_StatSRT=FALSE;
115 extern gint ett_tcap_stat;
117 extern int hf_tcapsrt_SessionId;
118 extern int hf_tcapsrt_Duplicate;
119 extern int hf_tcapsrt_BeginSession;
120 extern int hf_tcapsrt_EndSession;
121 extern int hf_tcapsrt_SessionTime;
123 /* Global hash tables*/
124 static GHashTable *tcaphash_context = NULL;
125 static GHashTable *tcaphash_begin = NULL;
126 static GHashTable *tcaphash_cont = NULL;
127 static GHashTable *tcaphash_end = NULL;
128 static GHashTable *tcaphash_ansi = NULL;
130 guint32 tcapsrt_global_SessionId=1;
136 /* #define MEM_TCAPSRT */
139 /* #define DEBUG_TCAPSRT */
144 static unsigned debug_level = 99;
147 dbg(unsigned level, char* fmt, ...)
151 if (level > debug_level) return;
153 vfprintf(stderr, fmt, ap);
159 tcaphash_context_equal(gconstpointer k1, gconstpointer k2)
161 const struct tcaphash_context_key_t *key1 = (const struct tcaphash_context_key_t *) k1;
162 const struct tcaphash_context_key_t *key2 = (const struct tcaphash_context_key_t *) k2;
164 return (key1->session_id == key2->session_id);
167 /* calculate a hash key */
169 tcaphash_context_calchash(gconstpointer k)
171 const struct tcaphash_context_key_t *key = (const struct tcaphash_context_key_t *) k;
172 return key->session_id;
177 tcaphash_begin_equal(gconstpointer k1, gconstpointer k2)
179 const struct tcaphash_begin_info_key_t *key1 = (const struct tcaphash_begin_info_key_t *) k1;
180 const struct tcaphash_begin_info_key_t *key2 = (const struct tcaphash_begin_info_key_t *) k2;
182 if (key1->hashKey == key2->hashKey) {
184 if ( ( (key1->opc_hash == key2->opc_hash) &&
185 (key1->dpc_hash == key2->dpc_hash) &&
186 (key1->tid == key2->tid) )
188 ( (key1->opc_hash == key2->dpc_hash) &&
189 (key1->dpc_hash == key2->opc_hash) &&
190 (key1->tid == key2->tid) )
197 /* calculate a hash key */
199 tcaphash_begin_calchash(gconstpointer k)
201 const struct tcaphash_begin_info_key_t *key = (const struct tcaphash_begin_info_key_t *) k;
203 /* hashkey = key->opc_hash<<16 + key->dpc_hash<<8 + key->src_tid; */
209 tcaphash_cont_equal(gconstpointer k1, gconstpointer k2)
211 const struct tcaphash_cont_info_key_t *key1 = (const struct tcaphash_cont_info_key_t *) k1;
212 const struct tcaphash_cont_info_key_t *key2 = (const struct tcaphash_cont_info_key_t *) k2;
214 if (key1->hashKey == key2->hashKey) {
216 if ( (key1->opc_hash == key2->opc_hash) &&
217 (key1->dpc_hash == key2->dpc_hash) &&
218 (key1->src_tid == key2->src_tid) &&
219 (key1->dst_tid == key2->dst_tid) ) {
222 else if ( (key1->opc_hash == key2->dpc_hash) &&
223 (key1->dpc_hash == key2->opc_hash) &&
224 (key1->src_tid == key2->dst_tid) &&
225 (key1->dst_tid == key2->src_tid) ) {
232 /* calculate a hash key */
234 tcaphash_cont_calchash(gconstpointer k)
236 const struct tcaphash_cont_info_key_t *key = (const struct tcaphash_cont_info_key_t *) k;
238 hashkey = key->src_tid + key->dst_tid;
244 tcaphash_end_equal(gconstpointer k1, gconstpointer k2)
246 const struct tcaphash_end_info_key_t *key1 = (const struct tcaphash_end_info_key_t *) k1;
247 const struct tcaphash_end_info_key_t *key2 = (const struct tcaphash_end_info_key_t *) k2;
249 if (key1->hashKey == key2->hashKey) {
250 if ( ( (key1->opc_hash == key2->opc_hash) &&
251 (key1->dpc_hash == key2->dpc_hash) &&
252 (key1->tid == key2->tid) )
254 ( (key1->opc_hash == key2->dpc_hash) &&
255 (key1->dpc_hash == key2->opc_hash) &&
256 (key1->tid == key2->tid) ) )
262 /* calculate a hash key */
264 tcaphash_end_calchash(gconstpointer k)
266 const struct tcaphash_end_info_key_t *key = (const struct tcaphash_end_info_key_t *) k;
273 tcaphash_ansi_equal(gconstpointer k1, gconstpointer k2)
275 const struct tcaphash_ansi_info_key_t *key1 = (const struct tcaphash_ansi_info_key_t *) k1;
276 const struct tcaphash_ansi_info_key_t *key2 = (const struct tcaphash_ansi_info_key_t *) k2;
278 if (key1->hashKey == key2->hashKey) {
280 if ( ( (key1->opc_hash == key2->opc_hash) &&
281 (key1->dpc_hash == key2->dpc_hash) &&
282 (key1->tid == key2->tid) )
284 ( (key1->opc_hash == key2->dpc_hash) &&
285 (key1->dpc_hash == key2->opc_hash) &&
286 (key1->tid == key2->tid) )
293 /* calculate a hash key */
295 tcaphash_ansi_calchash(gconstpointer k)
297 const struct tcaphash_ansi_info_key_t *key = (const struct tcaphash_ansi_info_key_t *) k;
299 /* hashkey = key->opc_hash<<16 + key->dpc_hash<<8 + key->src_tid; */
305 * Update a record with the data of the Request
308 update_tcaphash_begincall(struct tcaphash_begincall_t *p_tcaphash_begincall,
311 p_tcaphash_begincall->context->first_frame = pinfo->fd->num;
312 p_tcaphash_begincall->context->last_frame = 0;
313 p_tcaphash_begincall->context->responded = FALSE;
314 p_tcaphash_begincall->context->begin_time = pinfo->fd->abs_ts;
318 * Append a new dialogue, using the same Key, to the chained list
319 * The time is stored too
321 static struct tcaphash_begincall_t *
322 append_tcaphash_begincall(struct tcaphash_begincall_t *prev_begincall,
323 struct tcaphash_context_t *p_tcaphash_context,
326 struct tcaphash_begincall_t *p_new_tcaphash_begincall = NULL;
328 /* Append the transaction to the list, when the same key is found
329 This should append when the tcap-transaction Id is reused */
332 p_new_tcaphash_begincall = g_malloc0(sizeof(struct tcaphash_begincall_t));
334 p_new_tcaphash_begincall = se_alloc0(sizeof(struct tcaphash_begincall_t));
336 p_new_tcaphash_begincall->context=p_tcaphash_context;
337 p_tcaphash_context->begincall=p_new_tcaphash_begincall;
338 p_new_tcaphash_begincall->beginkey=prev_begincall->beginkey;
339 p_new_tcaphash_begincall->context->first_frame = pinfo->fd->num;
340 p_new_tcaphash_begincall->next_begincall=NULL;
341 p_new_tcaphash_begincall->previous_begincall=prev_begincall;
342 p_new_tcaphash_begincall->father=FALSE;
345 dbg(10,"+B%d ", p_new_tcaphash_begincall->context->session_id);
347 /* Insert in the chained list */
348 prev_begincall->next_begincall = p_new_tcaphash_begincall;
349 if (prev_begincall->context->last_frame == 0) {
353 prev_begincall->context->last_frame = pinfo->fd->num-1;
355 return p_new_tcaphash_begincall;
359 * Update a record with the data of the Request
362 update_tcaphash_ansicall(struct tcaphash_ansicall_t *p_tcaphash_ansicall,
365 p_tcaphash_ansicall->context->first_frame = pinfo->fd->num;
366 p_tcaphash_ansicall->context->last_frame = 0;
367 p_tcaphash_ansicall->context->responded = FALSE;
368 p_tcaphash_ansicall->context->begin_time = pinfo->fd->abs_ts;
372 * Append a new dialogue, using the same Key, to the chained list
373 * The time is stored too
375 static struct tcaphash_ansicall_t *
376 append_tcaphash_ansicall(struct tcaphash_ansicall_t *prev_ansicall,
377 struct tcaphash_context_t *p_tcaphash_context,
380 struct tcaphash_ansicall_t *p_new_tcaphash_ansicall = NULL;
382 /* Append the transaction to the list, when the same key is found
383 This should append when the tcap-transaction Id is reused */
386 p_new_tcaphash_ansicall = g_malloc0(sizeof(struct tcaphash_ansicall_t));
388 p_new_tcaphash_ansicall = se_alloc0(sizeof(struct tcaphash_ansicall_t));
390 p_new_tcaphash_ansicall->context=p_tcaphash_context;
391 p_tcaphash_context->ansicall=p_new_tcaphash_ansicall;
392 p_new_tcaphash_ansicall->ansikey=prev_ansicall->ansikey;
393 p_new_tcaphash_ansicall->context->first_frame = pinfo->fd->num;
394 p_new_tcaphash_ansicall->next_ansicall=NULL;
395 p_new_tcaphash_ansicall->previous_ansicall=prev_ansicall;
396 p_new_tcaphash_ansicall->father=FALSE;
399 dbg(10,"+A%d ", p_new_tcaphash_ansicall->context->session_id);
401 /* Insert in the chained list */
402 prev_ansicall->next_ansicall = p_new_tcaphash_ansicall;
403 if (prev_ansicall->context->last_frame == 0) {
407 prev_ansicall->context->last_frame = pinfo->fd->num-1;
409 return p_new_tcaphash_ansicall;
413 static struct tcaphash_contcall_t *
414 append_tcaphash_contcall(struct tcaphash_contcall_t *prev_contcall,
415 struct tcaphash_context_t *p_tcaphash_context)
417 struct tcaphash_contcall_t *p_new_tcaphash_contcall = NULL;
419 /* Append the transaction to the list, when the same key is found
420 This should append when the tcap-transaction Id is reused */
423 p_new_tcaphash_contcall = g_malloc0(sizeof(struct tcaphash_contcall_t));
425 p_new_tcaphash_contcall = se_alloc0(sizeof(struct tcaphash_contcall_t));
427 p_new_tcaphash_contcall->context=p_tcaphash_context;
428 p_tcaphash_context->contcall=p_new_tcaphash_contcall;
429 p_new_tcaphash_contcall->contkey=prev_contcall->contkey;
430 p_new_tcaphash_contcall->next_contcall=NULL;
431 p_new_tcaphash_contcall->previous_contcall=prev_contcall;
432 p_new_tcaphash_contcall->father=FALSE;
435 dbg(10,"+C%d ", p_new_tcaphash_contcall->context->session_id);
437 /* Insert in the chained list */
438 prev_contcall->next_contcall = p_new_tcaphash_contcall;
439 return p_new_tcaphash_contcall;
443 static struct tcaphash_endcall_t *
444 append_tcaphash_endcall(struct tcaphash_endcall_t *prev_endcall,
445 struct tcaphash_context_t *p_tcaphash_context)
447 struct tcaphash_endcall_t *p_new_tcaphash_endcall = NULL;
449 /* Append the transaction to the list, when the same key is found
450 This should append when the tcap-transaction Id is reused */
453 p_new_tcaphash_endcall = g_malloc0(sizeof(struct tcaphash_endcall_t));
455 p_new_tcaphash_endcall = se_alloc0(sizeof(struct tcaphash_endcall_t));
457 p_new_tcaphash_endcall->context=p_tcaphash_context;
458 p_tcaphash_context->endcall=p_new_tcaphash_endcall;
459 p_new_tcaphash_endcall->endkey=prev_endcall->endkey;
460 p_new_tcaphash_endcall->next_endcall=NULL;
461 p_new_tcaphash_endcall->previous_endcall=prev_endcall;
462 p_new_tcaphash_endcall->father=FALSE;
465 dbg(10,"+E%d ", p_new_tcaphash_endcall->context->session_id);
467 /* Insert in the chained list */
468 prev_endcall->next_endcall = p_new_tcaphash_endcall;
469 return p_new_tcaphash_endcall;
474 * Find the dialog by Key and Time
476 static struct tcaphash_begincall_t *
477 find_tcaphash_begin(struct tcaphash_begin_info_key_t *p_tcaphash_begin_key,
478 packet_info *pinfo, gboolean isBegin)
480 struct tcaphash_begincall_t *p_tcaphash_begincall = NULL;
481 p_tcaphash_begincall = (struct tcaphash_begincall_t *)g_hash_table_lookup(tcaphash_begin, p_tcaphash_begin_key);
483 if(p_tcaphash_begincall) {
485 if ( p_tcaphash_begincall->context ) {
487 pinfo->fd->num == p_tcaphash_begincall->context->first_frame )
490 pinfo->fd->num >= p_tcaphash_begincall->context->first_frame &&
491 ( p_tcaphash_begincall->context->last_frame?pinfo->fd->num <= p_tcaphash_begincall->context->last_frame:1 )
494 /* We have a dialogue, with this key, opened before this request */
496 dbg(10,"B%d ", p_tcaphash_begincall->context->session_id);
498 return p_tcaphash_begincall;
502 dbg(60,"[B%d] ", p_tcaphash_begincall->context->session_id);
505 /* Break when list end is reached */
506 if(p_tcaphash_begincall->next_begincall == NULL) {
508 dbg(23,"End of Blist ");
512 p_tcaphash_begincall = p_tcaphash_begincall->next_begincall;
513 } while (p_tcaphash_begincall != NULL) ;
516 dbg(23,"Not in Bhash ");
524 static struct tcaphash_contcall_t *
525 find_tcaphash_cont(struct tcaphash_cont_info_key_t *p_tcaphash_cont_key,
528 struct tcaphash_contcall_t *p_tcaphash_contcall = NULL;
529 p_tcaphash_contcall = (struct tcaphash_contcall_t *)g_hash_table_lookup(tcaphash_cont, p_tcaphash_cont_key);
531 if(p_tcaphash_contcall) {
533 if ( p_tcaphash_contcall->context ) {
534 if (pinfo->fd->num >= p_tcaphash_contcall->context->first_frame &&
535 (p_tcaphash_contcall->context->last_frame?pinfo->fd->num <= p_tcaphash_contcall->context->last_frame:1) ) {
536 /* We have a dialogue, with this key, opened before this request */
538 dbg(10,"C%d ", p_tcaphash_contcall->context->session_id);
540 return p_tcaphash_contcall;
544 dbg(60,"[C%d] ", p_tcaphash_contcall->context->session_id);
547 /* Break when list end is reached */
548 if(p_tcaphash_contcall->next_contcall == NULL) {
550 dbg(23,"End of Clist ");
554 p_tcaphash_contcall = p_tcaphash_contcall->next_contcall;
555 } while (p_tcaphash_contcall != NULL) ;
558 dbg(23,"Not in Chash ");
564 static struct tcaphash_endcall_t *
565 find_tcaphash_end(struct tcaphash_end_info_key_t *p_tcaphash_end_key,
566 packet_info *pinfo, gboolean isEnd)
568 struct tcaphash_endcall_t *p_tcaphash_endcall = NULL;
569 p_tcaphash_endcall = (struct tcaphash_endcall_t *)g_hash_table_lookup(tcaphash_end, p_tcaphash_end_key);
571 if(p_tcaphash_endcall) {
573 if ( p_tcaphash_endcall->context ) {
575 (p_tcaphash_endcall->context->last_frame?pinfo->fd->num == p_tcaphash_endcall->context->last_frame:1)
579 pinfo->fd->num >= p_tcaphash_endcall->context->first_frame &&
580 (p_tcaphash_endcall->context->last_frame?pinfo->fd->num <= p_tcaphash_endcall->context->last_frame:1)
583 /* We have a dialogue, with this key, opened before this request */
585 dbg(10,"E%d ", p_tcaphash_endcall->context->session_id);
587 return p_tcaphash_endcall;
591 dbg(60,"[E%d] ", p_tcaphash_endcall->context->session_id);
594 /* Break when list end is reached */
595 if(p_tcaphash_endcall->next_endcall == NULL) {
597 dbg(23,"End of Elist ");
601 p_tcaphash_endcall = p_tcaphash_endcall->next_endcall;
602 } while (p_tcaphash_endcall != NULL) ;
605 dbg(23,"Not in Ehash ");
612 * New record to create, to identify a new transaction
614 static struct tcaphash_context_t *
615 new_tcaphash_context(struct tcaphash_context_key_t *p_tcaphash_context_key,
618 struct tcaphash_context_key_t *p_new_tcaphash_context_key;
619 struct tcaphash_context_t *p_new_tcaphash_context = NULL;
621 /* Register the transaction in the hash table
622 with the tcap transaction Id as Main Key
623 Once created, this entry will be updated later */
626 p_new_tcaphash_context_key = g_malloc(sizeof(struct tcaphash_context_key_t));
628 p_new_tcaphash_context_key = se_alloc(sizeof(struct tcaphash_context_key_t));
630 p_new_tcaphash_context_key->session_id = p_tcaphash_context_key->session_id;
633 p_new_tcaphash_context = g_malloc0(sizeof(struct tcaphash_context_t));
635 p_new_tcaphash_context = se_alloc0(sizeof(struct tcaphash_context_t));
637 p_new_tcaphash_context->key = p_new_tcaphash_context_key;
638 p_new_tcaphash_context->session_id = p_tcaphash_context_key->session_id;
639 p_new_tcaphash_context->first_frame = pinfo->fd->num;
641 dbg(10,"S%d ", p_new_tcaphash_context->session_id);
644 g_hash_table_insert(tcaphash_context, p_new_tcaphash_context_key, p_new_tcaphash_context);
645 return p_new_tcaphash_context;
649 * New record to create, to identify a new transaction
651 static struct tcaphash_begincall_t *
652 new_tcaphash_begin(struct tcaphash_begin_info_key_t *p_tcaphash_begin_key,
653 struct tcaphash_context_t *p_tcaphash_context)
655 struct tcaphash_begin_info_key_t *p_new_tcaphash_begin_key;
656 struct tcaphash_begincall_t *p_new_tcaphash_begincall = NULL;
658 /* Register the transaction in the hash table
659 with the tcap transaction Id as Main Key
660 Once created, this entry will be updated later */
663 p_new_tcaphash_begin_key = g_malloc(sizeof(struct tcaphash_begin_info_key_t));
665 p_new_tcaphash_begin_key = se_alloc(sizeof(struct tcaphash_begin_info_key_t));
667 p_new_tcaphash_begin_key->hashKey = p_tcaphash_begin_key->hashKey;
668 p_new_tcaphash_begin_key->tid = p_tcaphash_begin_key->tid;
669 p_new_tcaphash_begin_key->opc_hash = p_tcaphash_begin_key->opc_hash;
670 p_new_tcaphash_begin_key->dpc_hash = p_tcaphash_begin_key->dpc_hash;
673 p_new_tcaphash_begincall = g_malloc0(sizeof(struct tcaphash_begincall_t));
675 p_new_tcaphash_begincall = se_alloc0(sizeof(struct tcaphash_begincall_t));
677 p_new_tcaphash_begincall->beginkey=p_new_tcaphash_begin_key;
678 p_new_tcaphash_begincall->context=p_tcaphash_context;
679 p_tcaphash_context->begincall=p_new_tcaphash_begincall;
680 p_new_tcaphash_begincall->father=TRUE;
681 p_new_tcaphash_begincall->next_begincall=NULL;
682 p_new_tcaphash_begincall->previous_begincall=NULL;
685 dbg(10,"B%d ", p_new_tcaphash_begincall->context->session_id);
688 g_hash_table_insert(tcaphash_begin, p_new_tcaphash_begin_key, p_new_tcaphash_begincall);
689 return p_new_tcaphash_begincall;
695 * New record to create, to identify a new transaction
697 static struct tcaphash_contcall_t *
698 new_tcaphash_cont(struct tcaphash_cont_info_key_t *p_tcaphash_cont_key,
699 struct tcaphash_context_t *p_tcaphash_context)
701 struct tcaphash_cont_info_key_t *p_new_tcaphash_cont_key;
702 struct tcaphash_contcall_t *p_new_tcaphash_contcall = NULL;
704 /* Register the transaction in the hash table
705 with the tcap transaction Id as Main Key
706 Once created, this entry will be updated later */
709 p_new_tcaphash_cont_key = g_malloc(sizeof(struct tcaphash_cont_info_key_t));
711 p_new_tcaphash_cont_key = se_alloc(sizeof(struct tcaphash_cont_info_key_t));
713 p_new_tcaphash_cont_key->hashKey = p_tcaphash_cont_key->hashKey;
714 p_new_tcaphash_cont_key->src_tid = p_tcaphash_cont_key->src_tid;
715 p_new_tcaphash_cont_key->dst_tid = p_tcaphash_cont_key->dst_tid;
716 p_new_tcaphash_cont_key->opc_hash = p_tcaphash_cont_key->opc_hash;
717 p_new_tcaphash_cont_key->dpc_hash = p_tcaphash_cont_key->dpc_hash;
720 p_new_tcaphash_contcall = g_malloc0(sizeof(struct tcaphash_contcall_t));
722 p_new_tcaphash_contcall = se_alloc0(sizeof(struct tcaphash_contcall_t));
724 p_new_tcaphash_contcall->contkey=p_new_tcaphash_cont_key;
725 p_new_tcaphash_contcall->context=p_tcaphash_context;
726 p_tcaphash_context->contcall=p_new_tcaphash_contcall;
727 p_new_tcaphash_contcall->father=TRUE;
728 p_new_tcaphash_contcall->next_contcall=NULL;
729 p_new_tcaphash_contcall->previous_contcall=NULL;
732 dbg(10,"C%d ", p_new_tcaphash_contcall->context->session_id);
735 g_hash_table_insert(tcaphash_cont, p_new_tcaphash_cont_key, p_new_tcaphash_contcall);
736 return p_new_tcaphash_contcall;
741 * New record to create, to identify a new transaction
743 static struct tcaphash_endcall_t *
744 new_tcaphash_end(struct tcaphash_end_info_key_t *p_tcaphash_end_key,
745 struct tcaphash_context_t *p_tcaphash_context)
747 struct tcaphash_end_info_key_t *p_new_tcaphash_end_key;
748 struct tcaphash_endcall_t *p_new_tcaphash_endcall = NULL;
750 /* Register the transaction in the hash table
751 with the tcap transaction Id as Main Key
752 Once created, this entry will be updated later */
755 p_new_tcaphash_end_key = g_malloc(sizeof(struct tcaphash_end_info_key_t));
757 p_new_tcaphash_end_key = se_alloc(sizeof(struct tcaphash_end_info_key_t));
759 p_new_tcaphash_end_key->hashKey = p_tcaphash_end_key->hashKey;
760 p_new_tcaphash_end_key->tid = p_tcaphash_end_key->tid;
761 p_new_tcaphash_end_key->opc_hash = p_tcaphash_end_key->opc_hash;
762 p_new_tcaphash_end_key->dpc_hash = p_tcaphash_end_key->dpc_hash;
765 p_new_tcaphash_endcall = g_malloc0(sizeof(struct tcaphash_endcall_t));
767 p_new_tcaphash_endcall = se_alloc0(sizeof(struct tcaphash_endcall_t));
769 p_new_tcaphash_endcall->endkey=p_new_tcaphash_end_key;
770 p_new_tcaphash_endcall->context=p_tcaphash_context;
771 p_tcaphash_context->endcall=p_new_tcaphash_endcall;
772 p_new_tcaphash_endcall->father=TRUE;
773 p_new_tcaphash_endcall->next_endcall=NULL;
774 p_new_tcaphash_endcall->previous_endcall=NULL;
777 dbg(10,"E%d ", p_new_tcaphash_endcall->context->session_id);
780 g_hash_table_insert(tcaphash_end, p_new_tcaphash_end_key, p_new_tcaphash_endcall);
781 return p_new_tcaphash_endcall;
784 * New record to create, to identify a new transaction
786 static struct tcaphash_ansicall_t *
787 new_tcaphash_ansi(struct tcaphash_ansi_info_key_t *p_tcaphash_ansi_key,
788 struct tcaphash_context_t *p_tcaphash_context)
790 struct tcaphash_ansi_info_key_t *p_new_tcaphash_ansi_key;
791 struct tcaphash_ansicall_t *p_new_tcaphash_ansicall = NULL;
793 /* Register the transaction in the hash table
794 with the tcap transaction Id as Main Key
795 Once created, this entry will be updated later */
798 p_new_tcaphash_ansi_key = g_malloc(sizeof(struct tcaphash_ansi_info_key_t));
800 p_new_tcaphash_ansi_key = se_alloc(sizeof(struct tcaphash_ansi_info_key_t));
802 p_new_tcaphash_ansi_key->hashKey = p_tcaphash_ansi_key->hashKey;
803 p_new_tcaphash_ansi_key->tid = p_tcaphash_ansi_key->tid;
804 p_new_tcaphash_ansi_key->opc_hash = p_tcaphash_ansi_key->opc_hash;
805 p_new_tcaphash_ansi_key->dpc_hash = p_tcaphash_ansi_key->dpc_hash;
808 p_new_tcaphash_ansicall = g_malloc0(sizeof(struct tcaphash_ansicall_t));
810 p_new_tcaphash_ansicall = se_alloc0(sizeof(struct tcaphash_ansicall_t));
812 p_new_tcaphash_ansicall->ansikey=p_new_tcaphash_ansi_key;
813 p_new_tcaphash_ansicall->context=p_tcaphash_context;
814 p_tcaphash_context->ansicall=p_new_tcaphash_ansicall;
815 p_new_tcaphash_ansicall->father=TRUE;
816 p_new_tcaphash_ansicall->next_ansicall=NULL;
817 p_new_tcaphash_ansicall->previous_ansicall=NULL;
820 dbg(10,"A%d ", p_new_tcaphash_ansicall->context->session_id);
823 g_hash_table_insert(tcaphash_ansi, p_new_tcaphash_ansi_key, p_new_tcaphash_ansicall);
824 return p_new_tcaphash_ansicall;
827 static struct tcaphash_contcall_t *
828 create_tcaphash_cont(struct tcaphash_cont_info_key_t *p_tcaphash_cont_key,
829 struct tcaphash_context_t *p_tcaphash_context)
831 struct tcaphash_contcall_t *p_tcaphash_contcall1 = NULL;
832 struct tcaphash_contcall_t *p_tcaphash_contcall = NULL;
834 p_tcaphash_contcall1 = (struct tcaphash_contcall_t *)
835 g_hash_table_lookup(tcaphash_cont, p_tcaphash_cont_key);
837 if (p_tcaphash_contcall1) {
838 /* Walk through list of transaction with identical keys */
839 /* go the the end to insert new record */
841 if (!p_tcaphash_contcall1->next_contcall) {
842 p_tcaphash_contcall=append_tcaphash_contcall(p_tcaphash_contcall1,
846 p_tcaphash_contcall1 = p_tcaphash_contcall1->next_contcall;
847 } while (p_tcaphash_contcall1 != NULL );
849 p_tcaphash_contcall = new_tcaphash_cont(p_tcaphash_cont_key,
852 return p_tcaphash_contcall;
856 static struct tcaphash_endcall_t *
857 create_tcaphash_end(struct tcaphash_end_info_key_t *p_tcaphash_end_key,
858 struct tcaphash_context_t *p_tcaphash_context)
860 struct tcaphash_endcall_t *p_tcaphash_endcall1 = NULL;
861 struct tcaphash_endcall_t *p_tcaphash_endcall = NULL;
863 p_tcaphash_endcall1 = (struct tcaphash_endcall_t *)
864 g_hash_table_lookup(tcaphash_end, p_tcaphash_end_key);
866 if (p_tcaphash_endcall1) {
867 /* Walk through list of transaction with identical keys */
868 /* go the the end to insert new record */
870 if (!p_tcaphash_endcall1->next_endcall) {
871 p_tcaphash_endcall=append_tcaphash_endcall(p_tcaphash_endcall1,
875 p_tcaphash_endcall1 = p_tcaphash_endcall1->next_endcall;
876 } while (p_tcaphash_endcall1 != NULL );
878 p_tcaphash_endcall = new_tcaphash_end(p_tcaphash_end_key,
881 return p_tcaphash_endcall;
886 * Routine called when the TAP is initialized.
887 * so hash table are (re)created
890 tcapsrt_init_routine(void)
893 /* free hash-tables and mem_chunks for SRT */
894 if (tcaphash_context != NULL) {
896 dbg(16,"Destroy hash_context ");
898 g_hash_table_destroy(tcaphash_context);
901 if (tcaphash_begin != NULL) {
903 dbg(16,"Destroy hash_begin ");
905 g_hash_table_destroy(tcaphash_begin);
908 if (tcaphash_cont != NULL) {
910 dbg(16,"Destroy hash_cont ");
912 g_hash_table_destroy(tcaphash_cont);
915 if (tcaphash_end != NULL) {
917 dbg(16,"Destroy hash_end ");
919 g_hash_table_destroy(tcaphash_end);
922 if (tcaphash_ansi != NULL) {
924 dbg(16,"Destroy hash_ansi ");
926 g_hash_table_destroy(tcaphash_ansi);
930 dbg(16,"Create hash ");
932 /* create new hash-tables and mem_chunks for SRT */
933 tcaphash_context = g_hash_table_new(tcaphash_context_calchash, tcaphash_context_equal);
934 tcaphash_begin = g_hash_table_new(tcaphash_begin_calchash, tcaphash_begin_equal);
935 tcaphash_cont = g_hash_table_new(tcaphash_cont_calchash, tcaphash_cont_equal);
936 tcaphash_end = g_hash_table_new(tcaphash_end_calchash, tcaphash_end_equal);
937 tcaphash_ansi = g_hash_table_new(tcaphash_ansi_calchash, tcaphash_ansi_equal);
939 /* Reset the session counter */
940 tcapsrt_global_SessionId=1;
942 /* Display of SRT only if Persistent Stat */
943 gtcap_DisplaySRT=gtcap_PersistentSRT || gtcap_HandleSRT>cap_StatSRT;
947 * Service Response Time analyze
948 * Called just after dissector call
949 * Associate a TCAP context to a tcap session and display session related infomations
950 * like the first frame, the last, the session duration,
951 * and a uniq session identifier for the filtering
953 * For ETSI tcap, the TCAP context can be reached through three keys
954 * - a key (BEGIN) identifying the session according to the tcap source identifier
955 * - a key (CONT) identifying the established session (src_id and dst_id)
956 * - a key (END) identifying the session according to the tcap destination identifier
958 * For ANSI tcap, the TCAP context is reached through a uniq key
959 * - a key (ANSI) identifying the session according to the tcap identifier
961 struct tcaphash_context_t *
962 tcapsrt_call_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
963 struct tcapsrt_info_t *p_tcapsrt_info)
965 struct tcaphash_context_t *tcap_context=NULL;
967 /* if this packet isn't loaded because of a read filter, don't output anything */
968 if(pinfo == NULL || pinfo->fd->num == 0) {
972 switch (p_tcapsrt_info->ope) {
978 tcap_context=tcaphash_begin_matching(tvb, pinfo, tree, p_tcapsrt_info);
985 tcap_context=tcaphash_cont_matching(tvb, pinfo, tree, p_tcapsrt_info);
992 tcap_context=tcaphash_end_matching(tvb, pinfo, tree, p_tcapsrt_info);
999 tcap_context=tcaphash_end_matching(tvb, pinfo, tree, p_tcapsrt_info);
1004 #ifdef DEBUG_TCAPSRT
1007 tcap_context=tcaphash_ansi_matching(tvb, pinfo, tree, p_tcapsrt_info);
1011 #ifdef DEBUG_TCAPSRT
1012 dbg(1,"Unknown %d ", p_tcapsrt_info->ope);
1015 } /* switch tcapop */
1016 #ifdef DEBUG_TCAPSRT
1018 dbg(1,"session %d ", tcap_context->session_id);
1020 return tcap_context;
1025 * Create the record identifiying the TCAP transaction
1026 * When the identifier for the transaction is reused, check
1027 * the following criteria before to append a new record:
1028 * - a timeout corresponding to a message retransmission is detected,
1029 * - a message hast been lost
1030 * - or the previous transaction has been be closed
1032 static struct tcaphash_context_t *
1033 tcaphash_begin_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1034 struct tcapsrt_info_t *p_tcapsrt_info)
1036 struct tcaphash_context_t *p_tcaphash_context=NULL;
1037 struct tcaphash_context_key_t tcaphash_context_key;
1038 struct tcaphash_begincall_t *p_tcaphash_begincall, *p_new_tcaphash_begincall=NULL;
1039 struct tcaphash_begin_info_key_t tcaphash_begin_key;
1041 proto_item *stat_item=NULL;
1042 proto_tree *stat_tree=NULL;
1044 /* prepare the key data */
1045 tcaphash_begin_key.tid = p_tcapsrt_info->src_tid;
1046 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1048 /* We have MTP3 PCs (so we can safely do this cast) */
1049 tcaphash_begin_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1050 tcaphash_begin_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1052 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1053 tcaphash_begin_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1054 tcaphash_begin_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1056 tcaphash_begin_key.hashKey=tcaphash_begin_calchash(&tcaphash_begin_key);
1058 /* look up the request */
1059 #ifdef DEBUG_TCAPSRT
1060 dbg(10,"\n Hbegin #%u ", pinfo->fd->num);
1061 dbg(11,"key %lx ",tcaphash_begin_key.hashKey);
1062 dbg(51,"PC %s %s ",ep_address_to_str(&pinfo->src), ep_address_to_str(&pinfo->dst));
1063 dbg(51,"Tid %lx ",tcaphash_begin_key.tid);
1066 p_tcaphash_begincall = (struct tcaphash_begincall_t *)
1067 g_hash_table_lookup(tcaphash_begin, &tcaphash_begin_key);
1069 if (p_tcaphash_begincall) {
1070 /* Walk through list of transaction with identical keys */
1072 /* Check if the request with this reqSeqNum has been seen, with the same Message Type */
1073 if (pinfo->fd->num == p_tcaphash_begincall->context->first_frame) {
1074 /* We have seen this request before -> do nothing */
1075 #ifdef DEBUG_TCAPSRT
1076 dbg(22,"Already seen ");
1078 p_tcaphash_context=p_tcaphash_begincall->context;
1081 /* If the last record for Tcap transaction with identifier has not been reached */
1082 if (!p_tcaphash_begincall->next_begincall) {
1083 /* check if we have to create a new record or not */
1084 /* if last request has been responded (response number is known)
1085 and this request appears after last response (has bigger frame number)
1086 and last request occured after the timeout for repetition,
1088 if last request hasn't been responded (so number unknown)
1089 and this request appears after last request (has bigger frame number)
1090 and this request occured after the timeout for message lost */
1091 if ( ( p_tcaphash_begincall->context->last_frame != 0
1092 && pinfo->fd->num > p_tcaphash_begincall->context->first_frame
1093 && (guint) pinfo->fd->abs_ts.secs > (guint)(p_tcaphash_begincall->context->begin_time.secs + gtcap_RepetitionTimeout)
1095 ( p_tcaphash_begincall->context->last_frame == 0
1096 && pinfo->fd->num > p_tcaphash_begincall->context->first_frame
1097 && (guint)pinfo->fd->abs_ts.secs > (guint)(p_tcaphash_begincall->context->begin_time.secs + gtcap_LostTimeout)
1101 /* we decide that we have a new request */
1102 /* Append new record to the list */
1103 #ifdef DEBUG_TCAPSRT
1104 dbg(12,"(timeout) Append key %lx ",tcaphash_begin_key.hashKey);
1105 dbg(12,"Frame %u rsp %u ",pinfo->fd->num,p_tcaphash_begincall->context->last_frame );
1107 tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
1108 p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
1110 p_new_tcaphash_begincall = append_tcaphash_begincall(p_tcaphash_begincall,
1113 #ifdef DEBUG_TCAPSRT
1114 dbg(12,"Update key %lx ",tcaphash_begin_key.hashKey);
1116 update_tcaphash_begincall(p_new_tcaphash_begincall, pinfo);
1117 p_tcaphash_begincall=p_new_tcaphash_begincall;
1118 } else { /* timeout or message lost */
1120 /* If the Tid is reused for a closed Transaction */
1121 /* Or if we received an TC_BEGIN for a Transaction marked as "closed" */
1122 /* (this is the case, for pre-arranged END, the transaction is marked as closed */
1123 /* by the upper layer, thank to a callback method close) */
1124 if ( p_tcaphash_begincall->context->closed) {
1125 #ifdef DEBUG_TCAPSRT
1126 dbg(12,"(closed) Append key %lu ",tcaphash_begin_key.hashKey);
1127 dbg(12,"Frame %u rsp %u ",pinfo->fd->num,p_tcaphash_begincall->context->last_frame );
1129 tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
1130 p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
1131 p_new_tcaphash_begincall = append_tcaphash_begincall(p_tcaphash_begincall,
1135 #ifdef DEBUG_TCAPSRT
1136 dbg(12,"Update key %lu ",tcaphash_begin_key.hashKey);
1138 update_tcaphash_begincall(p_new_tcaphash_begincall, pinfo);
1139 p_tcaphash_begincall=p_new_tcaphash_begincall;
1142 /* the TCAP session is not closed, so, either messages have been lost */
1143 /* or it's a duplicate request. Mark it as such. */
1144 #ifdef DEBUG_TCAPSRT
1145 dbg(21,"Display_duplicate %d ",p_tcaphash_begincall->context->first_frame);
1147 p_tcaphash_context=p_tcaphash_begincall->context;
1148 if (gtcap_DisplaySRT && tree) {
1149 stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
1150 PROTO_ITEM_SET_GENERATED(stat_item);
1151 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1152 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_Duplicate, tvb, 0, 0,
1153 p_tcaphash_context->first_frame,
1154 "Duplicate with session %u in frame %u",
1155 p_tcaphash_context->session_id,p_tcaphash_context->first_frame);
1156 PROTO_ITEM_SET_GENERATED(pi);
1158 return p_tcaphash_context;
1159 } /* Previous session closed */
1160 } /* test with Timeout or message Lost */
1162 } /* Next call is NULL */
1163 /* Repeat the tests for the next record with the same transaction identifier */
1164 p_tcaphash_begincall = p_tcaphash_begincall->next_begincall;
1165 } while (p_tcaphash_begincall != NULL );
1167 * End of analyze for the list be TC_BEGIN with same transaction ID
1169 } else { /* p_tcaphash_begincall has not been found */
1171 * Create a new TCAP context
1173 #ifdef DEBUG_TCAPSRT
1174 dbg(10,"New key %lx ",tcaphash_begin_key.hashKey);
1177 tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
1178 p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
1179 p_tcaphash_begincall = new_tcaphash_begin(&tcaphash_begin_key, p_tcaphash_context);
1181 #ifdef DEBUG_TCAPSRT
1182 dbg(11,"Update key %lx ",tcaphash_begin_key.hashKey);
1183 dbg(11,"Frame reqlink #%u ", pinfo->fd->num);
1185 update_tcaphash_begincall(p_tcaphash_begincall, pinfo);
1188 /* display tcap session, if available */
1189 if ( gtcap_DisplaySRT && tree &&
1190 p_tcaphash_context &&
1191 p_tcaphash_context->session_id) {
1192 stat_item = proto_tree_add_text(tree, tvb, 0, 0, "Stat");
1193 PROTO_ITEM_SET_GENERATED(stat_item);
1194 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1195 pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
1196 PROTO_ITEM_SET_GENERATED(pi);
1198 /* add link to response frame, if available */
1199 /* p_tcaphash_begincall->context->last_frame) */
1200 if( p_tcaphash_context->last_frame != 0 ){
1201 #ifdef DEBUG_TCAPSRT
1202 dbg(20,"Display_frameRsplink %d ",p_tcaphash_context->last_frame);
1204 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_BeginSession, tvb, 0, 0,
1205 p_tcaphash_context->last_frame,
1206 "End of session in frame %u",
1207 p_tcaphash_context->last_frame);
1208 PROTO_ITEM_SET_GENERATED(pi);
1211 return p_tcaphash_context;
1216 * Try to find a TCAP session according to the source and destination
1217 * Identifier given in the TC_CONT
1218 * If nothing is found, it is probably a session in opening state, so try to find
1219 * a tcap session registered with a TC_BEGIN "key", matching the destination Id of the TC_CONT
1220 * Then associate the TC_CONT "key" to the TCAP context, and create a TC_END "key"
1221 * and display the available info for the TCAP context
1223 static struct tcaphash_context_t *
1224 tcaphash_cont_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1225 struct tcapsrt_info_t *p_tcapsrt_info)
1227 struct tcaphash_context_t *p_tcaphash_context=NULL;
1228 struct tcaphash_contcall_t *p_tcaphash_contcall;
1229 struct tcaphash_cont_info_key_t tcaphash_cont_key;
1230 struct tcaphash_begin_info_key_t tcaphash_begin_key;
1231 struct tcaphash_begincall_t *p_tcaphash_begincall;
1232 struct tcaphash_end_info_key_t tcaphash_end_key;
1234 proto_item *stat_item=NULL;
1235 proto_tree *stat_tree=NULL;
1237 #ifdef DEBUG_TCAPSRT
1238 dbg(10,"\n Hcont #%u ", pinfo->fd->num);
1241 /* look only for matching request, if matching conversation is available. */
1242 tcaphash_cont_key.src_tid = p_tcapsrt_info->src_tid;
1243 tcaphash_cont_key.dst_tid = p_tcapsrt_info->dst_tid;
1244 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1246 /* We have MTP3 PCs (so we can safely do this cast) */
1247 tcaphash_cont_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1248 tcaphash_cont_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1250 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1251 tcaphash_cont_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1252 tcaphash_cont_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1254 tcaphash_cont_key.hashKey=tcaphash_cont_calchash(&tcaphash_cont_key);
1256 #ifdef DEBUG_TCAPSRT
1257 dbg(11,"Ckey %lx ", tcaphash_cont_key.hashKey);
1258 dbg(51,"PC %s %s ",ep_address_to_str(&pinfo->src), ep_address_to_str(&pinfo->dst));
1259 dbg(51,"Tid %lx %lx ",tcaphash_cont_key.src_tid, tcaphash_cont_key.dst_tid);
1261 p_tcaphash_contcall = find_tcaphash_cont(&tcaphash_cont_key, pinfo);
1262 if(p_tcaphash_contcall) {
1263 #ifdef DEBUG_TCAPSRT
1266 p_tcaphash_context=p_tcaphash_contcall->context;
1267 } else { /* cont not found */
1268 #ifdef DEBUG_TCAPSRT
1269 dbg(12,"CnotFound ");
1271 /* Find the TCAP transaction according to the TC_BEGIN */
1272 tcaphash_begin_key.tid = p_tcapsrt_info->dst_tid;
1273 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1275 /* We have MTP3 PCs (so we can safely do this cast) */
1276 tcaphash_begin_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1277 tcaphash_begin_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1279 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1280 tcaphash_begin_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1281 tcaphash_begin_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1283 tcaphash_begin_key.hashKey=tcaphash_begin_calchash(&tcaphash_begin_key);
1285 #ifdef DEBUG_TCAPSRT
1286 dbg(11,"Bkey %lx ", tcaphash_begin_key.hashKey);
1287 dbg(51,"PC %s %s ",ep_address_to_str(&pinfo->src), ep_address_to_str(&pinfo->dst));
1288 dbg(51,"Tid %lx ",tcaphash_begin_key.tid);
1290 p_tcaphash_begincall = find_tcaphash_begin(&tcaphash_begin_key, pinfo,FALSE);
1291 if(p_tcaphash_begincall &&
1292 !p_tcaphash_begincall->context->contcall ) {
1293 #ifdef DEBUG_TCAPSRT
1296 p_tcaphash_context=p_tcaphash_begincall->context;
1297 p_tcaphash_context->responded=TRUE;
1299 #ifdef DEBUG_TCAPSRT
1300 dbg(10,"New Ckey %lx ",tcaphash_cont_key.hashKey);
1301 dbg(11,"Frame reqlink #%u ", pinfo->fd->num);
1303 create_tcaphash_cont(&tcaphash_cont_key,
1304 p_tcaphash_begincall->context);
1306 tcaphash_end_key.tid = p_tcapsrt_info->src_tid;
1307 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1309 /* We have MTP3 PCs (so we can safely do this cast) */
1310 tcaphash_end_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1311 tcaphash_end_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1313 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1314 tcaphash_end_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1315 tcaphash_end_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1317 tcaphash_end_key.hashKey=tcaphash_end_calchash(&tcaphash_end_key);
1319 #ifdef DEBUG_TCAPSRT
1320 dbg(10,"New Ekey %lx ",tcaphash_end_key.hashKey);
1321 dbg(11,"Frame reqlink #%u ", pinfo->fd->num);
1323 create_tcaphash_end(&tcaphash_end_key,
1324 p_tcaphash_begincall->context);
1326 } else { /* Begin not found */
1327 #ifdef DEBUG_TCAPSRT
1328 dbg(12,"BnotFound ");
1332 /* display tcap session, if available */
1333 if (gtcap_DisplaySRT && tree &&
1334 p_tcaphash_context &&
1335 p_tcaphash_context->session_id) {
1336 stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
1337 PROTO_ITEM_SET_GENERATED(stat_item);
1338 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1339 pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
1340 PROTO_ITEM_SET_GENERATED(pi);
1343 return p_tcaphash_context;
1347 * Try to find a TCAP session according to the destination Identifier given in the TC_END/TC_ABORT
1348 * If nothing is found,
1349 * - either it is a session in opening state,
1350 * - or the session is closed/aborted by the remote, ( so we switch the src and dst tid )
1351 * so try to find a tcap session registered with a TC_BEGIN "key",
1352 * matching the destination Id of the TC_END
1353 * Then associate the TC_CONT "key" to the TCAP context
1354 * and display the available info for the TCAP context
1357 static struct tcaphash_context_t *
1358 tcaphash_end_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1359 struct tcapsrt_info_t *p_tcapsrt_info)
1361 struct tcaphash_context_t *p_tcaphash_context=NULL;
1363 struct tcaphash_end_info_key_t tcaphash_end_key;
1364 struct tcaphash_endcall_t *p_tcaphash_endcall=NULL;
1366 struct tcaphash_begin_info_key_t tcaphash_begin_key;
1367 struct tcaphash_begincall_t *p_tcaphash_begincall=NULL;
1370 proto_item *stat_item=NULL;
1371 proto_tree *stat_tree=NULL;
1373 #ifdef DEBUG_TCAPSRT
1374 dbg(10,"\n Hend #%u ", pinfo->fd->num);
1376 /* look only for matching request, if matching conversation is available. */
1377 tcaphash_end_key.tid = p_tcapsrt_info->dst_tid;
1378 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1380 /* We have MTP3 PCs (so we can safely do this cast) */
1381 tcaphash_end_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1382 tcaphash_end_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1384 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1385 tcaphash_end_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1386 tcaphash_end_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1388 tcaphash_end_key.hashKey=tcaphash_end_calchash(&tcaphash_end_key);
1390 #ifdef DEBUG_TCAPSRT
1391 dbg(11,"Ekey %lx ",tcaphash_end_key.hashKey);
1392 dbg(11,"PC %s %s ",ep_address_to_str(&pinfo->src), ep_address_to_str(&pinfo->dst));
1393 dbg(51,"Tid %lx ",tcaphash_end_key.tid);
1395 p_tcaphash_endcall = find_tcaphash_end(&tcaphash_end_key, pinfo,TRUE);
1397 if(!p_tcaphash_endcall) {
1398 #ifdef DEBUG_TCAPSRT
1399 dbg(12,"EnotFound ");
1401 tcaphash_begin_key.tid = p_tcapsrt_info->dst_tid;
1402 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1404 /* We have MTP3 PCs (so we can safely do this cast) */
1405 tcaphash_begin_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1406 tcaphash_begin_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1408 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1409 tcaphash_begin_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1410 tcaphash_begin_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1412 tcaphash_begin_key.hashKey=tcaphash_begin_calchash(&tcaphash_begin_key);
1414 #ifdef DEBUG_TCAPSRT
1415 dbg(11,"Bkey %lx ", tcaphash_begin_key.hashKey);
1416 dbg(51,"PC %s %s ",ep_address_to_str(&pinfo->src), ep_address_to_str(&pinfo->dst));
1417 dbg(51,"Tid %lx ",tcaphash_begin_key.tid);
1419 p_tcaphash_begincall = find_tcaphash_begin(&tcaphash_begin_key, pinfo,FALSE);
1420 if(!p_tcaphash_begincall) {
1421 #ifdef DEBUG_TCAPSRT
1422 dbg(12,"BnotFound ");
1426 if (p_tcaphash_endcall) {
1427 /* Use the TC_BEGIN Destination reference */
1428 p_tcaphash_context=p_tcaphash_endcall->context;
1429 } else if (p_tcaphash_begincall) {
1430 /* Use the TC_BEGIN Source reference */
1431 p_tcaphash_context=p_tcaphash_begincall->context;
1434 if (p_tcaphash_context) {
1436 #ifdef DEBUG_TCAPSRT
1437 dbg(12,"Found, req=%d ",p_tcaphash_context->first_frame);
1439 if (gtcap_DisplaySRT && tree) {
1440 stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
1441 PROTO_ITEM_SET_GENERATED(stat_item);
1442 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1444 pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
1445 PROTO_ITEM_SET_GENERATED(pi);
1448 #ifdef DEBUG_TCAPSRT
1449 dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
1451 /* Indicate the frame to which this is a reply. */
1452 if (gtcap_DisplaySRT && stat_tree) {
1453 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
1454 p_tcaphash_context->first_frame,
1455 "Begin of session in frame %u",
1456 p_tcaphash_context->first_frame);
1457 PROTO_ITEM_SET_GENERATED(pi);
1458 /* Calculate Service Response Time */
1459 nstime_delta(&delta, &pinfo->fd->abs_ts, &p_tcaphash_context->begin_time);
1461 /* display Service Response Time and make it filterable */
1462 pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
1463 PROTO_ITEM_SET_GENERATED(pi);
1465 /* Close the context and remove it (if needed) */
1466 tcapsrt_close(p_tcaphash_context,pinfo);
1468 } else {/* context present */
1469 #ifdef DEBUG_TCAPSRT
1470 dbg(12,"Context notFound ");
1473 return p_tcaphash_context;
1478 * Create the record identifiying the TCAP transaction
1479 * When the identifier for the transaction is reused, check
1480 * the following criteria before to append a new record:
1481 * - a timeout corresponding to a message retransmission is detected,
1482 * - a message hast been lost
1483 * - or the previous transaction has been be closed
1485 static struct tcaphash_context_t *
1486 tcaphash_ansi_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1487 struct tcapsrt_info_t *p_tcapsrt_info)
1489 struct tcaphash_context_t *p_tcaphash_context=NULL;
1490 struct tcaphash_context_key_t tcaphash_context_key;
1491 struct tcaphash_ansicall_t *p_tcaphash_ansicall, *p_new_tcaphash_ansicall;
1492 struct tcaphash_ansi_info_key_t tcaphash_ansi_key;
1495 gboolean isResponse=FALSE;
1496 proto_tree * stat_tree=NULL;
1497 proto_item * stat_item=NULL;
1499 /* prepare the key data */
1500 tcaphash_ansi_key.tid = p_tcapsrt_info->src_tid;
1501 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1503 /* We have MTP3 PCs (so we can safely do this cast) */
1504 tcaphash_ansi_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1505 tcaphash_ansi_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1507 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1508 tcaphash_ansi_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1509 tcaphash_ansi_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1511 tcaphash_ansi_key.hashKey=tcaphash_ansi_calchash(&tcaphash_ansi_key);
1513 /* look up the request */
1514 #ifdef DEBUG_TCAPSRT
1515 dbg(10,"\n Hansi #%u ", pinfo->fd->num);
1516 dbg(11,"key %lx ",tcaphash_ansi_key.hashKey);
1517 dbg(51,"PC %s %s ",ep_address_to_str(&pinfo->src), ep_address_to_str(&pinfo->dst));
1518 dbg(51,"Tid %lx ",tcaphash_ansi_key.tid);
1520 p_tcaphash_ansicall = (struct tcaphash_ansicall_t *)
1521 g_hash_table_lookup(tcaphash_ansi, &tcaphash_ansi_key);
1523 if (p_tcaphash_ansicall) {
1524 /* Walk through list of transaction with identical keys */
1526 /* Check if the request with this reqSeqNum has been seen */
1527 if (pinfo->fd->num == p_tcaphash_ansicall->context->first_frame) {
1528 /* We have seen this request before -> do nothing */
1529 #ifdef DEBUG_TCAPSRT
1530 dbg(22,"Request already seen ");
1533 p_tcaphash_context=p_tcaphash_ansicall->context;
1537 /* Check if the reponse with this reqSeqNum has been seen */
1538 if (pinfo->fd->num == p_tcaphash_ansicall->context->last_frame) {
1539 /* We have seen this response before -> do nothing */
1540 #ifdef DEBUG_TCAPSRT
1541 dbg(22,"Response already seen ");
1544 p_tcaphash_context=p_tcaphash_ansicall->context;
1548 /* Check for the first Request without Response
1549 received before this frame */
1550 if ( pinfo->fd->num > p_tcaphash_ansicall->context->first_frame &&
1551 p_tcaphash_ansicall->context->last_frame==0 ) {
1552 /* Take it, and update the context */
1554 #ifdef DEBUG_TCAPSRT
1555 dbg(12,"Update key %lx ",tcaphash_ansi_key.hashKey);
1557 p_tcaphash_ansicall->context->last_frame = pinfo->fd->num;
1558 p_tcaphash_ansicall->context->responded = TRUE;
1559 p_tcaphash_ansicall->context->closed = TRUE;
1560 p_tcaphash_context=p_tcaphash_ansicall->context;
1563 if (gtcap_DisplaySRT && tree) {
1564 stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
1565 PROTO_ITEM_SET_GENERATED(stat_item);
1566 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1568 pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
1569 PROTO_ITEM_SET_GENERATED(pi);
1571 #ifdef DEBUG_TCAPSRT
1572 dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
1574 /* Indicate the frame to which this is a reply. */
1575 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
1576 p_tcaphash_context->first_frame,
1577 "Begin of session in frame %u",
1578 p_tcaphash_context->first_frame);
1579 PROTO_ITEM_SET_GENERATED(pi);
1580 /* Calculate Service Response Time */
1581 nstime_delta(&delta, &pinfo->fd->abs_ts, &p_tcaphash_context->begin_time);
1583 /* display Service Response Time and make it filterable */
1584 pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
1585 PROTO_ITEM_SET_GENERATED(pi);
1588 } /* Lastframe=0, so take it */
1591 /* If the last record for Tcap transaction with identifier has been reached */
1592 if (!p_tcaphash_ansicall->next_ansicall) {
1593 /* check if we have to create a new record or not */
1594 /* if last request has been responded (response number in known)
1595 and this request appears after last response (has bigger frame number)
1596 and last request occured after the timeout for repetition,
1598 if last request hasn't been responded (so number unknown)
1599 and this request appears after last request (has bigger frame number)
1600 and this request occured after the timeout for message lost */
1601 if ( ( p_tcaphash_ansicall->context->last_frame != 0
1602 && pinfo->fd->num > p_tcaphash_ansicall->context->first_frame
1603 && (guint) pinfo->fd->abs_ts.secs > (guint)(p_tcaphash_ansicall->context->begin_time.secs + gtcap_RepetitionTimeout)
1605 ( p_tcaphash_ansicall->context->last_frame == 0
1606 && pinfo->fd->num > p_tcaphash_ansicall->context->first_frame
1607 && (guint)pinfo->fd->abs_ts.secs > (guint)(p_tcaphash_ansicall->context->begin_time.secs + gtcap_LostTimeout)
1611 /* we decide that we have a new request */
1612 /* Append new record to the list */
1613 #ifdef DEBUG_TCAPSRT
1614 dbg(12,"(timeout) Append key %lx ",tcaphash_ansi_key.hashKey);
1615 dbg(12,"Frame %u rsp %u ",pinfo->fd->num,p_tcaphash_ansicall->context->last_frame );
1617 tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
1618 p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
1619 p_new_tcaphash_ansicall = append_tcaphash_ansicall(p_tcaphash_ansicall,
1623 #ifdef DEBUG_TCAPSRT
1624 dbg(12,"Update key %lx ",tcaphash_ansi_key.hashKey);
1626 update_tcaphash_ansicall(p_new_tcaphash_ansicall, pinfo);
1627 p_tcaphash_ansicall=p_new_tcaphash_ansicall;
1630 /* If the Tid is reused for a closed Transaction */
1631 if ( p_tcaphash_ansicall->context->closed) {
1632 #ifdef DEBUG_TCAPSRT
1633 dbg(12,"(closed) Append key %lu ",tcaphash_ansi_key.hashKey);
1634 dbg(12,"Frame %u rsp %u ",pinfo->fd->num,p_tcaphash_ansicall->context->last_frame );
1636 tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
1637 p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
1638 p_new_tcaphash_ansicall = append_tcaphash_ansicall(p_tcaphash_ansicall,
1642 #ifdef DEBUG_TCAPSRT
1643 dbg(12,"Update key %lu ",tcaphash_ansi_key.hashKey);
1645 update_tcaphash_ansicall(p_new_tcaphash_ansicall, pinfo);
1646 p_tcaphash_ansicall=p_new_tcaphash_ansicall;
1649 /* the Tid is reused for an opened Transaction */
1650 /* so, this is the reply to the request of our context */
1651 p_tcaphash_context=p_tcaphash_ansicall->context;
1652 #ifdef DEBUG_TCAPSRT
1653 dbg(12,"Found, req=%d ",p_tcaphash_context->first_frame);
1656 if (gtcap_DisplaySRT && tree) {
1657 stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
1658 PROTO_ITEM_SET_GENERATED(stat_item);
1659 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1661 pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
1662 PROTO_ITEM_SET_GENERATED(pi);
1664 #ifdef DEBUG_TCAPSRT
1665 dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
1667 /* Indicate the frame to which this is a reply. */
1668 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
1669 p_tcaphash_context->first_frame,
1670 "Begin of session in frame %u",
1671 p_tcaphash_context->first_frame);
1672 PROTO_ITEM_SET_GENERATED(pi);
1673 /* Calculate Service Response Time */
1674 nstime_delta(&delta, &pinfo->fd->abs_ts, &p_tcaphash_context->begin_time);
1676 /* display Service Response Time and make it filterable */
1677 pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
1678 PROTO_ITEM_SET_GENERATED(pi);
1680 p_tcaphash_context=p_tcaphash_ansicall->context;
1681 } /* test with Timeout */
1684 } /* Next call is NULL */
1685 p_tcaphash_ansicall = p_tcaphash_ansicall->next_ansicall;
1686 } while (p_tcaphash_ansicall != NULL );
1690 } else { /* p_tcaphash_ansicall has not been found */
1691 #ifdef DEBUG_TCAPSRT
1692 dbg(10,"New key %lx ",tcaphash_ansi_key.hashKey);
1695 tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
1696 p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
1697 p_tcaphash_ansicall = new_tcaphash_ansi(&tcaphash_ansi_key, p_tcaphash_context);
1699 #ifdef DEBUG_TCAPSRT
1700 dbg(11,"Update key %lx ",tcaphash_ansi_key.hashKey);
1701 dbg(11,"Frame reqlink #%u ", pinfo->fd->num);
1703 update_tcaphash_ansicall(p_tcaphash_ansicall, pinfo);
1706 /* display tcap session, if available */
1707 if ( gtcap_DisplaySRT && tree &&
1708 p_tcaphash_context &&
1709 p_tcaphash_context->session_id) {
1710 stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
1711 PROTO_ITEM_SET_GENERATED(stat_item);
1712 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1713 pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
1714 PROTO_ITEM_SET_GENERATED(pi);
1718 /* add link to response frame, if available */
1719 if( gtcap_DisplaySRT && stat_tree &&
1720 p_tcaphash_ansicall->context->last_frame != 0){
1721 if (!isResponse) { /* Request */
1722 #ifdef DEBUG_TCAPSRT
1723 dbg(20,"Display_frameRsplink %d ",p_tcaphash_ansicall->context->last_frame);
1725 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_BeginSession, tvb, 0, 0,
1726 p_tcaphash_ansicall->context->last_frame,
1727 "End of session in frame %u",
1728 p_tcaphash_ansicall->context->last_frame);
1729 PROTO_ITEM_SET_GENERATED(pi);
1730 } else { /* Response */
1731 #ifdef DEBUG_TCAPSRT
1732 dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
1734 /* Indicate the frame to which this is a reply. */
1735 if (gtcap_DisplaySRT) {
1736 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
1737 p_tcaphash_context->first_frame,
1738 "Begin of session in frame %u",
1739 p_tcaphash_context->first_frame);
1740 PROTO_ITEM_SET_GENERATED(pi);
1741 /* Calculate Service Response Time */
1742 nstime_delta(&delta, &pinfo->fd->abs_ts, &p_tcaphash_context->begin_time);
1744 /* display Service Response Time and make it filterable */
1745 pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
1746 PROTO_ITEM_SET_GENERATED(pi);
1748 } /* Request or Response */
1750 return p_tcaphash_context;
1755 * Initialize the Message Info used by the main dissector
1756 * Data are linked to a TCAP transaction
1758 struct tcapsrt_info_t *
1759 tcapsrt_razinfo(void)
1761 struct tcapsrt_info_t *p_tcapsrt_info ;
1763 /* Global buffer for packet extraction */
1764 tcapsrt_global_current++;
1765 if(tcapsrt_global_current==MAX_TCAP_INSTANCE){
1766 tcapsrt_global_current=0;
1769 p_tcapsrt_info=&tcapsrt_global_info[tcapsrt_global_current];
1770 memset(p_tcapsrt_info,0,sizeof(struct tcapsrt_info_t));
1772 return p_tcapsrt_info;
1776 tcapsrt_close(struct tcaphash_context_t *p_tcaphash_context,
1779 #ifdef DEBUG_TCAPSRT
1780 dbg(60,"Force close ");
1782 if (p_tcaphash_context) {
1783 p_tcaphash_context->responded=TRUE;
1784 p_tcaphash_context->last_frame = pinfo->fd->num;
1785 p_tcaphash_context->end_time = pinfo->fd->abs_ts;
1786 p_tcaphash_context->closed=TRUE;
1788 /* If the endkey is present */
1789 if (p_tcaphash_context->endcall
1790 && !gtcap_PersistentSRT) {
1791 if (p_tcaphash_context->endcall->next_endcall) {
1792 if (p_tcaphash_context->endcall->previous_endcall ) {
1793 #ifdef DEBUG_TCAPSRT
1794 dbg(20,"deplace Ehash ");
1796 p_tcaphash_context->endcall->previous_endcall->next_endcall
1797 = p_tcaphash_context->endcall->next_endcall;
1798 p_tcaphash_context->endcall->next_endcall->previous_endcall
1799 = p_tcaphash_context->endcall->previous_endcall;
1800 g_hash_table_remove(tcaphash_end, p_tcaphash_context->endcall->endkey);
1802 g_free(p_tcaphash_context->endcall);
1805 /* cannot remove the father */
1806 #ifdef DEBUG_TCAPSRT
1807 dbg(20,"father Ehash ");
1809 } /* no previous link, so father */
1810 } else if (!gtcap_PersistentSRT) {
1811 #ifdef DEBUG_TCAPSRT
1812 dbg(20,"remove Ehash ");
1814 g_hash_table_remove(tcaphash_end, p_tcaphash_context->endcall->endkey);
1816 g_free(p_tcaphash_context->endcall->endkey);
1817 g_free(p_tcaphash_context->endcall);
1820 } /* endcall without chained string */
1824 /* If the contkey is present */
1825 if (p_tcaphash_context->contcall
1826 && !gtcap_PersistentSRT) {
1827 if (p_tcaphash_context->contcall->next_contcall) {
1828 if (p_tcaphash_context->contcall->previous_contcall ) {
1829 #ifdef DEBUG_TCAPSRT
1830 dbg(20,"deplace Chash ");
1832 p_tcaphash_context->contcall->previous_contcall->next_contcall
1833 = p_tcaphash_context->contcall->next_contcall;
1834 p_tcaphash_context->contcall->next_contcall->previous_contcall
1835 = p_tcaphash_context->contcall->previous_contcall;
1836 g_hash_table_remove(tcaphash_cont, p_tcaphash_context->contcall->contkey);
1838 g_free(p_tcaphash_context->contcall);
1841 /* cannot remove the father */
1842 #ifdef DEBUG_TCAPSRT
1843 dbg(20,"father Chash ");
1845 } /* no previous link, so father */
1846 } else if (!gtcap_PersistentSRT) {
1847 #ifdef DEBUG_TCAPSRT
1848 dbg(20,"remove Chash ");
1850 g_hash_table_remove(tcaphash_cont, p_tcaphash_context->contcall->contkey);
1852 g_free(p_tcaphash_context->contcall->contkey);
1853 g_free(p_tcaphash_context->contcall);
1855 } /* contcall without chained string */
1859 /* If the beginkey is present */
1860 if (p_tcaphash_context->begincall
1861 && !gtcap_PersistentSRT) {
1862 if (p_tcaphash_context->begincall->next_begincall) {
1863 if (p_tcaphash_context->begincall->previous_begincall ) {
1864 #ifdef DEBUG_TCAPSRT
1865 dbg(20,"deplace Bhash ");
1867 p_tcaphash_context->begincall->previous_begincall->next_begincall
1868 = p_tcaphash_context->begincall->next_begincall;
1869 p_tcaphash_context->begincall->next_begincall->previous_begincall
1870 = p_tcaphash_context->begincall->previous_begincall;
1871 g_hash_table_remove(tcaphash_begin, p_tcaphash_context->begincall->beginkey);
1873 g_free(p_tcaphash_context->begincall);
1876 /* cannot remove the father */
1877 #ifdef DEBUG_TCAPSRT
1878 dbg(20,"father Bhash ");
1881 } else if (!gtcap_PersistentSRT) {
1882 #ifdef DEBUG_TCAPSRT
1883 dbg(20,"remove Bhash ");
1885 g_hash_table_remove(tcaphash_begin, p_tcaphash_context->begincall->beginkey);
1887 g_free(p_tcaphash_context->begincall->beginkey);
1888 g_free(p_tcaphash_context->begincall);
1890 } /* begincall without chained string */
1891 } /* no begincall */
1893 /* If the ansikey is present */
1894 if (p_tcaphash_context->ansicall
1895 && !gtcap_PersistentSRT) {
1896 if (p_tcaphash_context->ansicall->next_ansicall) {
1897 if (p_tcaphash_context->ansicall->previous_ansicall ) {
1898 #ifdef DEBUG_TCAPSRT
1899 dbg(20,"deplace Ahash ");
1901 p_tcaphash_context->ansicall->previous_ansicall->next_ansicall
1902 = p_tcaphash_context->ansicall->next_ansicall;
1903 p_tcaphash_context->ansicall->next_ansicall->previous_ansicall
1904 = p_tcaphash_context->ansicall->previous_ansicall;
1905 g_hash_table_remove(tcaphash_ansi, p_tcaphash_context->ansicall->ansikey);
1907 g_free(p_tcaphash_context->ansicall);
1910 /* cannot remove the father */
1911 #ifdef DEBUG_TCAPSRT
1912 dbg(20,"father Ahash ");
1915 } else if (!gtcap_PersistentSRT) {
1916 #ifdef DEBUG_TCAPSRT
1917 dbg(20,"remove Ahash ");
1919 g_hash_table_remove(tcaphash_ansi, p_tcaphash_context->ansicall->ansikey);
1921 g_free(p_tcaphash_context->ansicall->ansikey);
1922 g_free(p_tcaphash_context->ansicall);
1924 } /* ansicall without chained string */
1927 if (!gtcap_PersistentSRT) {
1928 #ifdef DEBUG_TCAPSRT
1929 dbg(20,"remove context ");
1931 g_hash_table_remove(tcaphash_context, p_tcaphash_context->key);
1933 g_free(p_tcaphash_context->key);
1934 g_free(p_tcaphash_context);
1937 } else { /* no context */
1938 #ifdef DEBUG_TCAPSRT
1939 dbg(20,"No context to remove ");