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.
36 #include <epan/emem.h>
37 #include <epan/packet.h>
38 #include <epan/asn1.h>
39 #include <epan/tcap-persistentdata.h>
40 #include <epan/dissectors/packet-tcap.h>
41 #include <epan/dissectors/packet-mtp3.h>
43 static gint tcaphash_context_equal(gconstpointer k1, gconstpointer k2);
44 static guint tcaphash_context_calchash(gconstpointer k);
45 static gint tcaphash_begin_equal(gconstpointer k1, gconstpointer k2);
46 static guint tcaphash_begin_calchash(gconstpointer k);
47 static gint tcaphash_cont_equal(gconstpointer k1, gconstpointer k2);
48 static guint tcaphash_cont_calchash(gconstpointer k);
49 static gint tcaphash_end_equal(gconstpointer k1, gconstpointer k2);
50 static guint tcaphash_end_calchash(gconstpointer k);
51 static gint tcaphash_ansi_equal(gconstpointer k1, gconstpointer k2);
52 static guint tcaphash_ansi_calchash(gconstpointer k);
54 static void update_tcaphash_begincall(struct tcaphash_begincall_t *p_tcaphash_begincall,
57 static struct tcaphash_begincall_t *append_tcaphash_begincall(struct tcaphash_begincall_t *prev_begincall,
58 struct tcaphash_context_t *p_tcaphash_context,
62 static struct tcaphash_begincall_t *find_tcaphash_begin(struct tcaphash_begin_info_key_t *p_tcaphash_begin_key,
67 static struct tcaphash_contcall_t *find_tcaphash_cont(struct tcaphash_cont_info_key_t *p_tcaphash_cont_key,
70 static struct tcaphash_endcall_t *find_tcaphash_end(struct tcaphash_end_info_key_t *p_tcaphash_end_key,
74 static struct tcaphash_context_t *new_tcaphash_context(struct tcaphash_context_key_t *p_tcaphash_context_key,
77 static struct tcaphash_begincall_t *new_tcaphash_begin(struct tcaphash_begin_info_key_t *p_tcaphash_begin_key,
78 struct tcaphash_context_t *p_tcaphash_context);
80 static struct tcaphash_contcall_t *new_tcaphash_cont(struct tcaphash_cont_info_key_t *p_tcaphash_cont_key,
81 struct tcaphash_context_t *p_tcaphash_context);
83 static struct tcaphash_endcall_t *new_tcaphash_end(struct tcaphash_end_info_key_t *p_tcaphash_end_key,
84 struct tcaphash_context_t *p_tcaphash_context);
86 static struct tcaphash_context_t *tcaphash_begin_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
87 struct tcapsrt_info_t *p_tcapsrt_info);
89 static struct tcaphash_context_t *tcaphash_cont_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
90 struct tcapsrt_info_t *p_tcapsrt_info);
92 static struct tcaphash_context_t *tcaphash_end_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
93 struct tcapsrt_info_t *p_tcapsrt_info);
95 static struct tcaphash_context_t *tcaphash_ansi_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
96 struct tcapsrt_info_t *p_tcapsrt_info);
98 struct tcapsrt_info_t *tcapsrt_razinfo(void);
100 /* When several Tcap components are received in a single TCAP message,
101 we have to use several buffers for the stored parameters
102 because else this data are erased during TAP dissector call */
103 #define MAX_TCAP_INSTANCE 10
104 int tcapsrt_global_current=0;
105 struct tcapsrt_info_t tcapsrt_global_info[MAX_TCAP_INSTANCE];
107 /* These two timeout (in second) are used when some message are lost,
108 or when the same TCAP transcation identifier is reused */
109 guint gtcap_RepetitionTimeout = 10;
110 guint gtcap_LostTimeout = 30;
111 extern gboolean gtcap_HandleSRT;
112 gboolean gtcap_PersistentSRT=FALSE;
113 gboolean gtcap_DisplaySRT=FALSE;
114 gboolean gtcap_StatSRT=FALSE;
116 extern gint ett_tcap_stat;
118 extern int hf_tcapsrt_SessionId;
119 extern int hf_tcapsrt_Duplicate;
120 extern int hf_tcapsrt_BeginSession;
121 extern int hf_tcapsrt_EndSession;
122 extern int hf_tcapsrt_SessionTime;
124 /* Global hash tables*/
125 static GHashTable *tcaphash_context = NULL;
126 static GHashTable *tcaphash_begin = NULL;
127 static GHashTable *tcaphash_cont = NULL;
128 static GHashTable *tcaphash_end = NULL;
129 static GHashTable *tcaphash_ansi = NULL;
131 guint32 tcapsrt_global_SessionId=1;
137 /* #define MEM_TCAPSRT */
140 /* #define DEBUG_TCAPSRT */
145 static unsigned debug_level = 99;
148 dbg(unsigned level, char* fmt, ...)
152 if (level > debug_level) return;
154 vfprintf(stderr, fmt, ap);
160 tcaphash_context_equal(gconstpointer k1, gconstpointer k2)
162 const struct tcaphash_context_key_t *key1 = (const struct tcaphash_context_key_t *) k1;
163 const struct tcaphash_context_key_t *key2 = (const struct tcaphash_context_key_t *) k2;
165 return (key1->session_id == key2->session_id);
168 /* calculate a hash key */
170 tcaphash_context_calchash(gconstpointer k)
172 const struct tcaphash_context_key_t *key = (const struct tcaphash_context_key_t *) k;
173 return key->session_id;
178 tcaphash_begin_equal(gconstpointer k1, gconstpointer k2)
180 const struct tcaphash_begin_info_key_t *key1 = (const struct tcaphash_begin_info_key_t *) k1;
181 const struct tcaphash_begin_info_key_t *key2 = (const struct tcaphash_begin_info_key_t *) k2;
183 if (key1->hashKey == key2->hashKey) {
185 if ( ( (key1->opc_hash == key2->opc_hash) &&
186 (key1->dpc_hash == key2->dpc_hash) &&
187 (key1->tid == key2->tid) )
189 ( (key1->opc_hash == key2->dpc_hash) &&
190 (key1->dpc_hash == key2->opc_hash) &&
191 (key1->tid == key2->tid) )
198 /* calculate a hash key */
200 tcaphash_begin_calchash(gconstpointer k)
202 const struct tcaphash_begin_info_key_t *key = (const struct tcaphash_begin_info_key_t *) k;
204 /* hashkey = key->opc_hash<<16 + key->dpc_hash<<8 + key->src_tid; */
210 tcaphash_cont_equal(gconstpointer k1, gconstpointer k2)
212 const struct tcaphash_cont_info_key_t *key1 = (const struct tcaphash_cont_info_key_t *) k1;
213 const struct tcaphash_cont_info_key_t *key2 = (const struct tcaphash_cont_info_key_t *) k2;
215 if (key1->hashKey == key2->hashKey) {
217 if ( (key1->opc_hash == key2->opc_hash) &&
218 (key1->dpc_hash == key2->dpc_hash) &&
219 (key1->src_tid == key2->src_tid) &&
220 (key1->dst_tid == key2->dst_tid) ) {
223 else if ( (key1->opc_hash == key2->dpc_hash) &&
224 (key1->dpc_hash == key2->opc_hash) &&
225 (key1->src_tid == key2->dst_tid) &&
226 (key1->dst_tid == key2->src_tid) ) {
233 /* calculate a hash key */
235 tcaphash_cont_calchash(gconstpointer k)
237 const struct tcaphash_cont_info_key_t *key = (const struct tcaphash_cont_info_key_t *) k;
239 hashkey = key->src_tid + key->dst_tid;
245 tcaphash_end_equal(gconstpointer k1, gconstpointer k2)
247 const struct tcaphash_end_info_key_t *key1 = (const struct tcaphash_end_info_key_t *) k1;
248 const struct tcaphash_end_info_key_t *key2 = (const struct tcaphash_end_info_key_t *) k2;
250 if (key1->hashKey == key2->hashKey) {
251 if ( ( (key1->opc_hash == key2->opc_hash) &&
252 (key1->dpc_hash == key2->dpc_hash) &&
253 (key1->tid == key2->tid) )
255 ( (key1->opc_hash == key2->dpc_hash) &&
256 (key1->dpc_hash == key2->opc_hash) &&
257 (key1->tid == key2->tid) ) )
263 /* calculate a hash key */
265 tcaphash_end_calchash(gconstpointer k)
267 const struct tcaphash_end_info_key_t *key = (const struct tcaphash_end_info_key_t *) k;
274 tcaphash_ansi_equal(gconstpointer k1, gconstpointer k2)
276 const struct tcaphash_ansi_info_key_t *key1 = (const struct tcaphash_ansi_info_key_t *) k1;
277 const struct tcaphash_ansi_info_key_t *key2 = (const struct tcaphash_ansi_info_key_t *) k2;
279 if (key1->hashKey == key2->hashKey) {
281 if ( ( (key1->opc_hash == key2->opc_hash) &&
282 (key1->dpc_hash == key2->dpc_hash) &&
283 (key1->tid == key2->tid) )
285 ( (key1->opc_hash == key2->dpc_hash) &&
286 (key1->dpc_hash == key2->opc_hash) &&
287 (key1->tid == key2->tid) )
294 /* calculate a hash key */
296 tcaphash_ansi_calchash(gconstpointer k)
298 const struct tcaphash_ansi_info_key_t *key = (const struct tcaphash_ansi_info_key_t *) k;
300 /* hashkey = key->opc_hash<<16 + key->dpc_hash<<8 + key->src_tid; */
306 * Update a record with the data of the Request
309 update_tcaphash_begincall(struct tcaphash_begincall_t *p_tcaphash_begincall,
312 p_tcaphash_begincall->context->first_frame = pinfo->fd->num;
313 p_tcaphash_begincall->context->last_frame = 0;
314 p_tcaphash_begincall->context->responded = FALSE;
315 p_tcaphash_begincall->context->begin_time = pinfo->fd->abs_ts;
319 * Append a new dialogue, using the same Key, to the chained list
320 * The time is stored too
322 static struct tcaphash_begincall_t *
323 append_tcaphash_begincall(struct tcaphash_begincall_t *prev_begincall,
324 struct tcaphash_context_t *p_tcaphash_context,
327 struct tcaphash_begincall_t *p_new_tcaphash_begincall = NULL;
329 /* Append the transaction to the list, when the same key is found
330 This should append when the tcap-transaction Id is reused */
333 p_new_tcaphash_begincall = g_malloc0(sizeof(struct tcaphash_begincall_t));
335 p_new_tcaphash_begincall = se_alloc0(sizeof(struct tcaphash_begincall_t));
337 p_new_tcaphash_begincall->context=p_tcaphash_context;
338 p_tcaphash_context->begincall=p_new_tcaphash_begincall;
339 p_new_tcaphash_begincall->beginkey=prev_begincall->beginkey;
340 p_new_tcaphash_begincall->context->first_frame = pinfo->fd->num;
341 p_new_tcaphash_begincall->next_begincall=NULL;
342 p_new_tcaphash_begincall->previous_begincall=prev_begincall;
343 p_new_tcaphash_begincall->father=FALSE;
346 dbg(10,"+B%d ", p_new_tcaphash_begincall->context->session_id);
348 /* Insert in the chained list */
349 prev_begincall->next_begincall = p_new_tcaphash_begincall;
350 if (prev_begincall->context->last_frame == 0) {
354 prev_begincall->context->last_frame = pinfo->fd->num-1;
356 return p_new_tcaphash_begincall;
360 * Update a record with the data of the Request
363 update_tcaphash_ansicall(struct tcaphash_ansicall_t *p_tcaphash_ansicall,
366 p_tcaphash_ansicall->context->first_frame = pinfo->fd->num;
367 p_tcaphash_ansicall->context->last_frame = 0;
368 p_tcaphash_ansicall->context->responded = FALSE;
369 p_tcaphash_ansicall->context->begin_time = pinfo->fd->abs_ts;
373 * Append a new dialogue, using the same Key, to the chained list
374 * The time is stored too
376 static struct tcaphash_ansicall_t *
377 append_tcaphash_ansicall(struct tcaphash_ansicall_t *prev_ansicall,
378 struct tcaphash_context_t *p_tcaphash_context,
381 struct tcaphash_ansicall_t *p_new_tcaphash_ansicall = NULL;
383 /* Append the transaction to the list, when the same key is found
384 This should append when the tcap-transaction Id is reused */
387 p_new_tcaphash_ansicall = g_malloc0(sizeof(struct tcaphash_ansicall_t));
389 p_new_tcaphash_ansicall = se_alloc0(sizeof(struct tcaphash_ansicall_t));
391 p_new_tcaphash_ansicall->context=p_tcaphash_context;
392 p_tcaphash_context->ansicall=p_new_tcaphash_ansicall;
393 p_new_tcaphash_ansicall->ansikey=prev_ansicall->ansikey;
394 p_new_tcaphash_ansicall->context->first_frame = pinfo->fd->num;
395 p_new_tcaphash_ansicall->next_ansicall=NULL;
396 p_new_tcaphash_ansicall->previous_ansicall=prev_ansicall;
397 p_new_tcaphash_ansicall->father=FALSE;
400 dbg(10,"+A%d ", p_new_tcaphash_ansicall->context->session_id);
402 /* Insert in the chained list */
403 prev_ansicall->next_ansicall = p_new_tcaphash_ansicall;
404 if (prev_ansicall->context->last_frame == 0) {
408 prev_ansicall->context->last_frame = pinfo->fd->num-1;
410 return p_new_tcaphash_ansicall;
414 static struct tcaphash_contcall_t *
415 append_tcaphash_contcall(struct tcaphash_contcall_t *prev_contcall,
416 struct tcaphash_context_t *p_tcaphash_context)
418 struct tcaphash_contcall_t *p_new_tcaphash_contcall = NULL;
420 /* Append the transaction to the list, when the same key is found
421 This should append when the tcap-transaction Id is reused */
424 p_new_tcaphash_contcall = g_malloc0(sizeof(struct tcaphash_contcall_t));
426 p_new_tcaphash_contcall = se_alloc0(sizeof(struct tcaphash_contcall_t));
428 p_new_tcaphash_contcall->context=p_tcaphash_context;
429 p_tcaphash_context->contcall=p_new_tcaphash_contcall;
430 p_new_tcaphash_contcall->contkey=prev_contcall->contkey;
431 p_new_tcaphash_contcall->next_contcall=NULL;
432 p_new_tcaphash_contcall->previous_contcall=prev_contcall;
433 p_new_tcaphash_contcall->father=FALSE;
436 dbg(10,"+C%d ", p_new_tcaphash_contcall->context->session_id);
438 /* Insert in the chained list */
439 prev_contcall->next_contcall = p_new_tcaphash_contcall;
440 return p_new_tcaphash_contcall;
444 static struct tcaphash_endcall_t *
445 append_tcaphash_endcall(struct tcaphash_endcall_t *prev_endcall,
446 struct tcaphash_context_t *p_tcaphash_context)
448 struct tcaphash_endcall_t *p_new_tcaphash_endcall = NULL;
450 /* Append the transaction to the list, when the same key is found
451 This should append when the tcap-transaction Id is reused */
454 p_new_tcaphash_endcall = g_malloc0(sizeof(struct tcaphash_endcall_t));
456 p_new_tcaphash_endcall = se_alloc0(sizeof(struct tcaphash_endcall_t));
458 p_new_tcaphash_endcall->context=p_tcaphash_context;
459 p_tcaphash_context->endcall=p_new_tcaphash_endcall;
460 p_new_tcaphash_endcall->endkey=prev_endcall->endkey;
461 p_new_tcaphash_endcall->next_endcall=NULL;
462 p_new_tcaphash_endcall->previous_endcall=prev_endcall;
463 p_new_tcaphash_endcall->father=FALSE;
466 dbg(10,"+E%d ", p_new_tcaphash_endcall->context->session_id);
468 /* Insert in the chained list */
469 prev_endcall->next_endcall = p_new_tcaphash_endcall;
470 return p_new_tcaphash_endcall;
475 * Find the dialog by Key and Time
477 static struct tcaphash_begincall_t *
478 find_tcaphash_begin(struct tcaphash_begin_info_key_t *p_tcaphash_begin_key,
479 packet_info *pinfo, gboolean isBegin)
481 struct tcaphash_begincall_t *p_tcaphash_begincall = NULL;
482 p_tcaphash_begincall = (struct tcaphash_begincall_t *)g_hash_table_lookup(tcaphash_begin, p_tcaphash_begin_key);
484 if(p_tcaphash_begincall) {
486 if ( p_tcaphash_begincall->context ) {
488 pinfo->fd->num == p_tcaphash_begincall->context->first_frame )
491 pinfo->fd->num >= p_tcaphash_begincall->context->first_frame &&
492 ( p_tcaphash_begincall->context->last_frame?pinfo->fd->num <= p_tcaphash_begincall->context->last_frame:1 )
495 /* We have a dialogue, with this key, opened before this request */
497 dbg(10,"B%d ", p_tcaphash_begincall->context->session_id);
499 return p_tcaphash_begincall;
503 dbg(60,"[B%d] ", p_tcaphash_begincall->context->session_id);
506 /* Break when list end is reached */
507 if(p_tcaphash_begincall->next_begincall == NULL) {
509 dbg(23,"End of Blist ");
513 p_tcaphash_begincall = p_tcaphash_begincall->next_begincall;
514 } while (p_tcaphash_begincall != NULL) ;
517 dbg(23,"Not in Bhash ");
525 static struct tcaphash_contcall_t *
526 find_tcaphash_cont(struct tcaphash_cont_info_key_t *p_tcaphash_cont_key,
529 struct tcaphash_contcall_t *p_tcaphash_contcall = NULL;
530 p_tcaphash_contcall = (struct tcaphash_contcall_t *)g_hash_table_lookup(tcaphash_cont, p_tcaphash_cont_key);
532 if(p_tcaphash_contcall) {
534 if ( p_tcaphash_contcall->context ) {
535 if (pinfo->fd->num >= p_tcaphash_contcall->context->first_frame &&
536 (p_tcaphash_contcall->context->last_frame?pinfo->fd->num <= p_tcaphash_contcall->context->last_frame:1) ) {
537 /* We have a dialogue, with this key, opened before this request */
539 dbg(10,"C%d ", p_tcaphash_contcall->context->session_id);
541 return p_tcaphash_contcall;
545 dbg(60,"[C%d] ", p_tcaphash_contcall->context->session_id);
548 /* Break when list end is reached */
549 if(p_tcaphash_contcall->next_contcall == NULL) {
551 dbg(23,"End of Clist ");
555 p_tcaphash_contcall = p_tcaphash_contcall->next_contcall;
556 } while (p_tcaphash_contcall != NULL) ;
559 dbg(23,"Not in Chash ");
565 static struct tcaphash_endcall_t *
566 find_tcaphash_end(struct tcaphash_end_info_key_t *p_tcaphash_end_key,
567 packet_info *pinfo, gboolean isEnd)
569 struct tcaphash_endcall_t *p_tcaphash_endcall = NULL;
570 p_tcaphash_endcall = (struct tcaphash_endcall_t *)g_hash_table_lookup(tcaphash_end, p_tcaphash_end_key);
572 if(p_tcaphash_endcall) {
574 if ( p_tcaphash_endcall->context ) {
576 (p_tcaphash_endcall->context->last_frame?pinfo->fd->num == p_tcaphash_endcall->context->last_frame:1)
580 pinfo->fd->num >= p_tcaphash_endcall->context->first_frame &&
581 (p_tcaphash_endcall->context->last_frame?pinfo->fd->num <= p_tcaphash_endcall->context->last_frame:1)
584 /* We have a dialogue, with this key, opened before this request */
586 dbg(10,"E%d ", p_tcaphash_endcall->context->session_id);
588 return p_tcaphash_endcall;
592 dbg(60,"[E%d] ", p_tcaphash_endcall->context->session_id);
595 /* Break when list end is reached */
596 if(p_tcaphash_endcall->next_endcall == NULL) {
598 dbg(23,"End of Elist ");
602 p_tcaphash_endcall = p_tcaphash_endcall->next_endcall;
603 } while (p_tcaphash_endcall != NULL) ;
606 dbg(23,"Not in Ehash ");
613 * New record to create, to identify a new transaction
615 static struct tcaphash_context_t *
616 new_tcaphash_context(struct tcaphash_context_key_t *p_tcaphash_context_key,
619 struct tcaphash_context_key_t *p_new_tcaphash_context_key;
620 struct tcaphash_context_t *p_new_tcaphash_context = NULL;
622 /* Register the transaction in the hash table
623 with the tcap transaction Id as Main Key
624 Once created, this entry will be updated later */
627 p_new_tcaphash_context_key = g_malloc(sizeof(struct tcaphash_context_key_t));
629 p_new_tcaphash_context_key = se_alloc(sizeof(struct tcaphash_context_key_t));
631 p_new_tcaphash_context_key->session_id = p_tcaphash_context_key->session_id;
634 p_new_tcaphash_context = g_malloc0(sizeof(struct tcaphash_context_t));
636 p_new_tcaphash_context = se_alloc0(sizeof(struct tcaphash_context_t));
638 p_new_tcaphash_context->key = p_new_tcaphash_context_key;
639 p_new_tcaphash_context->session_id = p_tcaphash_context_key->session_id;
640 p_new_tcaphash_context->first_frame = pinfo->fd->num;
642 dbg(10,"S%d ", p_new_tcaphash_context->session_id);
645 g_hash_table_insert(tcaphash_context, p_new_tcaphash_context_key, p_new_tcaphash_context);
646 return p_new_tcaphash_context;
650 * New record to create, to identify a new transaction
652 static struct tcaphash_begincall_t *
653 new_tcaphash_begin(struct tcaphash_begin_info_key_t *p_tcaphash_begin_key,
654 struct tcaphash_context_t *p_tcaphash_context)
656 struct tcaphash_begin_info_key_t *p_new_tcaphash_begin_key;
657 struct tcaphash_begincall_t *p_new_tcaphash_begincall = NULL;
659 /* Register the transaction in the hash table
660 with the tcap transaction Id as Main Key
661 Once created, this entry will be updated later */
664 p_new_tcaphash_begin_key = g_malloc(sizeof(struct tcaphash_begin_info_key_t));
666 p_new_tcaphash_begin_key = se_alloc(sizeof(struct tcaphash_begin_info_key_t));
668 p_new_tcaphash_begin_key->hashKey = p_tcaphash_begin_key->hashKey;
669 p_new_tcaphash_begin_key->tid = p_tcaphash_begin_key->tid;
670 p_new_tcaphash_begin_key->opc_hash = p_tcaphash_begin_key->opc_hash;
671 p_new_tcaphash_begin_key->dpc_hash = p_tcaphash_begin_key->dpc_hash;
674 p_new_tcaphash_begincall = g_malloc0(sizeof(struct tcaphash_begincall_t));
676 p_new_tcaphash_begincall = se_alloc0(sizeof(struct tcaphash_begincall_t));
678 p_new_tcaphash_begincall->beginkey=p_new_tcaphash_begin_key;
679 p_new_tcaphash_begincall->context=p_tcaphash_context;
680 p_tcaphash_context->begincall=p_new_tcaphash_begincall;
681 p_new_tcaphash_begincall->father=TRUE;
682 p_new_tcaphash_begincall->next_begincall=NULL;
683 p_new_tcaphash_begincall->previous_begincall=NULL;
686 dbg(10,"B%d ", p_new_tcaphash_begincall->context->session_id);
689 g_hash_table_insert(tcaphash_begin, p_new_tcaphash_begin_key, p_new_tcaphash_begincall);
690 return p_new_tcaphash_begincall;
696 * New record to create, to identify a new transaction
698 static struct tcaphash_contcall_t *
699 new_tcaphash_cont(struct tcaphash_cont_info_key_t *p_tcaphash_cont_key,
700 struct tcaphash_context_t *p_tcaphash_context)
702 struct tcaphash_cont_info_key_t *p_new_tcaphash_cont_key;
703 struct tcaphash_contcall_t *p_new_tcaphash_contcall = NULL;
705 /* Register the transaction in the hash table
706 with the tcap transaction Id as Main Key
707 Once created, this entry will be updated later */
710 p_new_tcaphash_cont_key = g_malloc(sizeof(struct tcaphash_cont_info_key_t));
712 p_new_tcaphash_cont_key = se_alloc(sizeof(struct tcaphash_cont_info_key_t));
714 p_new_tcaphash_cont_key->hashKey = p_tcaphash_cont_key->hashKey;
715 p_new_tcaphash_cont_key->src_tid = p_tcaphash_cont_key->src_tid;
716 p_new_tcaphash_cont_key->dst_tid = p_tcaphash_cont_key->dst_tid;
717 p_new_tcaphash_cont_key->opc_hash = p_tcaphash_cont_key->opc_hash;
718 p_new_tcaphash_cont_key->dpc_hash = p_tcaphash_cont_key->dpc_hash;
721 p_new_tcaphash_contcall = g_malloc0(sizeof(struct tcaphash_contcall_t));
723 p_new_tcaphash_contcall = se_alloc0(sizeof(struct tcaphash_contcall_t));
725 p_new_tcaphash_contcall->contkey=p_new_tcaphash_cont_key;
726 p_new_tcaphash_contcall->context=p_tcaphash_context;
727 p_tcaphash_context->contcall=p_new_tcaphash_contcall;
728 p_new_tcaphash_contcall->father=TRUE;
729 p_new_tcaphash_contcall->next_contcall=NULL;
730 p_new_tcaphash_contcall->previous_contcall=NULL;
733 dbg(10,"C%d ", p_new_tcaphash_contcall->context->session_id);
736 g_hash_table_insert(tcaphash_cont, p_new_tcaphash_cont_key, p_new_tcaphash_contcall);
737 return p_new_tcaphash_contcall;
742 * New record to create, to identify a new transaction
744 static struct tcaphash_endcall_t *
745 new_tcaphash_end(struct tcaphash_end_info_key_t *p_tcaphash_end_key,
746 struct tcaphash_context_t *p_tcaphash_context)
748 struct tcaphash_end_info_key_t *p_new_tcaphash_end_key;
749 struct tcaphash_endcall_t *p_new_tcaphash_endcall = NULL;
751 /* Register the transaction in the hash table
752 with the tcap transaction Id as Main Key
753 Once created, this entry will be updated later */
756 p_new_tcaphash_end_key = g_malloc(sizeof(struct tcaphash_end_info_key_t));
758 p_new_tcaphash_end_key = se_alloc(sizeof(struct tcaphash_end_info_key_t));
760 p_new_tcaphash_end_key->hashKey = p_tcaphash_end_key->hashKey;
761 p_new_tcaphash_end_key->tid = p_tcaphash_end_key->tid;
762 p_new_tcaphash_end_key->opc_hash = p_tcaphash_end_key->opc_hash;
763 p_new_tcaphash_end_key->dpc_hash = p_tcaphash_end_key->dpc_hash;
766 p_new_tcaphash_endcall = g_malloc0(sizeof(struct tcaphash_endcall_t));
768 p_new_tcaphash_endcall = se_alloc0(sizeof(struct tcaphash_endcall_t));
770 p_new_tcaphash_endcall->endkey=p_new_tcaphash_end_key;
771 p_new_tcaphash_endcall->context=p_tcaphash_context;
772 p_tcaphash_context->endcall=p_new_tcaphash_endcall;
773 p_new_tcaphash_endcall->father=TRUE;
774 p_new_tcaphash_endcall->next_endcall=NULL;
775 p_new_tcaphash_endcall->previous_endcall=NULL;
778 dbg(10,"E%d ", p_new_tcaphash_endcall->context->session_id);
781 g_hash_table_insert(tcaphash_end, p_new_tcaphash_end_key, p_new_tcaphash_endcall);
782 return p_new_tcaphash_endcall;
785 * New record to create, to identify a new transaction
787 static struct tcaphash_ansicall_t *
788 new_tcaphash_ansi(struct tcaphash_ansi_info_key_t *p_tcaphash_ansi_key,
789 struct tcaphash_context_t *p_tcaphash_context)
791 struct tcaphash_ansi_info_key_t *p_new_tcaphash_ansi_key;
792 struct tcaphash_ansicall_t *p_new_tcaphash_ansicall = NULL;
794 /* Register the transaction in the hash table
795 with the tcap transaction Id as Main Key
796 Once created, this entry will be updated later */
799 p_new_tcaphash_ansi_key = g_malloc(sizeof(struct tcaphash_ansi_info_key_t));
801 p_new_tcaphash_ansi_key = se_alloc(sizeof(struct tcaphash_ansi_info_key_t));
803 p_new_tcaphash_ansi_key->hashKey = p_tcaphash_ansi_key->hashKey;
804 p_new_tcaphash_ansi_key->tid = p_tcaphash_ansi_key->tid;
805 p_new_tcaphash_ansi_key->opc_hash = p_tcaphash_ansi_key->opc_hash;
806 p_new_tcaphash_ansi_key->dpc_hash = p_tcaphash_ansi_key->dpc_hash;
809 p_new_tcaphash_ansicall = g_malloc0(sizeof(struct tcaphash_ansicall_t));
811 p_new_tcaphash_ansicall = se_alloc0(sizeof(struct tcaphash_ansicall_t));
813 p_new_tcaphash_ansicall->ansikey=p_new_tcaphash_ansi_key;
814 p_new_tcaphash_ansicall->context=p_tcaphash_context;
815 p_tcaphash_context->ansicall=p_new_tcaphash_ansicall;
816 p_new_tcaphash_ansicall->father=TRUE;
817 p_new_tcaphash_ansicall->next_ansicall=NULL;
818 p_new_tcaphash_ansicall->previous_ansicall=NULL;
821 dbg(10,"A%d ", p_new_tcaphash_ansicall->context->session_id);
824 g_hash_table_insert(tcaphash_ansi, p_new_tcaphash_ansi_key, p_new_tcaphash_ansicall);
825 return p_new_tcaphash_ansicall;
828 static struct tcaphash_contcall_t *
829 create_tcaphash_cont(struct tcaphash_cont_info_key_t *p_tcaphash_cont_key,
830 struct tcaphash_context_t *p_tcaphash_context)
832 struct tcaphash_contcall_t *p_tcaphash_contcall1 = NULL;
833 struct tcaphash_contcall_t *p_tcaphash_contcall = NULL;
835 p_tcaphash_contcall1 = (struct tcaphash_contcall_t *)
836 g_hash_table_lookup(tcaphash_cont, p_tcaphash_cont_key);
838 if (p_tcaphash_contcall1) {
839 /* Walk through list of transaction with identical keys */
840 /* go the the end to insert new record */
842 if (!p_tcaphash_contcall1->next_contcall) {
843 p_tcaphash_contcall=append_tcaphash_contcall(p_tcaphash_contcall1,
847 p_tcaphash_contcall1 = p_tcaphash_contcall1->next_contcall;
848 } while (p_tcaphash_contcall1 != NULL );
850 p_tcaphash_contcall = new_tcaphash_cont(p_tcaphash_cont_key,
853 return p_tcaphash_contcall;
857 static struct tcaphash_endcall_t *
858 create_tcaphash_end(struct tcaphash_end_info_key_t *p_tcaphash_end_key,
859 struct tcaphash_context_t *p_tcaphash_context)
861 struct tcaphash_endcall_t *p_tcaphash_endcall1 = NULL;
862 struct tcaphash_endcall_t *p_tcaphash_endcall = NULL;
864 p_tcaphash_endcall1 = (struct tcaphash_endcall_t *)
865 g_hash_table_lookup(tcaphash_end, p_tcaphash_end_key);
867 if (p_tcaphash_endcall1) {
868 /* Walk through list of transaction with identical keys */
869 /* go the the end to insert new record */
871 if (!p_tcaphash_endcall1->next_endcall) {
872 p_tcaphash_endcall=append_tcaphash_endcall(p_tcaphash_endcall1,
876 p_tcaphash_endcall1 = p_tcaphash_endcall1->next_endcall;
877 } while (p_tcaphash_endcall1 != NULL );
879 p_tcaphash_endcall = new_tcaphash_end(p_tcaphash_end_key,
882 return p_tcaphash_endcall;
887 * Routine called when the TAP is initialized.
888 * so hash table are (re)created
891 tcapsrt_init_routine(void)
894 /* free hash-tables and mem_chunks for SRT */
895 if (tcaphash_context != NULL) {
897 dbg(16,"Destroy hash_context ");
899 g_hash_table_destroy(tcaphash_context);
902 if (tcaphash_begin != NULL) {
904 dbg(16,"Destroy hash_begin ");
906 g_hash_table_destroy(tcaphash_begin);
909 if (tcaphash_cont != NULL) {
911 dbg(16,"Destroy hash_cont ");
913 g_hash_table_destroy(tcaphash_cont);
916 if (tcaphash_end != NULL) {
918 dbg(16,"Destroy hash_end ");
920 g_hash_table_destroy(tcaphash_end);
923 if (tcaphash_ansi != NULL) {
925 dbg(16,"Destroy hash_ansi ");
927 g_hash_table_destroy(tcaphash_ansi);
931 dbg(16,"Create hash ");
933 /* create new hash-tables and mem_chunks for SRT */
934 tcaphash_context = g_hash_table_new(tcaphash_context_calchash, tcaphash_context_equal);
935 tcaphash_begin = g_hash_table_new(tcaphash_begin_calchash, tcaphash_begin_equal);
936 tcaphash_cont = g_hash_table_new(tcaphash_cont_calchash, tcaphash_cont_equal);
937 tcaphash_end = g_hash_table_new(tcaphash_end_calchash, tcaphash_end_equal);
938 tcaphash_ansi = g_hash_table_new(tcaphash_ansi_calchash, tcaphash_ansi_equal);
940 /* Reset the session counter */
941 tcapsrt_global_SessionId=1;
943 /* Display of SRT only if Persistent Stat */
944 gtcap_DisplaySRT=gtcap_PersistentSRT || gtcap_HandleSRT>cap_StatSRT;
948 * Service Response Time analyze
949 * Called just after dissector call
950 * Associate a TCAP context to a tcap session and display session related infomations
951 * like the first frame, the last, the session duration,
952 * and a uniq session identifier for the filtering
954 * For ETSI tcap, the TCAP context can be reached through three keys
955 * - a key (BEGIN) identifying the session according to the tcap source identifier
956 * - a key (CONT) identifying the established session (src_id and dst_id)
957 * - a key (END) identifying the session according to the tcap destination identifier
959 * For ANSI tcap, the TCAP context is reached through a uniq key
960 * - a key (ANSI) identifying the session according to the tcap identifier
962 struct tcaphash_context_t *
963 tcapsrt_call_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
964 struct tcapsrt_info_t *p_tcapsrt_info)
966 struct tcaphash_context_t *tcap_context=NULL;
968 /* if this packet isn't loaded because of a read filter, don't output anything */
969 if(pinfo == NULL || pinfo->fd->num == 0) {
973 switch (p_tcapsrt_info->ope) {
979 tcap_context=tcaphash_begin_matching(tvb, pinfo, tree, p_tcapsrt_info);
986 tcap_context=tcaphash_cont_matching(tvb, pinfo, tree, p_tcapsrt_info);
993 tcap_context=tcaphash_end_matching(tvb, pinfo, tree, p_tcapsrt_info);
1000 tcap_context=tcaphash_end_matching(tvb, pinfo, tree, p_tcapsrt_info);
1005 #ifdef DEBUG_TCAPSRT
1008 tcap_context=tcaphash_ansi_matching(tvb, pinfo, tree, p_tcapsrt_info);
1012 #ifdef DEBUG_TCAPSRT
1013 dbg(1,"Unknown %d ", p_tcapsrt_info->ope);
1016 } /* switch tcapop */
1017 #ifdef DEBUG_TCAPSRT
1019 dbg(1,"session %d ", tcap_context->session_id);
1021 return tcap_context;
1026 * Create the record identifiying the TCAP transaction
1027 * When the identifier for the transaction is reused, check
1028 * the following criteria before to append a new record:
1029 * - a timeout corresponding to a message retransmission is detected,
1030 * - a message hast been lost
1031 * - or the previous transaction has been be closed
1033 static struct tcaphash_context_t *
1034 tcaphash_begin_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1035 struct tcapsrt_info_t *p_tcapsrt_info)
1037 struct tcaphash_context_t *p_tcaphash_context=NULL;
1038 struct tcaphash_context_key_t tcaphash_context_key;
1039 struct tcaphash_begincall_t *p_tcaphash_begincall, *p_new_tcaphash_begincall=NULL;
1040 struct tcaphash_begin_info_key_t tcaphash_begin_key;
1042 proto_item *stat_item=NULL;
1043 proto_tree *stat_tree=NULL;
1045 /* prepare the key data */
1046 tcaphash_begin_key.tid = p_tcapsrt_info->src_tid;
1047 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1049 /* We have MTP3 PCs (so we can safely do this cast) */
1050 tcaphash_begin_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1051 tcaphash_begin_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1053 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1054 tcaphash_begin_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1055 tcaphash_begin_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1057 tcaphash_begin_key.hashKey=tcaphash_begin_calchash(&tcaphash_begin_key);
1059 /* look up the request */
1060 #ifdef DEBUG_TCAPSRT
1061 dbg(10,"\n Hbegin #%u ", pinfo->fd->num);
1062 dbg(11,"key %lx ",tcaphash_begin_key.hashKey);
1063 dbg(51,"PC %s %s ",ep_address_to_str(&pinfo->src), ep_address_to_str(&pinfo->dst));
1064 dbg(51,"Tid %lx ",tcaphash_begin_key.tid);
1067 p_tcaphash_begincall = (struct tcaphash_begincall_t *)
1068 g_hash_table_lookup(tcaphash_begin, &tcaphash_begin_key);
1070 if (p_tcaphash_begincall) {
1071 /* Walk through list of transaction with identical keys */
1073 /* Check if the request with this reqSeqNum has been seen, with the same Message Type */
1074 if (pinfo->fd->num == p_tcaphash_begincall->context->first_frame) {
1075 /* We have seen this request before -> do nothing */
1076 #ifdef DEBUG_TCAPSRT
1077 dbg(22,"Already seen ");
1079 p_tcaphash_context=p_tcaphash_begincall->context;
1082 /* If the last record for Tcap transaction with identifier has not been reached */
1083 if (!p_tcaphash_begincall->next_begincall) {
1084 /* check if we have to create a new record or not */
1085 /* if last request has been responded (response number is known)
1086 and this request appears after last response (has bigger frame number)
1087 and last request occured after the timeout for repetition,
1089 if last request hasn't been responded (so number unknown)
1090 and this request appears after last request (has bigger frame number)
1091 and this request occured after the timeout for message lost */
1092 if ( ( p_tcaphash_begincall->context->last_frame != 0
1093 && pinfo->fd->num > p_tcaphash_begincall->context->first_frame
1094 && (guint) pinfo->fd->abs_ts.secs > (guint)(p_tcaphash_begincall->context->begin_time.secs + gtcap_RepetitionTimeout)
1096 ( p_tcaphash_begincall->context->last_frame == 0
1097 && pinfo->fd->num > p_tcaphash_begincall->context->first_frame
1098 && (guint)pinfo->fd->abs_ts.secs > (guint)(p_tcaphash_begincall->context->begin_time.secs + gtcap_LostTimeout)
1102 /* we decide that we have a new request */
1103 /* Append new record to the list */
1104 #ifdef DEBUG_TCAPSRT
1105 dbg(12,"(timeout) Append key %lx ",tcaphash_begin_key.hashKey);
1106 dbg(12,"Frame %u rsp %u ",pinfo->fd->num,p_tcaphash_begincall->context->last_frame );
1108 tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
1109 p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
1111 p_new_tcaphash_begincall = append_tcaphash_begincall(p_tcaphash_begincall,
1114 #ifdef DEBUG_TCAPSRT
1115 dbg(12,"Update key %lx ",tcaphash_begin_key.hashKey);
1117 update_tcaphash_begincall(p_new_tcaphash_begincall, pinfo);
1118 p_tcaphash_begincall=p_new_tcaphash_begincall;
1119 } else { /* timeout or message lost */
1121 /* If the Tid is reused for a closed Transaction */
1122 /* Or if we received an TC_BEGIN for a Transaction marked as "closed" */
1123 /* (this is the case, for pre-arranged END, the transaction is marked as closed */
1124 /* by the upper layer, thank to a callback method close) */
1125 if ( p_tcaphash_begincall->context->closed) {
1126 #ifdef DEBUG_TCAPSRT
1127 dbg(12,"(closed) Append key %lu ",tcaphash_begin_key.hashKey);
1128 dbg(12,"Frame %u rsp %u ",pinfo->fd->num,p_tcaphash_begincall->context->last_frame );
1130 tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
1131 p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
1132 p_new_tcaphash_begincall = append_tcaphash_begincall(p_tcaphash_begincall,
1136 #ifdef DEBUG_TCAPSRT
1137 dbg(12,"Update key %lu ",tcaphash_begin_key.hashKey);
1139 update_tcaphash_begincall(p_new_tcaphash_begincall, pinfo);
1140 p_tcaphash_begincall=p_new_tcaphash_begincall;
1143 /* the TCAP session is not closed, so, either messages have been lost */
1144 /* or it's a duplicate request. Mark it as such. */
1145 #ifdef DEBUG_TCAPSRT
1146 dbg(21,"Display_duplicate %d ",p_tcaphash_begincall->context->first_frame);
1148 p_tcaphash_context=p_tcaphash_begincall->context;
1149 if (gtcap_DisplaySRT && tree) {
1150 stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
1151 PROTO_ITEM_SET_GENERATED(stat_item);
1152 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1153 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_Duplicate, tvb, 0, 0,
1154 p_tcaphash_context->first_frame,
1155 "Duplicate with session %u in frame %u",
1156 p_tcaphash_context->session_id,p_tcaphash_context->first_frame);
1157 PROTO_ITEM_SET_GENERATED(pi);
1159 return p_tcaphash_context;
1160 } /* Previous session closed */
1161 } /* test with Timeout or message Lost */
1163 } /* Next call is NULL */
1164 /* Repeat the tests for the next record with the same transaction identifier */
1165 p_tcaphash_begincall = p_tcaphash_begincall->next_begincall;
1166 } while (p_tcaphash_begincall != NULL );
1168 * End of analyze for the list be TC_BEGIN with same transaction ID
1170 } else { /* p_tcaphash_begincall has not been found */
1172 * Create a new TCAP context
1174 #ifdef DEBUG_TCAPSRT
1175 dbg(10,"New key %lx ",tcaphash_begin_key.hashKey);
1178 tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
1179 p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
1180 p_tcaphash_begincall = new_tcaphash_begin(&tcaphash_begin_key, p_tcaphash_context);
1182 #ifdef DEBUG_TCAPSRT
1183 dbg(11,"Update key %lx ",tcaphash_begin_key.hashKey);
1184 dbg(11,"Frame reqlink #%u ", pinfo->fd->num);
1186 update_tcaphash_begincall(p_tcaphash_begincall, pinfo);
1189 /* display tcap session, if available */
1190 if ( gtcap_DisplaySRT && tree &&
1191 p_tcaphash_context &&
1192 p_tcaphash_context->session_id) {
1193 stat_item = proto_tree_add_text(tree, tvb, 0, 0, "Stat");
1194 PROTO_ITEM_SET_GENERATED(stat_item);
1195 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1196 pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
1197 PROTO_ITEM_SET_GENERATED(pi);
1199 /* add link to response frame, if available */
1200 /* p_tcaphash_begincall->context->last_frame) */
1201 if( p_tcaphash_context->last_frame != 0 ){
1202 #ifdef DEBUG_TCAPSRT
1203 dbg(20,"Display_frameRsplink %d ",p_tcaphash_context->last_frame);
1205 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_BeginSession, tvb, 0, 0,
1206 p_tcaphash_context->last_frame,
1207 "End of session in frame %u",
1208 p_tcaphash_context->last_frame);
1209 PROTO_ITEM_SET_GENERATED(pi);
1212 return p_tcaphash_context;
1217 * Try to find a TCAP session according to the source and destination
1218 * Identifier given in the TC_CONT
1219 * If nothing is found, it is probably a session in opening state, so try to find
1220 * a tcap session registered with a TC_BEGIN "key", matching the destination Id of the TC_CONT
1221 * Then associate the TC_CONT "key" to the TCAP context, and create a TC_END "key"
1222 * and display the available info for the TCAP context
1224 static struct tcaphash_context_t *
1225 tcaphash_cont_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1226 struct tcapsrt_info_t *p_tcapsrt_info)
1228 struct tcaphash_context_t *p_tcaphash_context=NULL;
1229 struct tcaphash_contcall_t *p_tcaphash_contcall;
1230 struct tcaphash_cont_info_key_t tcaphash_cont_key;
1231 struct tcaphash_begin_info_key_t tcaphash_begin_key;
1232 struct tcaphash_begincall_t *p_tcaphash_begincall;
1233 struct tcaphash_end_info_key_t tcaphash_end_key;
1234 struct tcaphash_endcall_t *p_tcaphash_endcall;
1236 proto_item *stat_item=NULL;
1237 proto_tree *stat_tree=NULL;
1239 #ifdef DEBUG_TCAPSRT
1240 dbg(10,"\n Hcont #%u ", pinfo->fd->num);
1243 /* look only for matching request, if matching conversation is available. */
1244 tcaphash_cont_key.src_tid = p_tcapsrt_info->src_tid;
1245 tcaphash_cont_key.dst_tid = p_tcapsrt_info->dst_tid;
1246 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1248 /* We have MTP3 PCs (so we can safely do this cast) */
1249 tcaphash_cont_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1250 tcaphash_cont_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1252 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1253 tcaphash_cont_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1254 tcaphash_cont_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1256 tcaphash_cont_key.hashKey=tcaphash_cont_calchash(&tcaphash_cont_key);
1258 #ifdef DEBUG_TCAPSRT
1259 dbg(11,"Ckey %lx ", tcaphash_cont_key.hashKey);
1260 dbg(51,"PC %s %s ",ep_address_to_str(&pinfo->src), ep_address_to_str(&pinfo->dst));
1261 dbg(51,"Tid %lx %lx ",tcaphash_cont_key.src_tid, tcaphash_cont_key.dst_tid);
1263 p_tcaphash_contcall = find_tcaphash_cont(&tcaphash_cont_key, pinfo);
1264 if(p_tcaphash_contcall) {
1265 #ifdef DEBUG_TCAPSRT
1268 p_tcaphash_context=p_tcaphash_contcall->context;
1269 } else { /* cont not found */
1270 #ifdef DEBUG_TCAPSRT
1271 dbg(12,"CnotFound ");
1273 /* Find the TCAP transaction according to the TC_BEGIN */
1274 tcaphash_begin_key.tid = p_tcapsrt_info->dst_tid;
1275 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1277 /* We have MTP3 PCs (so we can safely do this cast) */
1278 tcaphash_begin_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1279 tcaphash_begin_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1281 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1282 tcaphash_begin_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1283 tcaphash_begin_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1285 tcaphash_begin_key.hashKey=tcaphash_begin_calchash(&tcaphash_begin_key);
1287 #ifdef DEBUG_TCAPSRT
1288 dbg(11,"Bkey %lx ", tcaphash_begin_key.hashKey);
1289 dbg(51,"PC %s %s ",ep_address_to_str(&pinfo->src), ep_address_to_str(&pinfo->dst));
1290 dbg(51,"Tid %lx ",tcaphash_begin_key.tid);
1292 p_tcaphash_begincall = find_tcaphash_begin(&tcaphash_begin_key, pinfo,FALSE);
1293 if(p_tcaphash_begincall &&
1294 !p_tcaphash_begincall->context->contcall ) {
1295 #ifdef DEBUG_TCAPSRT
1298 p_tcaphash_context=p_tcaphash_begincall->context;
1299 p_tcaphash_context->responded=TRUE;
1301 #ifdef DEBUG_TCAPSRT
1302 dbg(10,"New Ckey %lx ",tcaphash_cont_key.hashKey);
1303 dbg(11,"Frame reqlink #%u ", pinfo->fd->num);
1305 p_tcaphash_contcall = create_tcaphash_cont(&tcaphash_cont_key,
1306 p_tcaphash_begincall->context);
1308 tcaphash_end_key.tid = p_tcapsrt_info->src_tid;
1309 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1311 /* We have MTP3 PCs (so we can safely do this cast) */
1312 tcaphash_end_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1313 tcaphash_end_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1315 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1316 tcaphash_end_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1317 tcaphash_end_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1319 tcaphash_end_key.hashKey=tcaphash_end_calchash(&tcaphash_end_key);
1321 #ifdef DEBUG_TCAPSRT
1322 dbg(10,"New Ekey %lx ",tcaphash_end_key.hashKey);
1323 dbg(11,"Frame reqlink #%u ", pinfo->fd->num);
1325 p_tcaphash_endcall = create_tcaphash_end(&tcaphash_end_key,
1326 p_tcaphash_begincall->context);
1328 } else { /* Begin not found */
1329 #ifdef DEBUG_TCAPSRT
1330 dbg(12,"BnotFound ");
1334 /* display tcap session, if available */
1335 if (gtcap_DisplaySRT && tree &&
1336 p_tcaphash_context &&
1337 p_tcaphash_context->session_id) {
1338 stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
1339 PROTO_ITEM_SET_GENERATED(stat_item);
1340 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1341 pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
1342 PROTO_ITEM_SET_GENERATED(pi);
1345 return p_tcaphash_context;
1349 * Try to find a TCAP session according to the destination Identifier given in the TC_END/TC_ABORT
1350 * If nothing is found,
1351 * - either it is a session in opening state,
1352 * - or the session is closed/aborted by the remote, ( so we switch the src and dst tid )
1353 * so try to find a tcap session registered with a TC_BEGIN "key",
1354 * matching the destination Id of the TC_END
1355 * Then associate the TC_CONT "key" to the TCAP context
1356 * and display the available info for the TCAP context
1359 static struct tcaphash_context_t *
1360 tcaphash_end_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1361 struct tcapsrt_info_t *p_tcapsrt_info)
1363 struct tcaphash_context_t *p_tcaphash_context=NULL;
1365 struct tcaphash_end_info_key_t tcaphash_end_key;
1366 struct tcaphash_endcall_t *p_tcaphash_endcall=NULL;
1368 struct tcaphash_begin_info_key_t tcaphash_begin_key;
1369 struct tcaphash_begincall_t *p_tcaphash_begincall=NULL;
1372 proto_item *stat_item=NULL;
1373 proto_tree *stat_tree=NULL;
1375 #ifdef DEBUG_TCAPSRT
1376 dbg(10,"\n Hend #%u ", pinfo->fd->num);
1378 /* look only for matching request, if matching conversation is available. */
1379 tcaphash_end_key.tid = p_tcapsrt_info->dst_tid;
1380 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1382 /* We have MTP3 PCs (so we can safely do this cast) */
1383 tcaphash_end_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1384 tcaphash_end_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1386 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1387 tcaphash_end_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1388 tcaphash_end_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1390 tcaphash_end_key.hashKey=tcaphash_end_calchash(&tcaphash_end_key);
1392 #ifdef DEBUG_TCAPSRT
1393 dbg(11,"Ekey %lx ",tcaphash_end_key.hashKey);
1394 dbg(11,"PC %s %s ",ep_address_to_str(&pinfo->src), ep_address_to_str(&pinfo->dst));
1395 dbg(51,"Tid %lx ",tcaphash_end_key.tid);
1397 p_tcaphash_endcall = find_tcaphash_end(&tcaphash_end_key, pinfo,TRUE);
1399 if(!p_tcaphash_endcall) {
1400 #ifdef DEBUG_TCAPSRT
1401 dbg(12,"EnotFound ");
1403 tcaphash_begin_key.tid = p_tcapsrt_info->dst_tid;
1404 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1406 /* We have MTP3 PCs (so we can safely do this cast) */
1407 tcaphash_begin_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1408 tcaphash_begin_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1410 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1411 tcaphash_begin_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1412 tcaphash_begin_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1414 tcaphash_begin_key.hashKey=tcaphash_begin_calchash(&tcaphash_begin_key);
1416 #ifdef DEBUG_TCAPSRT
1417 dbg(11,"Bkey %lx ", tcaphash_begin_key.hashKey);
1418 dbg(51,"PC %s %s ",ep_address_to_str(&pinfo->src), ep_address_to_str(&pinfo->dst));
1419 dbg(51,"Tid %lx ",tcaphash_begin_key.tid);
1421 p_tcaphash_begincall = find_tcaphash_begin(&tcaphash_begin_key, pinfo,FALSE);
1422 if(!p_tcaphash_begincall) {
1423 #ifdef DEBUG_TCAPSRT
1424 dbg(12,"BnotFound ");
1428 if (p_tcaphash_endcall) {
1429 /* Use the TC_BEGIN Destination reference */
1430 p_tcaphash_context=p_tcaphash_endcall->context;
1431 } else if (p_tcaphash_begincall) {
1432 /* Use the TC_BEGIN Source reference */
1433 p_tcaphash_context=p_tcaphash_begincall->context;
1436 if (p_tcaphash_context) {
1438 #ifdef DEBUG_TCAPSRT
1439 dbg(12,"Found, req=%d ",p_tcaphash_context->first_frame);
1441 if (gtcap_DisplaySRT && tree) {
1442 stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
1443 PROTO_ITEM_SET_GENERATED(stat_item);
1444 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1446 pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
1447 PROTO_ITEM_SET_GENERATED(pi);
1450 #ifdef DEBUG_TCAPSRT
1451 dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
1453 /* Indicate the frame to which this is a reply. */
1454 if (gtcap_DisplaySRT && stat_tree) {
1455 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
1456 p_tcaphash_context->first_frame,
1457 "Begin of session in frame %u",
1458 p_tcaphash_context->first_frame);
1459 PROTO_ITEM_SET_GENERATED(pi);
1460 /* Calculate Service Response Time */
1461 nstime_delta(&delta, &pinfo->fd->abs_ts, &p_tcaphash_context->begin_time);
1463 /* display Service Response Time and make it filterable */
1464 pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
1465 PROTO_ITEM_SET_GENERATED(pi);
1467 /* Close the context and remove it (if needed) */
1468 tcapsrt_close(p_tcaphash_context,pinfo);
1470 } else {/* context present */
1471 #ifdef DEBUG_TCAPSRT
1472 dbg(12,"Context notFound ");
1475 return p_tcaphash_context;
1480 * Create the record identifiying the TCAP transaction
1481 * When the identifier for the transaction is reused, check
1482 * the following criteria before to append a new record:
1483 * - a timeout corresponding to a message retransmission is detected,
1484 * - a message hast been lost
1485 * - or the previous transaction has been be closed
1487 static struct tcaphash_context_t *
1488 tcaphash_ansi_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1489 struct tcapsrt_info_t *p_tcapsrt_info)
1491 struct tcaphash_context_t *p_tcaphash_context=NULL;
1492 struct tcaphash_context_key_t tcaphash_context_key;
1493 struct tcaphash_ansicall_t *p_tcaphash_ansicall, *p_new_tcaphash_ansicall;
1494 struct tcaphash_ansi_info_key_t tcaphash_ansi_key;
1497 gboolean isResponse=FALSE;
1498 proto_tree * stat_tree=NULL;
1499 proto_item * stat_item=NULL;
1501 /* prepare the key data */
1502 tcaphash_ansi_key.tid = p_tcapsrt_info->src_tid;
1503 if (pinfo->src.type == AT_SS7PC && pinfo->dst.type == AT_SS7PC)
1505 /* We have MTP3 PCs (so we can safely do this cast) */
1506 tcaphash_ansi_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
1507 tcaphash_ansi_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
1509 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1510 tcaphash_ansi_key.opc_hash = g_str_hash(ep_address_to_str(&pinfo->src));
1511 tcaphash_ansi_key.dpc_hash = g_str_hash(ep_address_to_str(&pinfo->dst));
1513 tcaphash_ansi_key.hashKey=tcaphash_ansi_calchash(&tcaphash_ansi_key);
1515 /* look up the request */
1516 #ifdef DEBUG_TCAPSRT
1517 dbg(10,"\n Hansi #%u ", pinfo->fd->num);
1518 dbg(11,"key %lx ",tcaphash_ansi_key.hashKey);
1519 dbg(51,"PC %s %s ",ep_address_to_str(&pinfo->src), ep_address_to_str(&pinfo->dst));
1520 dbg(51,"Tid %lx ",tcaphash_ansi_key.tid);
1522 p_tcaphash_ansicall = (struct tcaphash_ansicall_t *)
1523 g_hash_table_lookup(tcaphash_ansi, &tcaphash_ansi_key);
1525 if (p_tcaphash_ansicall) {
1526 /* Walk through list of transaction with identical keys */
1528 /* Check if the request with this reqSeqNum has been seen */
1529 if (pinfo->fd->num == p_tcaphash_ansicall->context->first_frame) {
1530 /* We have seen this request before -> do nothing */
1531 #ifdef DEBUG_TCAPSRT
1532 dbg(22,"Request already seen ");
1535 p_tcaphash_context=p_tcaphash_ansicall->context;
1539 /* Check if the reponse with this reqSeqNum has been seen */
1540 if (pinfo->fd->num == p_tcaphash_ansicall->context->last_frame) {
1541 /* We have seen this response before -> do nothing */
1542 #ifdef DEBUG_TCAPSRT
1543 dbg(22,"Response already seen ");
1546 p_tcaphash_context=p_tcaphash_ansicall->context;
1550 /* Check for the first Request without Response
1551 received before this frame */
1552 if ( pinfo->fd->num > p_tcaphash_ansicall->context->first_frame &&
1553 p_tcaphash_ansicall->context->last_frame==0 ) {
1554 /* Take it, and update the context */
1556 #ifdef DEBUG_TCAPSRT
1557 dbg(12,"Update key %lx ",tcaphash_ansi_key.hashKey);
1559 p_tcaphash_ansicall->context->last_frame = pinfo->fd->num;
1560 p_tcaphash_ansicall->context->responded = TRUE;
1561 p_tcaphash_ansicall->context->closed = TRUE;
1562 p_tcaphash_context=p_tcaphash_ansicall->context;
1565 if (gtcap_DisplaySRT && tree) {
1566 stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
1567 PROTO_ITEM_SET_GENERATED(stat_item);
1568 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1570 pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
1571 PROTO_ITEM_SET_GENERATED(pi);
1573 #ifdef DEBUG_TCAPSRT
1574 dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
1576 /* Indicate the frame to which this is a reply. */
1577 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
1578 p_tcaphash_context->first_frame,
1579 "Begin of session in frame %u",
1580 p_tcaphash_context->first_frame);
1581 PROTO_ITEM_SET_GENERATED(pi);
1582 /* Calculate Service Response Time */
1583 nstime_delta(&delta, &pinfo->fd->abs_ts, &p_tcaphash_context->begin_time);
1585 /* display Service Response Time and make it filterable */
1586 pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
1587 PROTO_ITEM_SET_GENERATED(pi);
1590 } /* Lastframe=0, so take it */
1593 /* If the last record for Tcap transaction with identifier has been reached */
1594 if (!p_tcaphash_ansicall->next_ansicall) {
1595 /* check if we have to create a new record or not */
1596 /* if last request has been responded (response number in known)
1597 and this request appears after last response (has bigger frame number)
1598 and last request occured after the timeout for repetition,
1600 if last request hasn't been responded (so number unknown)
1601 and this request appears after last request (has bigger frame number)
1602 and this request occured after the timeout for message lost */
1603 if ( ( p_tcaphash_ansicall->context->last_frame != 0
1604 && pinfo->fd->num > p_tcaphash_ansicall->context->first_frame
1605 && (guint) pinfo->fd->abs_ts.secs > (guint)(p_tcaphash_ansicall->context->begin_time.secs + gtcap_RepetitionTimeout)
1607 ( p_tcaphash_ansicall->context->last_frame == 0
1608 && pinfo->fd->num > p_tcaphash_ansicall->context->first_frame
1609 && (guint)pinfo->fd->abs_ts.secs > (guint)(p_tcaphash_ansicall->context->begin_time.secs + gtcap_LostTimeout)
1613 /* we decide that we have a new request */
1614 /* Append new record to the list */
1615 #ifdef DEBUG_TCAPSRT
1616 dbg(12,"(timeout) Append key %lx ",tcaphash_ansi_key.hashKey);
1617 dbg(12,"Frame %u rsp %u ",pinfo->fd->num,p_tcaphash_ansicall->context->last_frame );
1619 tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
1620 p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
1621 p_new_tcaphash_ansicall = append_tcaphash_ansicall(p_tcaphash_ansicall,
1625 #ifdef DEBUG_TCAPSRT
1626 dbg(12,"Update key %lx ",tcaphash_ansi_key.hashKey);
1628 update_tcaphash_ansicall(p_new_tcaphash_ansicall, pinfo);
1629 p_tcaphash_ansicall=p_new_tcaphash_ansicall;
1632 /* If the Tid is reused for a closed Transaction */
1633 if ( p_tcaphash_ansicall->context->closed) {
1634 #ifdef DEBUG_TCAPSRT
1635 dbg(12,"(closed) Append key %lu ",tcaphash_ansi_key.hashKey);
1636 dbg(12,"Frame %u rsp %u ",pinfo->fd->num,p_tcaphash_ansicall->context->last_frame );
1638 tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
1639 p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
1640 p_new_tcaphash_ansicall = append_tcaphash_ansicall(p_tcaphash_ansicall,
1644 #ifdef DEBUG_TCAPSRT
1645 dbg(12,"Update key %lu ",tcaphash_ansi_key.hashKey);
1647 update_tcaphash_ansicall(p_new_tcaphash_ansicall, pinfo);
1648 p_tcaphash_ansicall=p_new_tcaphash_ansicall;
1651 /* the Tid is reused for an opened Transaction */
1652 /* so, this is the reply to the request of our context */
1653 p_tcaphash_context=p_tcaphash_ansicall->context;
1654 #ifdef DEBUG_TCAPSRT
1655 dbg(12,"Found, req=%d ",p_tcaphash_context->first_frame);
1658 if (gtcap_DisplaySRT && tree) {
1659 stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
1660 PROTO_ITEM_SET_GENERATED(stat_item);
1661 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1663 pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
1664 PROTO_ITEM_SET_GENERATED(pi);
1666 #ifdef DEBUG_TCAPSRT
1667 dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
1669 /* Indicate the frame to which this is a reply. */
1670 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
1671 p_tcaphash_context->first_frame,
1672 "Begin of session in frame %u",
1673 p_tcaphash_context->first_frame);
1674 PROTO_ITEM_SET_GENERATED(pi);
1675 /* Calculate Service Response Time */
1676 nstime_delta(&delta, &pinfo->fd->abs_ts, &p_tcaphash_context->begin_time);
1678 /* display Service Response Time and make it filterable */
1679 pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
1680 PROTO_ITEM_SET_GENERATED(pi);
1682 p_tcaphash_context=p_tcaphash_ansicall->context;
1683 } /* test with Timeout */
1686 } /* Next call is NULL */
1687 p_tcaphash_ansicall = p_tcaphash_ansicall->next_ansicall;
1688 } while (p_tcaphash_ansicall != NULL );
1692 } else { /* p_tcaphash_ansicall has not been found */
1693 #ifdef DEBUG_TCAPSRT
1694 dbg(10,"New key %lx ",tcaphash_ansi_key.hashKey);
1697 tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
1698 p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
1699 p_tcaphash_ansicall = new_tcaphash_ansi(&tcaphash_ansi_key, p_tcaphash_context);
1701 #ifdef DEBUG_TCAPSRT
1702 dbg(11,"Update key %lx ",tcaphash_ansi_key.hashKey);
1703 dbg(11,"Frame reqlink #%u ", pinfo->fd->num);
1705 update_tcaphash_ansicall(p_tcaphash_ansicall, pinfo);
1708 /* display tcap session, if available */
1709 if ( gtcap_DisplaySRT && tree &&
1710 p_tcaphash_context &&
1711 p_tcaphash_context->session_id) {
1712 stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
1713 PROTO_ITEM_SET_GENERATED(stat_item);
1714 stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
1715 pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
1716 PROTO_ITEM_SET_GENERATED(pi);
1720 /* add link to response frame, if available */
1721 if( gtcap_DisplaySRT && stat_tree &&
1722 p_tcaphash_ansicall->context->last_frame != 0){
1723 if (!isResponse) { /* Request */
1724 #ifdef DEBUG_TCAPSRT
1725 dbg(20,"Display_frameRsplink %d ",p_tcaphash_ansicall->context->last_frame);
1727 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_BeginSession, tvb, 0, 0,
1728 p_tcaphash_ansicall->context->last_frame,
1729 "End of session in frame %u",
1730 p_tcaphash_ansicall->context->last_frame);
1731 PROTO_ITEM_SET_GENERATED(pi);
1732 } else { /* Response */
1733 #ifdef DEBUG_TCAPSRT
1734 dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
1736 /* Indicate the frame to which this is a reply. */
1737 if (gtcap_DisplaySRT) {
1738 pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
1739 p_tcaphash_context->first_frame,
1740 "Begin of session in frame %u",
1741 p_tcaphash_context->first_frame);
1742 PROTO_ITEM_SET_GENERATED(pi);
1743 /* Calculate Service Response Time */
1744 nstime_delta(&delta, &pinfo->fd->abs_ts, &p_tcaphash_context->begin_time);
1746 /* display Service Response Time and make it filterable */
1747 pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
1748 PROTO_ITEM_SET_GENERATED(pi);
1750 } /* Request or Response */
1752 return p_tcaphash_context;
1757 * Initialize the Message Info used by the main dissector
1758 * Data are linked to a TCAP transaction
1760 struct tcapsrt_info_t *
1761 tcapsrt_razinfo(void)
1763 struct tcapsrt_info_t *p_tcapsrt_info ;
1765 /* Global buffer for packet extraction */
1766 tcapsrt_global_current++;
1767 if(tcapsrt_global_current==MAX_TCAP_INSTANCE){
1768 tcapsrt_global_current=0;
1771 p_tcapsrt_info=&tcapsrt_global_info[tcapsrt_global_current];
1772 memset(p_tcapsrt_info,0,sizeof(struct tcapsrt_info_t));
1774 return p_tcapsrt_info;
1778 tcapsrt_close(struct tcaphash_context_t *p_tcaphash_context,
1781 #ifdef DEBUG_TCAPSRT
1782 dbg(60,"Force close ");
1784 if (p_tcaphash_context) {
1785 p_tcaphash_context->responded=TRUE;
1786 p_tcaphash_context->last_frame = pinfo->fd->num;
1787 p_tcaphash_context->end_time = pinfo->fd->abs_ts;
1788 p_tcaphash_context->closed=TRUE;
1790 /* If the endkey is present */
1791 if (p_tcaphash_context->endcall
1792 && !gtcap_PersistentSRT) {
1793 if (p_tcaphash_context->endcall->next_endcall) {
1794 if (p_tcaphash_context->endcall->previous_endcall ) {
1795 #ifdef DEBUG_TCAPSRT
1796 dbg(20,"deplace Ehash ");
1798 p_tcaphash_context->endcall->previous_endcall->next_endcall
1799 = p_tcaphash_context->endcall->next_endcall;
1800 p_tcaphash_context->endcall->next_endcall->previous_endcall
1801 = p_tcaphash_context->endcall->previous_endcall;
1802 g_hash_table_remove(tcaphash_end, p_tcaphash_context->endcall->endkey);
1804 g_free(p_tcaphash_context->endcall);
1807 /* cannot remove the father */
1808 #ifdef DEBUG_TCAPSRT
1809 dbg(20,"father Ehash ");
1811 } /* no previous link, so father */
1812 } else if (!gtcap_PersistentSRT) {
1813 #ifdef DEBUG_TCAPSRT
1814 dbg(20,"remove Ehash ");
1816 g_hash_table_remove(tcaphash_end, p_tcaphash_context->endcall->endkey);
1818 g_free(p_tcaphash_context->endcall->endkey);
1819 g_free(p_tcaphash_context->endcall);
1822 } /* endcall without chained string */
1826 /* If the contkey is present */
1827 if (p_tcaphash_context->contcall
1828 && !gtcap_PersistentSRT) {
1829 if (p_tcaphash_context->contcall->next_contcall) {
1830 if (p_tcaphash_context->contcall->previous_contcall ) {
1831 #ifdef DEBUG_TCAPSRT
1832 dbg(20,"deplace Chash ");
1834 p_tcaphash_context->contcall->previous_contcall->next_contcall
1835 = p_tcaphash_context->contcall->next_contcall;
1836 p_tcaphash_context->contcall->next_contcall->previous_contcall
1837 = p_tcaphash_context->contcall->previous_contcall;
1838 g_hash_table_remove(tcaphash_cont, p_tcaphash_context->contcall->contkey);
1840 g_free(p_tcaphash_context->contcall);
1843 /* cannot remove the father */
1844 #ifdef DEBUG_TCAPSRT
1845 dbg(20,"father Chash ");
1847 } /* no previous link, so father */
1848 } else if (!gtcap_PersistentSRT) {
1849 #ifdef DEBUG_TCAPSRT
1850 dbg(20,"remove Chash ");
1852 g_hash_table_remove(tcaphash_cont, p_tcaphash_context->contcall->contkey);
1854 g_free(p_tcaphash_context->contcall->contkey);
1855 g_free(p_tcaphash_context->contcall);
1857 } /* contcall without chained string */
1861 /* If the beginkey is present */
1862 if (p_tcaphash_context->begincall
1863 && !gtcap_PersistentSRT) {
1864 if (p_tcaphash_context->begincall->next_begincall) {
1865 if (p_tcaphash_context->begincall->previous_begincall ) {
1866 #ifdef DEBUG_TCAPSRT
1867 dbg(20,"deplace Bhash ");
1869 p_tcaphash_context->begincall->previous_begincall->next_begincall
1870 = p_tcaphash_context->begincall->next_begincall;
1871 p_tcaphash_context->begincall->next_begincall->previous_begincall
1872 = p_tcaphash_context->begincall->previous_begincall;
1873 g_hash_table_remove(tcaphash_begin, p_tcaphash_context->begincall->beginkey);
1875 g_free(p_tcaphash_context->begincall);
1878 /* cannot remove the father */
1879 #ifdef DEBUG_TCAPSRT
1880 dbg(20,"father Bhash ");
1883 } else if (!gtcap_PersistentSRT) {
1884 #ifdef DEBUG_TCAPSRT
1885 dbg(20,"remove Bhash ");
1887 g_hash_table_remove(tcaphash_begin, p_tcaphash_context->begincall->beginkey);
1889 g_free(p_tcaphash_context->begincall->beginkey);
1890 g_free(p_tcaphash_context->begincall);
1892 } /* begincall without chained string */
1893 } /* no begincall */
1895 /* If the ansikey is present */
1896 if (p_tcaphash_context->ansicall
1897 && !gtcap_PersistentSRT) {
1898 if (p_tcaphash_context->ansicall->next_ansicall) {
1899 if (p_tcaphash_context->ansicall->previous_ansicall ) {
1900 #ifdef DEBUG_TCAPSRT
1901 dbg(20,"deplace Ahash ");
1903 p_tcaphash_context->ansicall->previous_ansicall->next_ansicall
1904 = p_tcaphash_context->ansicall->next_ansicall;
1905 p_tcaphash_context->ansicall->next_ansicall->previous_ansicall
1906 = p_tcaphash_context->ansicall->previous_ansicall;
1907 g_hash_table_remove(tcaphash_ansi, p_tcaphash_context->ansicall->ansikey);
1909 g_free(p_tcaphash_context->ansicall);
1912 /* cannot remove the father */
1913 #ifdef DEBUG_TCAPSRT
1914 dbg(20,"father Ahash ");
1917 } else if (!gtcap_PersistentSRT) {
1918 #ifdef DEBUG_TCAPSRT
1919 dbg(20,"remove Ahash ");
1921 g_hash_table_remove(tcaphash_ansi, p_tcaphash_context->ansicall->ansikey);
1923 g_free(p_tcaphash_context->ansicall->ansikey);
1924 g_free(p_tcaphash_context->ansicall);
1926 } /* ansicall without chained string */
1929 if (!gtcap_PersistentSRT) {
1930 #ifdef DEBUG_TCAPSRT
1931 dbg(20,"remove context ");
1933 g_hash_table_remove(tcaphash_context, p_tcaphash_context->key);
1935 g_free(p_tcaphash_context->key);
1936 g_free(p_tcaphash_context);
1939 } else { /* no context */
1940 #ifdef DEBUG_TCAPSRT
1941 dbg(20,"No context to remove ");