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-table for SRT */
894 if (tcaphash_context != NULL) {
896 dbg(16,"Destroy hash_context \n");
898 g_hash_table_destroy(tcaphash_context);
901 if (tcaphash_begin != NULL) {
903 dbg(16,"Destroy hash_begin \n");
905 g_hash_table_destroy(tcaphash_begin);
908 if (tcaphash_cont != NULL) {
910 dbg(16,"Destroy hash_cont \n");
912 g_hash_table_destroy(tcaphash_cont);
915 if (tcaphash_end != NULL) {
917 dbg(16,"Destroy hash_end \n");
919 g_hash_table_destroy(tcaphash_end);
922 if (tcaphash_ansi != NULL) {
924 dbg(16,"Destroy hash_ansi \n");
926 g_hash_table_destroy(tcaphash_ansi);
930 dbg(16,"Create hash \n");
932 /* create new hash-tables 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) {
976 dbg(1,"\nTC_BEGIN ");
978 tcap_context=tcaphash_begin_matching(tvb, pinfo, tree, p_tcapsrt_info);
985 tcap_context=tcaphash_cont_matching(tvb, pinfo, tree, p_tcapsrt_info);
990 dbg(1,"\nTC_ABORT ");
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
1005 dbg(1,"\nTC_ANSI ");
1007 tcap_context=tcaphash_ansi_matching(tvb, pinfo, tree, p_tcapsrt_info);
1011 #ifdef DEBUG_TCAPSRT
1012 dbg(1,"\nUnknown %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 \n",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 } else { /* timeout or message lost */
1119 /* If the Tid is reused for a closed Transaction */
1120 /* Or if we received an TC_BEGIN for a Transaction marked as "closed" */
1121 /* (this is the case, for pre-arranged END, the transaction is marked as closed */
1122 /* by the upper layer, thank to a callback method close) */
1123 if ( p_tcaphash_begincall->context->closed) {
1124 #ifdef DEBUG_TCAPSRT
1125 dbg(12,"(closed) Append key %lu ",tcaphash_begin_key.hashKey);
1126 dbg(12,"Frame %u rsp %u ",pinfo->fd->num,p_tcaphash_begincall->context->last_frame );
1128 tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
1129 p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
1130 p_new_tcaphash_begincall = append_tcaphash_begincall(p_tcaphash_begincall,
1134 #ifdef DEBUG_TCAPSRT
1135 dbg(12,"Update key %lu ",tcaphash_begin_key.hashKey);
1137 update_tcaphash_begincall(p_new_tcaphash_begincall, pinfo);
1140 /* the TCAP session is not closed, so, either messages have been lost */
1141 /* or it's a duplicate request. Mark it as such. */
1142 #ifdef DEBUG_TCAPSRT
1143 dbg(21,"Display_duplicate %d ",p_tcaphash_begincall->context->first_frame);
1145 p_tcaphash_context=p_tcaphash_begincall->context;
1146 if (gtcap_DisplaySRT && tree) {
1147 stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
1148 PROTO_ITEM_SET_GENERATED(stat_item);
1149 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1150 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_Duplicate, tvb, 0, 0,
1151 p_tcaphash_context->first_frame,
1152 "Duplicate with session %u in frame %u",
1153 p_tcaphash_context->session_id,p_tcaphash_context->first_frame);
1154 PROTO_ITEM_SET_GENERATED(pi);
1156 return p_tcaphash_context;
1157 } /* Previous session closed */
1158 } /* test with Timeout or message Lost */
1160 } /* Next call is NULL */
1161 /* Repeat the tests for the next record with the same transaction identifier */
1162 p_tcaphash_begincall = p_tcaphash_begincall->next_begincall;
1163 } while (p_tcaphash_begincall != NULL );
1165 * End of analyze for the list be TC_BEGIN with same transaction ID
1167 } else { /* p_tcaphash_begincall has not been found */
1169 * Create a new TCAP context
1171 #ifdef DEBUG_TCAPSRT
1172 dbg(10,"New key %lx ",tcaphash_begin_key.hashKey);
1175 tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
1176 p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
1177 p_tcaphash_begincall = new_tcaphash_begin(&tcaphash_begin_key, p_tcaphash_context);
1179 #ifdef DEBUG_TCAPSRT
1180 dbg(11,"Update key %lx ",tcaphash_begin_key.hashKey);
1181 dbg(11,"Frame reqlink #%u ", pinfo->fd->num);
1183 update_tcaphash_begincall(p_tcaphash_begincall, pinfo);
1186 /* display tcap session, if available */
1187 if ( gtcap_DisplaySRT && tree &&
1188 p_tcaphash_context &&
1189 p_tcaphash_context->session_id) {
1190 stat_item = proto_tree_add_text(tree, tvb, 0, 0, "Stat");
1191 PROTO_ITEM_SET_GENERATED(stat_item);
1192 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1193 pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
1194 PROTO_ITEM_SET_GENERATED(pi);
1196 /* add link to response frame, if available */
1197 /* p_tcaphash_begincall->context->last_frame) */
1198 if( p_tcaphash_context->last_frame != 0 ){
1199 #ifdef DEBUG_TCAPSRT
1200 dbg(20,"Display_frameRsplink %d ",p_tcaphash_context->last_frame);
1202 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_BeginSession, tvb, 0, 0,
1203 p_tcaphash_context->last_frame,
1204 "End of session in frame %u",
1205 p_tcaphash_context->last_frame);
1206 PROTO_ITEM_SET_GENERATED(pi);
1209 return p_tcaphash_context;
1214 * Try to find a TCAP session according to the source and destination
1215 * Identifier given in the TC_CONT
1216 * If nothing is found, it is probably a session in opening state, so try to find
1217 * a tcap session registered with a TC_BEGIN "key", matching the destination Id of the TC_CONT
1218 * Then associate the TC_CONT "key" to the TCAP context, and create a TC_END "key"
1219 * and display the available info for the TCAP context
1221 static struct tcaphash_context_t *
1222 tcaphash_cont_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1223 struct tcapsrt_info_t *p_tcapsrt_info)
1225 struct tcaphash_context_t *p_tcaphash_context=NULL;
1226 struct tcaphash_contcall_t *p_tcaphash_contcall;
1227 struct tcaphash_cont_info_key_t tcaphash_cont_key;
1228 struct tcaphash_begin_info_key_t tcaphash_begin_key;
1229 struct tcaphash_begincall_t *p_tcaphash_begincall;
1230 struct tcaphash_end_info_key_t tcaphash_end_key;
1232 proto_item *stat_item=NULL;
1233 proto_tree *stat_tree=NULL;
1235 #ifdef DEBUG_TCAPSRT
1236 dbg(10,"\n Hcont #%u ", pinfo->fd->num);
1239 /* look only for matching request, if matching conversation is available. */
1240 tcaphash_cont_key.src_tid = p_tcapsrt_info->src_tid;
1241 tcaphash_cont_key.dst_tid = p_tcapsrt_info->dst_tid;
1242 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1244 /* We have MTP3 PCs (so we can safely do this cast) */
1245 tcaphash_cont_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1246 tcaphash_cont_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1248 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1249 tcaphash_cont_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1250 tcaphash_cont_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1252 tcaphash_cont_key.hashKey=tcaphash_cont_calchash(&tcaphash_cont_key);
1254 #ifdef DEBUG_TCAPSRT
1255 dbg(11,"Ckey %lx ", tcaphash_cont_key.hashKey);
1256 dbg(51,"PC %s %s ",ep_address_to_str(&pinfo->src), ep_address_to_str(&pinfo->dst));
1257 dbg(51,"Tid %lx %lx \n",tcaphash_cont_key.src_tid, tcaphash_cont_key.dst_tid);
1259 p_tcaphash_contcall = find_tcaphash_cont(&tcaphash_cont_key, pinfo);
1260 if(p_tcaphash_contcall) {
1261 #ifdef DEBUG_TCAPSRT
1264 p_tcaphash_context=p_tcaphash_contcall->context;
1265 } else { /* cont not found */
1266 #ifdef DEBUG_TCAPSRT
1267 dbg(12,"CnotFound ");
1269 /* Find the TCAP transaction according to the TC_BEGIN */
1270 tcaphash_begin_key.tid = p_tcapsrt_info->dst_tid;
1271 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1273 /* We have MTP3 PCs (so we can safely do this cast) */
1274 tcaphash_begin_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1275 tcaphash_begin_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1277 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1278 tcaphash_begin_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1279 tcaphash_begin_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1281 tcaphash_begin_key.hashKey=tcaphash_begin_calchash(&tcaphash_begin_key);
1283 #ifdef DEBUG_TCAPSRT
1284 dbg(11,"Bkey %lx ", tcaphash_begin_key.hashKey);
1285 dbg(51,"PC %s %s ",ep_address_to_str(&pinfo->src), ep_address_to_str(&pinfo->dst));
1286 dbg(51,"Tid %lx \n",tcaphash_begin_key.tid);
1288 p_tcaphash_begincall = find_tcaphash_begin(&tcaphash_begin_key, pinfo, FALSE);
1289 if(!p_tcaphash_begincall){
1290 /* Do we have a continue from the same source? */
1291 tcaphash_begin_key.tid = p_tcapsrt_info->src_tid;
1292 tcaphash_begin_key.hashKey=tcaphash_begin_calchash(&tcaphash_begin_key);
1293 p_tcaphash_begincall = find_tcaphash_begin(&tcaphash_begin_key, pinfo,FALSE);
1295 if(p_tcaphash_begincall &&
1296 !p_tcaphash_begincall->context->contcall ) {
1297 #ifdef DEBUG_TCAPSRT
1298 dbg(12,"BFound \n");
1300 p_tcaphash_context=p_tcaphash_begincall->context;
1301 p_tcaphash_context->responded=TRUE;
1303 #ifdef DEBUG_TCAPSRT
1304 dbg(10,"New Ckey %lx ",tcaphash_cont_key.hashKey);
1305 dbg(11,"Frame reqlink #%u \n", pinfo->fd->num);
1307 create_tcaphash_cont(&tcaphash_cont_key,
1308 p_tcaphash_begincall->context);
1310 tcaphash_end_key.tid = p_tcapsrt_info->src_tid;
1311 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1313 /* We have MTP3 PCs (so we can safely do this cast) */
1314 tcaphash_end_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1315 tcaphash_end_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1317 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1318 tcaphash_end_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1319 tcaphash_end_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1321 tcaphash_end_key.hashKey=tcaphash_end_calchash(&tcaphash_end_key);
1323 #ifdef DEBUG_TCAPSRT
1324 dbg(10,"New Ekey %lx ",tcaphash_end_key.hashKey);
1325 dbg(11,"Frame reqlink #%u ", pinfo->fd->num);
1327 create_tcaphash_end(&tcaphash_end_key,
1328 p_tcaphash_begincall->context);
1330 } else { /* Begin not found */
1331 #ifdef DEBUG_TCAPSRT
1332 dbg(12,"BnotFound ");
1336 /* display tcap session, if available */
1337 if (gtcap_DisplaySRT && tree &&
1338 p_tcaphash_context &&
1339 p_tcaphash_context->session_id) {
1340 stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
1341 PROTO_ITEM_SET_GENERATED(stat_item);
1342 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1343 pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
1344 PROTO_ITEM_SET_GENERATED(pi);
1347 return p_tcaphash_context;
1351 * Try to find a TCAP session according to the destination Identifier given in the TC_END/TC_ABORT
1352 * If nothing is found,
1353 * - either it is a session in opening state,
1354 * - or the session is closed/aborted by the remote, ( so we switch the src and dst tid )
1355 * so try to find a tcap session registered with a TC_BEGIN "key",
1356 * matching the destination Id of the TC_END
1357 * Then associate the TC_CONT "key" to the TCAP context
1358 * and display the available info for the TCAP context
1361 static struct tcaphash_context_t *
1362 tcaphash_end_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1363 struct tcapsrt_info_t *p_tcapsrt_info)
1365 struct tcaphash_context_t *p_tcaphash_context=NULL;
1367 struct tcaphash_end_info_key_t tcaphash_end_key;
1368 struct tcaphash_endcall_t *p_tcaphash_endcall=NULL;
1370 struct tcaphash_begin_info_key_t tcaphash_begin_key;
1371 struct tcaphash_begincall_t *p_tcaphash_begincall=NULL;
1374 proto_item *stat_item=NULL;
1375 proto_tree *stat_tree=NULL;
1377 #ifdef DEBUG_TCAPSRT
1378 dbg(10,"\n Hend #%u ", pinfo->fd->num);
1380 /* look only for matching request, if matching conversation is available. */
1381 tcaphash_end_key.tid = p_tcapsrt_info->dst_tid;
1382 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1384 /* We have MTP3 PCs (so we can safely do this cast) */
1385 tcaphash_end_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1386 tcaphash_end_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1388 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1389 tcaphash_end_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1390 tcaphash_end_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1392 tcaphash_end_key.hashKey=tcaphash_end_calchash(&tcaphash_end_key);
1394 #ifdef DEBUG_TCAPSRT
1395 dbg(11,"Ekey %lx ",tcaphash_end_key.hashKey);
1396 dbg(11,"PC %s %s ",ep_address_to_str(&pinfo->src), ep_address_to_str(&pinfo->dst));
1397 dbg(51,"Tid %lx ",tcaphash_end_key.tid);
1399 p_tcaphash_endcall = find_tcaphash_end(&tcaphash_end_key, pinfo,TRUE);
1401 if(!p_tcaphash_endcall) {
1402 #ifdef DEBUG_TCAPSRT
1403 dbg(12,"EnotFound ");
1405 tcaphash_begin_key.tid = p_tcapsrt_info->dst_tid;
1406 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1408 /* We have MTP3 PCs (so we can safely do this cast) */
1409 tcaphash_begin_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1410 tcaphash_begin_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1412 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1413 tcaphash_begin_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1414 tcaphash_begin_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1416 tcaphash_begin_key.hashKey=tcaphash_begin_calchash(&tcaphash_begin_key);
1418 #ifdef DEBUG_TCAPSRT
1419 dbg(11,"Bkey %lx ", tcaphash_begin_key.hashKey);
1420 dbg(51,"PC %s %s ",ep_address_to_str(&pinfo->src), ep_address_to_str(&pinfo->dst));
1421 dbg(51,"Tid %lx ",tcaphash_begin_key.tid);
1423 p_tcaphash_begincall = find_tcaphash_begin(&tcaphash_begin_key, pinfo,FALSE);
1424 if(!p_tcaphash_begincall) {
1425 #ifdef DEBUG_TCAPSRT
1426 dbg(12,"BnotFound ");
1430 if (p_tcaphash_endcall) {
1431 /* Use the TC_BEGIN Destination reference */
1432 p_tcaphash_context=p_tcaphash_endcall->context;
1433 } else if (p_tcaphash_begincall) {
1434 /* Use the TC_BEGIN Source reference */
1435 p_tcaphash_context=p_tcaphash_begincall->context;
1438 if (p_tcaphash_context) {
1440 #ifdef DEBUG_TCAPSRT
1441 dbg(12,"Found, req=%d ",p_tcaphash_context->first_frame);
1443 if (gtcap_DisplaySRT && tree) {
1444 stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
1445 PROTO_ITEM_SET_GENERATED(stat_item);
1446 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1448 pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
1449 PROTO_ITEM_SET_GENERATED(pi);
1452 #ifdef DEBUG_TCAPSRT
1453 dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
1455 /* Indicate the frame to which this is a reply. */
1456 if (gtcap_DisplaySRT && stat_tree) {
1457 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
1458 p_tcaphash_context->first_frame,
1459 "Begin of session in frame %u",
1460 p_tcaphash_context->first_frame);
1461 PROTO_ITEM_SET_GENERATED(pi);
1462 /* Calculate Service Response Time */
1463 nstime_delta(&delta, &pinfo->fd->abs_ts, &p_tcaphash_context->begin_time);
1465 /* display Service Response Time and make it filterable */
1466 pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
1467 PROTO_ITEM_SET_GENERATED(pi);
1469 /* Close the context and remove it (if needed) */
1470 tcapsrt_close(p_tcaphash_context,pinfo);
1472 } else {/* context present */
1473 #ifdef DEBUG_TCAPSRT
1474 dbg(12,"Context notFound ");
1477 return p_tcaphash_context;
1482 * Create the record identifiying the TCAP transaction
1483 * When the identifier for the transaction is reused, check
1484 * the following criteria before to append a new record:
1485 * - a timeout corresponding to a message retransmission is detected,
1486 * - a message hast been lost
1487 * - or the previous transaction has been be closed
1489 static struct tcaphash_context_t *
1490 tcaphash_ansi_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1491 struct tcapsrt_info_t *p_tcapsrt_info)
1493 struct tcaphash_context_t *p_tcaphash_context=NULL;
1494 struct tcaphash_context_key_t tcaphash_context_key;
1495 struct tcaphash_ansicall_t *p_tcaphash_ansicall, *p_new_tcaphash_ansicall;
1496 struct tcaphash_ansi_info_key_t tcaphash_ansi_key;
1499 gboolean isResponse=FALSE;
1500 proto_tree * stat_tree=NULL;
1501 proto_item * stat_item=NULL;
1503 /* prepare the key data */
1504 tcaphash_ansi_key.tid = p_tcapsrt_info->src_tid;
1505 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1507 /* We have MTP3 PCs (so we can safely do this cast) */
1508 tcaphash_ansi_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1509 tcaphash_ansi_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1511 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1512 tcaphash_ansi_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1513 tcaphash_ansi_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1515 tcaphash_ansi_key.hashKey=tcaphash_ansi_calchash(&tcaphash_ansi_key);
1517 /* look up the request */
1518 #ifdef DEBUG_TCAPSRT
1519 dbg(10,"\n Hansi #%u ", pinfo->fd->num);
1520 dbg(11,"key %lx ",tcaphash_ansi_key.hashKey);
1521 dbg(51,"PC %s %s ",ep_address_to_str(&pinfo->src), ep_address_to_str(&pinfo->dst));
1522 dbg(51,"Tid %lx ",tcaphash_ansi_key.tid);
1524 p_tcaphash_ansicall = (struct tcaphash_ansicall_t *)
1525 g_hash_table_lookup(tcaphash_ansi, &tcaphash_ansi_key);
1527 if (p_tcaphash_ansicall) {
1528 /* Walk through list of transaction with identical keys */
1530 /* Check if the request with this reqSeqNum has been seen */
1531 if (pinfo->fd->num == p_tcaphash_ansicall->context->first_frame) {
1532 /* We have seen this request before -> do nothing */
1533 #ifdef DEBUG_TCAPSRT
1534 dbg(22,"Request already seen ");
1537 p_tcaphash_context=p_tcaphash_ansicall->context;
1541 /* Check if the reponse with this reqSeqNum has been seen */
1542 if (pinfo->fd->num == p_tcaphash_ansicall->context->last_frame) {
1543 /* We have seen this response before -> do nothing */
1544 #ifdef DEBUG_TCAPSRT
1545 dbg(22,"Response already seen ");
1548 p_tcaphash_context=p_tcaphash_ansicall->context;
1552 /* Check for the first Request without Response
1553 received before this frame */
1554 if ( pinfo->fd->num > p_tcaphash_ansicall->context->first_frame &&
1555 p_tcaphash_ansicall->context->last_frame==0 ) {
1556 /* Take it, and update the context */
1558 #ifdef DEBUG_TCAPSRT
1559 dbg(12,"Update key %lx ",tcaphash_ansi_key.hashKey);
1561 p_tcaphash_ansicall->context->last_frame = pinfo->fd->num;
1562 p_tcaphash_ansicall->context->responded = TRUE;
1563 p_tcaphash_ansicall->context->closed = TRUE;
1564 p_tcaphash_context=p_tcaphash_ansicall->context;
1567 if (gtcap_DisplaySRT && tree) {
1568 stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
1569 PROTO_ITEM_SET_GENERATED(stat_item);
1570 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1572 pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
1573 PROTO_ITEM_SET_GENERATED(pi);
1575 #ifdef DEBUG_TCAPSRT
1576 dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
1578 /* Indicate the frame to which this is a reply. */
1579 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
1580 p_tcaphash_context->first_frame,
1581 "Begin of session in frame %u",
1582 p_tcaphash_context->first_frame);
1583 PROTO_ITEM_SET_GENERATED(pi);
1584 /* Calculate Service Response Time */
1585 nstime_delta(&delta, &pinfo->fd->abs_ts, &p_tcaphash_context->begin_time);
1587 /* display Service Response Time and make it filterable */
1588 pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
1589 PROTO_ITEM_SET_GENERATED(pi);
1592 } /* Lastframe=0, so take it */
1595 /* If the last record for Tcap transaction with identifier has been reached */
1596 if (!p_tcaphash_ansicall->next_ansicall) {
1597 /* check if we have to create a new record or not */
1598 /* if last request has been responded (response number in known)
1599 and this request appears after last response (has bigger frame number)
1600 and last request occured after the timeout for repetition,
1602 if last request hasn't been responded (so number unknown)
1603 and this request appears after last request (has bigger frame number)
1604 and this request occured after the timeout for message lost */
1605 if ( ( 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_RepetitionTimeout)
1609 ( p_tcaphash_ansicall->context->last_frame == 0
1610 && pinfo->fd->num > p_tcaphash_ansicall->context->first_frame
1611 && (guint)pinfo->fd->abs_ts.secs > (guint)(p_tcaphash_ansicall->context->begin_time.secs + gtcap_LostTimeout)
1615 /* we decide that we have a new request */
1616 /* Append new record to the list */
1617 #ifdef DEBUG_TCAPSRT
1618 dbg(12,"(timeout) Append key %lx ",tcaphash_ansi_key.hashKey);
1619 dbg(12,"Frame %u rsp %u ",pinfo->fd->num,p_tcaphash_ansicall->context->last_frame );
1621 tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
1622 p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
1623 p_new_tcaphash_ansicall = append_tcaphash_ansicall(p_tcaphash_ansicall,
1627 #ifdef DEBUG_TCAPSRT
1628 dbg(12,"Update key %lx ",tcaphash_ansi_key.hashKey);
1630 update_tcaphash_ansicall(p_new_tcaphash_ansicall, pinfo);
1631 p_tcaphash_ansicall=p_new_tcaphash_ansicall;
1634 /* If the Tid is reused for a closed Transaction */
1635 if ( p_tcaphash_ansicall->context->closed) {
1636 #ifdef DEBUG_TCAPSRT
1637 dbg(12,"(closed) Append key %lu ",tcaphash_ansi_key.hashKey);
1638 dbg(12,"Frame %u rsp %u ",pinfo->fd->num,p_tcaphash_ansicall->context->last_frame );
1640 tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
1641 p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
1642 p_new_tcaphash_ansicall = append_tcaphash_ansicall(p_tcaphash_ansicall,
1646 #ifdef DEBUG_TCAPSRT
1647 dbg(12,"Update key %lu ",tcaphash_ansi_key.hashKey);
1649 update_tcaphash_ansicall(p_new_tcaphash_ansicall, pinfo);
1650 p_tcaphash_ansicall=p_new_tcaphash_ansicall;
1653 /* the Tid is reused for an opened Transaction */
1654 /* so, this is the reply to the request of our context */
1655 p_tcaphash_context=p_tcaphash_ansicall->context;
1656 #ifdef DEBUG_TCAPSRT
1657 dbg(12,"Found, req=%d ",p_tcaphash_context->first_frame);
1660 if (gtcap_DisplaySRT && tree) {
1661 stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
1662 PROTO_ITEM_SET_GENERATED(stat_item);
1663 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1665 pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
1666 PROTO_ITEM_SET_GENERATED(pi);
1668 #ifdef DEBUG_TCAPSRT
1669 dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
1671 /* Indicate the frame to which this is a reply. */
1672 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
1673 p_tcaphash_context->first_frame,
1674 "Begin of session in frame %u",
1675 p_tcaphash_context->first_frame);
1676 PROTO_ITEM_SET_GENERATED(pi);
1677 /* Calculate Service Response Time */
1678 nstime_delta(&delta, &pinfo->fd->abs_ts, &p_tcaphash_context->begin_time);
1680 /* display Service Response Time and make it filterable */
1681 pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
1682 PROTO_ITEM_SET_GENERATED(pi);
1684 p_tcaphash_context=p_tcaphash_ansicall->context;
1685 } /* test with Timeout */
1688 } /* Next call is NULL */
1689 p_tcaphash_ansicall = p_tcaphash_ansicall->next_ansicall;
1690 } while (p_tcaphash_ansicall != NULL );
1694 } else { /* p_tcaphash_ansicall has not been found */
1695 #ifdef DEBUG_TCAPSRT
1696 dbg(10,"New key %lx ",tcaphash_ansi_key.hashKey);
1699 tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
1700 p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
1701 p_tcaphash_ansicall = new_tcaphash_ansi(&tcaphash_ansi_key, p_tcaphash_context);
1703 #ifdef DEBUG_TCAPSRT
1704 dbg(11,"Update key %lx ",tcaphash_ansi_key.hashKey);
1705 dbg(11,"Frame reqlink #%u ", pinfo->fd->num);
1707 update_tcaphash_ansicall(p_tcaphash_ansicall, pinfo);
1710 /* display tcap session, if available */
1711 if ( gtcap_DisplaySRT && tree &&
1712 p_tcaphash_context &&
1713 p_tcaphash_context->session_id) {
1714 stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
1715 PROTO_ITEM_SET_GENERATED(stat_item);
1716 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1717 pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
1718 PROTO_ITEM_SET_GENERATED(pi);
1722 /* add link to response frame, if available */
1723 if( gtcap_DisplaySRT && stat_tree &&
1724 p_tcaphash_ansicall->context->last_frame != 0){
1725 if (!isResponse) { /* Request */
1726 #ifdef DEBUG_TCAPSRT
1727 dbg(20,"Display_frameRsplink %d ",p_tcaphash_ansicall->context->last_frame);
1729 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_BeginSession, tvb, 0, 0,
1730 p_tcaphash_ansicall->context->last_frame,
1731 "End of session in frame %u",
1732 p_tcaphash_ansicall->context->last_frame);
1733 PROTO_ITEM_SET_GENERATED(pi);
1734 } else { /* Response */
1735 #ifdef DEBUG_TCAPSRT
1736 dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
1738 /* Indicate the frame to which this is a reply. */
1739 if (gtcap_DisplaySRT) {
1740 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
1741 p_tcaphash_context->first_frame,
1742 "Begin of session in frame %u",
1743 p_tcaphash_context->first_frame);
1744 PROTO_ITEM_SET_GENERATED(pi);
1745 /* Calculate Service Response Time */
1746 nstime_delta(&delta, &pinfo->fd->abs_ts, &p_tcaphash_context->begin_time);
1748 /* display Service Response Time and make it filterable */
1749 pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
1750 PROTO_ITEM_SET_GENERATED(pi);
1752 } /* Request or Response */
1754 return p_tcaphash_context;
1759 * Initialize the Message Info used by the main dissector
1760 * Data are linked to a TCAP transaction
1762 struct tcapsrt_info_t *
1763 tcapsrt_razinfo(void)
1765 struct tcapsrt_info_t *p_tcapsrt_info ;
1767 /* Global buffer for packet extraction */
1768 tcapsrt_global_current++;
1769 if(tcapsrt_global_current==MAX_TCAP_INSTANCE){
1770 tcapsrt_global_current=0;
1773 p_tcapsrt_info=&tcapsrt_global_info[tcapsrt_global_current];
1774 memset(p_tcapsrt_info,0,sizeof(struct tcapsrt_info_t));
1776 return p_tcapsrt_info;
1780 tcapsrt_close(struct tcaphash_context_t *p_tcaphash_context,
1783 #ifdef DEBUG_TCAPSRT
1784 dbg(60,"Force close ");
1786 if (p_tcaphash_context) {
1787 p_tcaphash_context->responded=TRUE;
1788 p_tcaphash_context->last_frame = pinfo->fd->num;
1789 p_tcaphash_context->end_time = pinfo->fd->abs_ts;
1790 p_tcaphash_context->closed=TRUE;
1792 /* If the endkey is present */
1793 if (p_tcaphash_context->endcall
1794 && !gtcap_PersistentSRT) {
1795 if (p_tcaphash_context->endcall->next_endcall) {
1796 if (p_tcaphash_context->endcall->previous_endcall ) {
1797 #ifdef DEBUG_TCAPSRT
1798 dbg(20,"deplace Ehash ");
1800 p_tcaphash_context->endcall->previous_endcall->next_endcall
1801 = p_tcaphash_context->endcall->next_endcall;
1802 p_tcaphash_context->endcall->next_endcall->previous_endcall
1803 = p_tcaphash_context->endcall->previous_endcall;
1804 g_hash_table_remove(tcaphash_end, p_tcaphash_context->endcall->endkey);
1806 g_free(p_tcaphash_context->endcall);
1809 /* cannot remove the father */
1810 #ifdef DEBUG_TCAPSRT
1811 dbg(20,"father Ehash ");
1813 } /* no previous link, so father */
1814 } else if (!gtcap_PersistentSRT) {
1815 #ifdef DEBUG_TCAPSRT
1816 dbg(20,"remove Ehash ");
1818 g_hash_table_remove(tcaphash_end, p_tcaphash_context->endcall->endkey);
1820 g_free(p_tcaphash_context->endcall->endkey);
1821 g_free(p_tcaphash_context->endcall);
1824 } /* endcall without chained string */
1828 /* If the contkey is present */
1829 if (p_tcaphash_context->contcall
1830 && !gtcap_PersistentSRT) {
1831 if (p_tcaphash_context->contcall->next_contcall) {
1832 if (p_tcaphash_context->contcall->previous_contcall ) {
1833 #ifdef DEBUG_TCAPSRT
1834 dbg(20,"deplace Chash ");
1836 p_tcaphash_context->contcall->previous_contcall->next_contcall
1837 = p_tcaphash_context->contcall->next_contcall;
1838 p_tcaphash_context->contcall->next_contcall->previous_contcall
1839 = p_tcaphash_context->contcall->previous_contcall;
1840 g_hash_table_remove(tcaphash_cont, p_tcaphash_context->contcall->contkey);
1842 g_free(p_tcaphash_context->contcall);
1845 /* cannot remove the father */
1846 #ifdef DEBUG_TCAPSRT
1847 dbg(20,"father Chash ");
1849 } /* no previous link, so father */
1850 } else if (!gtcap_PersistentSRT) {
1851 #ifdef DEBUG_TCAPSRT
1852 dbg(20,"remove Chash ");
1854 g_hash_table_remove(tcaphash_cont, p_tcaphash_context->contcall->contkey);
1856 g_free(p_tcaphash_context->contcall->contkey);
1857 g_free(p_tcaphash_context->contcall);
1859 } /* contcall without chained string */
1863 /* If the beginkey is present */
1864 if (p_tcaphash_context->begincall
1865 && !gtcap_PersistentSRT) {
1866 if (p_tcaphash_context->begincall->next_begincall) {
1867 if (p_tcaphash_context->begincall->previous_begincall ) {
1868 #ifdef DEBUG_TCAPSRT
1869 dbg(20,"deplace Bhash ");
1871 p_tcaphash_context->begincall->previous_begincall->next_begincall
1872 = p_tcaphash_context->begincall->next_begincall;
1873 p_tcaphash_context->begincall->next_begincall->previous_begincall
1874 = p_tcaphash_context->begincall->previous_begincall;
1875 g_hash_table_remove(tcaphash_begin, p_tcaphash_context->begincall->beginkey);
1877 g_free(p_tcaphash_context->begincall);
1880 /* cannot remove the father */
1881 #ifdef DEBUG_TCAPSRT
1882 dbg(20,"father Bhash ");
1885 } else if (!gtcap_PersistentSRT) {
1886 #ifdef DEBUG_TCAPSRT
1887 dbg(20,"remove Bhash ");
1889 g_hash_table_remove(tcaphash_begin, p_tcaphash_context->begincall->beginkey);
1891 g_free(p_tcaphash_context->begincall->beginkey);
1892 g_free(p_tcaphash_context->begincall);
1894 } /* begincall without chained string */
1895 } /* no begincall */
1897 /* If the ansikey is present */
1898 if (p_tcaphash_context->ansicall
1899 && !gtcap_PersistentSRT) {
1900 if (p_tcaphash_context->ansicall->next_ansicall) {
1901 if (p_tcaphash_context->ansicall->previous_ansicall ) {
1902 #ifdef DEBUG_TCAPSRT
1903 dbg(20,"deplace Ahash ");
1905 p_tcaphash_context->ansicall->previous_ansicall->next_ansicall
1906 = p_tcaphash_context->ansicall->next_ansicall;
1907 p_tcaphash_context->ansicall->next_ansicall->previous_ansicall
1908 = p_tcaphash_context->ansicall->previous_ansicall;
1909 g_hash_table_remove(tcaphash_ansi, p_tcaphash_context->ansicall->ansikey);
1911 g_free(p_tcaphash_context->ansicall);
1914 /* cannot remove the father */
1915 #ifdef DEBUG_TCAPSRT
1916 dbg(20,"father Ahash ");
1919 } else if (!gtcap_PersistentSRT) {
1920 #ifdef DEBUG_TCAPSRT
1921 dbg(20,"remove Ahash ");
1923 g_hash_table_remove(tcaphash_ansi, p_tcaphash_context->ansicall->ansikey);
1925 g_free(p_tcaphash_context->ansicall->ansikey);
1926 g_free(p_tcaphash_context->ansicall);
1928 } /* ansicall without chained string */
1931 if (!gtcap_PersistentSRT) {
1932 #ifdef DEBUG_TCAPSRT
1933 dbg(20,"remove context ");
1935 g_hash_table_remove(tcaphash_context, p_tcaphash_context->key);
1937 g_free(p_tcaphash_context->key);
1938 g_free(p_tcaphash_context);
1941 } else { /* no context */
1942 #ifdef DEBUG_TCAPSRT
1943 dbg(20,"No context to remove ");