2 * tcap-persistentdata.c
3 * Source for lists and hash tables used in wireshark's tcap dissector
4 * for calculation of delays in tcap-calls
5 * Copyright 2006 Florent Drouin (based on h225-persistentdata.c from Lars Roland)
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 #include <epan/emem.h>
34 #include <epan/packet.h>
35 #include <epan/to_str.h>
36 #include <epan/asn1.h>
37 #include <epan/tcap-persistentdata.h>
38 #include <epan/dissectors/packet-tcap.h>
39 #include <epan/dissectors/packet-mtp3.h>
41 static gint
tcaphash_context_equal(gconstpointer k1
, gconstpointer k2
);
42 static guint
tcaphash_context_calchash(gconstpointer k
);
43 static gint
tcaphash_begin_equal(gconstpointer k1
, gconstpointer k2
);
44 static guint
tcaphash_begin_calchash(gconstpointer k
);
45 static gint
tcaphash_cont_equal(gconstpointer k1
, gconstpointer k2
);
46 static guint
tcaphash_cont_calchash(gconstpointer k
);
47 static gint
tcaphash_end_equal(gconstpointer k1
, gconstpointer k2
);
48 static guint
tcaphash_end_calchash(gconstpointer k
);
49 static gint
tcaphash_ansi_equal(gconstpointer k1
, gconstpointer k2
);
50 static guint
tcaphash_ansi_calchash(gconstpointer k
);
52 static void update_tcaphash_begincall(struct tcaphash_begincall_t
*p_tcaphash_begincall
,
55 static struct tcaphash_begincall_t
*append_tcaphash_begincall(struct tcaphash_begincall_t
*prev_begincall
,
56 struct tcaphash_context_t
*p_tcaphash_context
,
60 static struct tcaphash_begincall_t
*find_tcaphash_begin(struct tcaphash_begin_info_key_t
*p_tcaphash_begin_key
,
65 static struct tcaphash_contcall_t
*find_tcaphash_cont(struct tcaphash_cont_info_key_t
*p_tcaphash_cont_key
,
68 static struct tcaphash_endcall_t
*find_tcaphash_end(struct tcaphash_end_info_key_t
*p_tcaphash_end_key
,
72 static struct tcaphash_context_t
*new_tcaphash_context(struct tcaphash_context_key_t
*p_tcaphash_context_key
,
75 static struct tcaphash_begincall_t
*new_tcaphash_begin(struct tcaphash_begin_info_key_t
*p_tcaphash_begin_key
,
76 struct tcaphash_context_t
*p_tcaphash_context
);
78 static struct tcaphash_contcall_t
*new_tcaphash_cont(struct tcaphash_cont_info_key_t
*p_tcaphash_cont_key
,
79 struct tcaphash_context_t
*p_tcaphash_context
);
81 static struct tcaphash_endcall_t
*new_tcaphash_end(struct tcaphash_end_info_key_t
*p_tcaphash_end_key
,
82 struct tcaphash_context_t
*p_tcaphash_context
);
84 static struct tcaphash_context_t
*tcaphash_begin_matching(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
85 struct tcapsrt_info_t
*p_tcapsrt_info
);
87 static struct tcaphash_context_t
*tcaphash_cont_matching(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
88 struct tcapsrt_info_t
*p_tcapsrt_info
);
90 static struct tcaphash_context_t
*tcaphash_end_matching(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
91 struct tcapsrt_info_t
*p_tcapsrt_info
);
93 static struct tcaphash_context_t
*tcaphash_ansi_matching(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
94 struct tcapsrt_info_t
*p_tcapsrt_info
);
96 struct tcapsrt_info_t
*tcapsrt_razinfo(void);
98 /* When several Tcap components are received in a single TCAP message,
99 we have to use several buffers for the stored parameters
100 because else this data are erased during TAP dissector call */
101 #define MAX_TCAP_INSTANCE 10
102 int tcapsrt_global_current
=0;
103 struct tcapsrt_info_t tcapsrt_global_info
[MAX_TCAP_INSTANCE
];
105 /* These two timeout (in second) are used when some message are lost,
106 or when the same TCAP transcation identifier is reused */
107 guint gtcap_RepetitionTimeout
= 10;
108 guint gtcap_LostTimeout
= 30;
109 extern gboolean gtcap_HandleSRT
;
110 gboolean gtcap_PersistentSRT
=FALSE
;
111 gboolean gtcap_DisplaySRT
=FALSE
;
112 gboolean gtcap_StatSRT
=FALSE
;
114 extern gint ett_tcap_stat
;
116 extern int hf_tcapsrt_SessionId
;
117 extern int hf_tcapsrt_Duplicate
;
118 extern int hf_tcapsrt_BeginSession
;
119 extern int hf_tcapsrt_EndSession
;
120 extern int hf_tcapsrt_SessionTime
;
122 /* Global hash tables*/
123 static GHashTable
*tcaphash_context
= NULL
;
124 static GHashTable
*tcaphash_begin
= NULL
;
125 static GHashTable
*tcaphash_cont
= NULL
;
126 static GHashTable
*tcaphash_end
= NULL
;
127 static GHashTable
*tcaphash_ansi
= NULL
;
129 guint32 tcapsrt_global_SessionId
=1;
135 /* #define MEM_TCAPSRT */
138 /* #define DEBUG_TCAPSRT */
143 static guint debug_level
= 99;
146 dbg(guint level
, char* fmt
, ...)
150 if (level
> debug_level
) return;
152 vfprintf(stderr
, fmt
, ap
);
158 tcaphash_context_equal(gconstpointer k1
, gconstpointer k2
)
160 const struct tcaphash_context_key_t
*key1
= (const struct tcaphash_context_key_t
*) k1
;
161 const struct tcaphash_context_key_t
*key2
= (const struct tcaphash_context_key_t
*) k2
;
163 return (key1
->session_id
== key2
->session_id
);
166 /* calculate a hash key */
168 tcaphash_context_calchash(gconstpointer k
)
170 const struct tcaphash_context_key_t
*key
= (const struct tcaphash_context_key_t
*) k
;
171 return key
->session_id
;
176 tcaphash_begin_equal(gconstpointer k1
, gconstpointer k2
)
178 const struct tcaphash_begin_info_key_t
*key1
= (const struct tcaphash_begin_info_key_t
*) k1
;
179 const struct tcaphash_begin_info_key_t
*key2
= (const struct tcaphash_begin_info_key_t
*) k2
;
181 if (key1
->hashKey
== key2
->hashKey
) {
183 if ( ( (key1
->opc_hash
== key2
->opc_hash
) &&
184 (key1
->dpc_hash
== key2
->dpc_hash
) &&
185 (key1
->tid
== key2
->tid
) )
187 ( (key1
->opc_hash
== key2
->dpc_hash
) &&
188 (key1
->dpc_hash
== key2
->opc_hash
) &&
189 (key1
->tid
== key2
->tid
) )
196 /* calculate a hash key */
198 tcaphash_begin_calchash(gconstpointer k
)
200 const struct tcaphash_begin_info_key_t
*key
= (const struct tcaphash_begin_info_key_t
*) k
;
202 /* hashkey = key->opc_hash<<16 + key->dpc_hash<<8 + key->src_tid; */
208 tcaphash_cont_equal(gconstpointer k1
, gconstpointer k2
)
210 const struct tcaphash_cont_info_key_t
*key1
= (const struct tcaphash_cont_info_key_t
*) k1
;
211 const struct tcaphash_cont_info_key_t
*key2
= (const struct tcaphash_cont_info_key_t
*) k2
;
213 if (key1
->hashKey
== key2
->hashKey
) {
215 if ( (key1
->opc_hash
== key2
->opc_hash
) &&
216 (key1
->dpc_hash
== key2
->dpc_hash
) &&
217 (key1
->src_tid
== key2
->src_tid
) &&
218 (key1
->dst_tid
== key2
->dst_tid
) ) {
221 else if ( (key1
->opc_hash
== key2
->dpc_hash
) &&
222 (key1
->dpc_hash
== key2
->opc_hash
) &&
223 (key1
->src_tid
== key2
->dst_tid
) &&
224 (key1
->dst_tid
== key2
->src_tid
) ) {
231 /* calculate a hash key */
233 tcaphash_cont_calchash(gconstpointer k
)
235 const struct tcaphash_cont_info_key_t
*key
= (const struct tcaphash_cont_info_key_t
*) k
;
237 hashkey
= key
->src_tid
+ key
->dst_tid
;
243 tcaphash_end_equal(gconstpointer k1
, gconstpointer k2
)
245 const struct tcaphash_end_info_key_t
*key1
= (const struct tcaphash_end_info_key_t
*) k1
;
246 const struct tcaphash_end_info_key_t
*key2
= (const struct tcaphash_end_info_key_t
*) k2
;
248 if (key1
->hashKey
== key2
->hashKey
) {
249 if ( ( (key1
->opc_hash
== key2
->opc_hash
) &&
250 (key1
->dpc_hash
== key2
->dpc_hash
) &&
251 (key1
->tid
== key2
->tid
) )
253 ( (key1
->opc_hash
== key2
->dpc_hash
) &&
254 (key1
->dpc_hash
== key2
->opc_hash
) &&
255 (key1
->tid
== key2
->tid
) ) )
261 /* calculate a hash key */
263 tcaphash_end_calchash(gconstpointer k
)
265 const struct tcaphash_end_info_key_t
*key
= (const struct tcaphash_end_info_key_t
*) k
;
272 tcaphash_ansi_equal(gconstpointer k1
, gconstpointer k2
)
274 const struct tcaphash_ansi_info_key_t
*key1
= (const struct tcaphash_ansi_info_key_t
*) k1
;
275 const struct tcaphash_ansi_info_key_t
*key2
= (const struct tcaphash_ansi_info_key_t
*) k2
;
277 if (key1
->hashKey
== key2
->hashKey
) {
279 if ( ( (key1
->opc_hash
== key2
->opc_hash
) &&
280 (key1
->dpc_hash
== key2
->dpc_hash
) &&
281 (key1
->tid
== key2
->tid
) )
283 ( (key1
->opc_hash
== key2
->dpc_hash
) &&
284 (key1
->dpc_hash
== key2
->opc_hash
) &&
285 (key1
->tid
== key2
->tid
) )
292 /* calculate a hash key */
294 tcaphash_ansi_calchash(gconstpointer k
)
296 const struct tcaphash_ansi_info_key_t
*key
= (const struct tcaphash_ansi_info_key_t
*) k
;
298 /* hashkey = key->opc_hash<<16 + key->dpc_hash<<8 + key->src_tid; */
304 * Update a record with the data of the Request
307 update_tcaphash_begincall(struct tcaphash_begincall_t
*p_tcaphash_begincall
,
310 p_tcaphash_begincall
->context
->first_frame
= pinfo
->fd
->num
;
311 p_tcaphash_begincall
->context
->last_frame
= 0;
312 p_tcaphash_begincall
->context
->responded
= FALSE
;
313 p_tcaphash_begincall
->context
->begin_time
= pinfo
->fd
->abs_ts
;
317 * Append a new dialogue, using the same Key, to the chained list
318 * The time is stored too
320 static struct tcaphash_begincall_t
*
321 append_tcaphash_begincall(struct tcaphash_begincall_t
*prev_begincall
,
322 struct tcaphash_context_t
*p_tcaphash_context
,
325 struct tcaphash_begincall_t
*p_new_tcaphash_begincall
= NULL
;
327 /* Append the transaction to the list, when the same key is found
328 This should append when the tcap-transaction Id is reused */
331 p_new_tcaphash_begincall
= (struct tcaphash_begincall_t
*)g_malloc0(sizeof(struct tcaphash_begincall_t
));
333 p_new_tcaphash_begincall
= se_new0(struct tcaphash_begincall_t
);
335 p_new_tcaphash_begincall
->context
=p_tcaphash_context
;
336 p_tcaphash_context
->begincall
=p_new_tcaphash_begincall
;
337 p_new_tcaphash_begincall
->beginkey
=prev_begincall
->beginkey
;
338 p_new_tcaphash_begincall
->context
->first_frame
= pinfo
->fd
->num
;
339 p_new_tcaphash_begincall
->next_begincall
=NULL
;
340 p_new_tcaphash_begincall
->previous_begincall
=prev_begincall
;
341 p_new_tcaphash_begincall
->father
=FALSE
;
344 dbg(10,"+B%d ", p_new_tcaphash_begincall
->context
->session_id
);
346 /* Insert in the chained list */
347 prev_begincall
->next_begincall
= p_new_tcaphash_begincall
;
348 if (prev_begincall
->context
->last_frame
== 0) {
352 prev_begincall
->context
->last_frame
= pinfo
->fd
->num
-1;
354 return p_new_tcaphash_begincall
;
358 * Update a record with the data of the Request
361 update_tcaphash_ansicall(struct tcaphash_ansicall_t
*p_tcaphash_ansicall
,
364 p_tcaphash_ansicall
->context
->first_frame
= pinfo
->fd
->num
;
365 p_tcaphash_ansicall
->context
->last_frame
= 0;
366 p_tcaphash_ansicall
->context
->responded
= FALSE
;
367 p_tcaphash_ansicall
->context
->begin_time
= pinfo
->fd
->abs_ts
;
371 * Append a new dialogue, using the same Key, to the chained list
372 * The time is stored too
374 static struct tcaphash_ansicall_t
*
375 append_tcaphash_ansicall(struct tcaphash_ansicall_t
*prev_ansicall
,
376 struct tcaphash_context_t
*p_tcaphash_context
,
379 struct tcaphash_ansicall_t
*p_new_tcaphash_ansicall
= NULL
;
381 /* Append the transaction to the list, when the same key is found
382 This should append when the tcap-transaction Id is reused */
385 p_new_tcaphash_ansicall
= (struct tcaphash_ansicall_t
*)g_malloc0(sizeof(struct tcaphash_ansicall_t
));
387 p_new_tcaphash_ansicall
= se_new0(struct tcaphash_ansicall_t
);
389 p_new_tcaphash_ansicall
->context
=p_tcaphash_context
;
390 p_tcaphash_context
->ansicall
=p_new_tcaphash_ansicall
;
391 p_new_tcaphash_ansicall
->ansikey
=prev_ansicall
->ansikey
;
392 p_new_tcaphash_ansicall
->context
->first_frame
= pinfo
->fd
->num
;
393 p_new_tcaphash_ansicall
->next_ansicall
=NULL
;
394 p_new_tcaphash_ansicall
->previous_ansicall
=prev_ansicall
;
395 p_new_tcaphash_ansicall
->father
=FALSE
;
398 dbg(10,"+A%d ", p_new_tcaphash_ansicall
->context
->session_id
);
400 /* Insert in the chained list */
401 prev_ansicall
->next_ansicall
= p_new_tcaphash_ansicall
;
402 if (prev_ansicall
->context
->last_frame
== 0) {
406 prev_ansicall
->context
->last_frame
= pinfo
->fd
->num
-1;
408 return p_new_tcaphash_ansicall
;
412 static struct tcaphash_contcall_t
*
413 append_tcaphash_contcall(struct tcaphash_contcall_t
*prev_contcall
,
414 struct tcaphash_context_t
*p_tcaphash_context
)
416 struct tcaphash_contcall_t
*p_new_tcaphash_contcall
= NULL
;
418 /* Append the transaction to the list, when the same key is found
419 This should append when the tcap-transaction Id is reused */
422 p_new_tcaphash_contcall
= (struct tcaphash_contcall_t
*)g_malloc0(sizeof(struct tcaphash_contcall_t
));
424 p_new_tcaphash_contcall
= se_new0(struct tcaphash_contcall_t
);
426 p_new_tcaphash_contcall
->context
=p_tcaphash_context
;
427 p_tcaphash_context
->contcall
=p_new_tcaphash_contcall
;
428 p_new_tcaphash_contcall
->contkey
=prev_contcall
->contkey
;
429 p_new_tcaphash_contcall
->next_contcall
=NULL
;
430 p_new_tcaphash_contcall
->previous_contcall
=prev_contcall
;
431 p_new_tcaphash_contcall
->father
=FALSE
;
434 dbg(10,"+C%d ", p_new_tcaphash_contcall
->context
->session_id
);
436 /* Insert in the chained list */
437 prev_contcall
->next_contcall
= p_new_tcaphash_contcall
;
438 return p_new_tcaphash_contcall
;
442 static struct tcaphash_endcall_t
*
443 append_tcaphash_endcall(struct tcaphash_endcall_t
*prev_endcall
,
444 struct tcaphash_context_t
*p_tcaphash_context
)
446 struct tcaphash_endcall_t
*p_new_tcaphash_endcall
= NULL
;
448 /* Append the transaction to the list, when the same key is found
449 This should append when the tcap-transaction Id is reused */
452 p_new_tcaphash_endcall
= (struct tcaphas_endcall_t
*)g_malloc0(sizeof(struct tcaphash_endcall_t
));
454 p_new_tcaphash_endcall
= se_new0(struct tcaphash_endcall_t
);
456 p_new_tcaphash_endcall
->context
=p_tcaphash_context
;
457 p_tcaphash_context
->endcall
=p_new_tcaphash_endcall
;
458 p_new_tcaphash_endcall
->endkey
=prev_endcall
->endkey
;
459 p_new_tcaphash_endcall
->next_endcall
=NULL
;
460 p_new_tcaphash_endcall
->previous_endcall
=prev_endcall
;
461 p_new_tcaphash_endcall
->father
=FALSE
;
464 dbg(10,"+E%d ", p_new_tcaphash_endcall
->context
->session_id
);
466 /* Insert in the chained list */
467 prev_endcall
->next_endcall
= p_new_tcaphash_endcall
;
468 return p_new_tcaphash_endcall
;
473 * Find the dialog by Key and Time
475 static struct tcaphash_begincall_t
*
476 find_tcaphash_begin(struct tcaphash_begin_info_key_t
*p_tcaphash_begin_key
,
477 packet_info
*pinfo
, gboolean isBegin
)
479 struct tcaphash_begincall_t
*p_tcaphash_begincall
= NULL
;
480 p_tcaphash_begincall
= (struct tcaphash_begincall_t
*)g_hash_table_lookup(tcaphash_begin
, p_tcaphash_begin_key
);
482 if(p_tcaphash_begincall
) {
484 if ( p_tcaphash_begincall
->context
) {
486 pinfo
->fd
->num
== p_tcaphash_begincall
->context
->first_frame
)
489 pinfo
->fd
->num
>= p_tcaphash_begincall
->context
->first_frame
&&
490 ( p_tcaphash_begincall
->context
->last_frame
?pinfo
->fd
->num
<= p_tcaphash_begincall
->context
->last_frame
:1 )
493 /* We have a dialogue, with this key, opened before this request */
495 dbg(10,"B%d ", p_tcaphash_begincall
->context
->session_id
);
497 return p_tcaphash_begincall
;
500 dbg(60,"[B%d] ", p_tcaphash_begincall
->context
->session_id
);
503 /* Break when list end is reached */
504 if(p_tcaphash_begincall
->next_begincall
== NULL
) {
506 dbg(23,"End of Blist ");
510 p_tcaphash_begincall
= p_tcaphash_begincall
->next_begincall
;
511 } while (p_tcaphash_begincall
!= NULL
) ;
514 dbg(23,"Not in Bhash ");
522 static struct tcaphash_contcall_t
*
523 find_tcaphash_cont(struct tcaphash_cont_info_key_t
*p_tcaphash_cont_key
,
526 struct tcaphash_contcall_t
*p_tcaphash_contcall
= NULL
;
527 p_tcaphash_contcall
= (struct tcaphash_contcall_t
*)g_hash_table_lookup(tcaphash_cont
, p_tcaphash_cont_key
);
529 if(p_tcaphash_contcall
) {
531 if ( p_tcaphash_contcall
->context
) {
532 if (pinfo
->fd
->num
>= p_tcaphash_contcall
->context
->first_frame
&&
533 (p_tcaphash_contcall
->context
->last_frame
?pinfo
->fd
->num
<= p_tcaphash_contcall
->context
->last_frame
:1) ) {
534 /* We have a dialogue, with this key, opened before this request */
536 dbg(10,"C%d ", p_tcaphash_contcall
->context
->session_id
);
538 return p_tcaphash_contcall
;
541 dbg(60,"[C%d] ", p_tcaphash_contcall
->context
->session_id
);
544 /* Break when list end is reached */
545 if(p_tcaphash_contcall
->next_contcall
== NULL
) {
547 dbg(23,"End of Clist ");
551 p_tcaphash_contcall
= p_tcaphash_contcall
->next_contcall
;
552 } while (p_tcaphash_contcall
!= NULL
) ;
555 dbg(23,"Not in Chash ");
561 static struct tcaphash_endcall_t
*
562 find_tcaphash_end(struct tcaphash_end_info_key_t
*p_tcaphash_end_key
,
563 packet_info
*pinfo
, gboolean isEnd
)
565 struct tcaphash_endcall_t
*p_tcaphash_endcall
= NULL
;
566 p_tcaphash_endcall
= (struct tcaphash_endcall_t
*)g_hash_table_lookup(tcaphash_end
, p_tcaphash_end_key
);
568 if(p_tcaphash_endcall
) {
570 if ( p_tcaphash_endcall
->context
) {
572 (p_tcaphash_endcall
->context
->last_frame
?pinfo
->fd
->num
== p_tcaphash_endcall
->context
->last_frame
:1)
576 pinfo
->fd
->num
>= p_tcaphash_endcall
->context
->first_frame
&&
577 (p_tcaphash_endcall
->context
->last_frame
?pinfo
->fd
->num
<= p_tcaphash_endcall
->context
->last_frame
:1)
580 /* We have a dialogue, with this key, opened before this request */
582 dbg(10,"E%d ", p_tcaphash_endcall
->context
->session_id
);
584 return p_tcaphash_endcall
;
587 dbg(60,"[E%d] ", p_tcaphash_endcall
->context
->session_id
);
590 /* Break when list end is reached */
591 if(p_tcaphash_endcall
->next_endcall
== NULL
) {
593 dbg(23,"End of Elist ");
597 p_tcaphash_endcall
= p_tcaphash_endcall
->next_endcall
;
598 } while (p_tcaphash_endcall
!= NULL
) ;
601 dbg(23,"Not in Ehash ");
608 * New record to create, to identify a new transaction
610 static struct tcaphash_context_t
*
611 new_tcaphash_context(struct tcaphash_context_key_t
*p_tcaphash_context_key
,
614 struct tcaphash_context_key_t
*p_new_tcaphash_context_key
;
615 struct tcaphash_context_t
*p_new_tcaphash_context
= NULL
;
617 /* Register the transaction in the hash table
618 with the tcap transaction Id as Main Key
619 Once created, this entry will be updated later */
622 p_new_tcaphash_context_key
= (struct tcaphash_context_key_t
*)g_malloc(sizeof(struct tcaphash_context_key_t
));
624 p_new_tcaphash_context_key
= se_new(struct tcaphash_context_key_t
);
626 p_new_tcaphash_context_key
->session_id
= p_tcaphash_context_key
->session_id
;
629 p_new_tcaphash_context
= (struct tcaphash_context_t
*)g_malloc0(sizeof(struct tcaphash_context_t
));
631 p_new_tcaphash_context
= se_new0(struct tcaphash_context_t
);
633 p_new_tcaphash_context
->key
= p_new_tcaphash_context_key
;
634 p_new_tcaphash_context
->session_id
= p_tcaphash_context_key
->session_id
;
635 p_new_tcaphash_context
->first_frame
= pinfo
->fd
->num
;
637 dbg(10,"S%d ", p_new_tcaphash_context
->session_id
);
640 g_hash_table_insert(tcaphash_context
, p_new_tcaphash_context_key
, p_new_tcaphash_context
);
641 return p_new_tcaphash_context
;
645 * New record to create, to identify a new transaction
647 static struct tcaphash_begincall_t
*
648 new_tcaphash_begin(struct tcaphash_begin_info_key_t
*p_tcaphash_begin_key
,
649 struct tcaphash_context_t
*p_tcaphash_context
)
651 struct tcaphash_begin_info_key_t
*p_new_tcaphash_begin_key
;
652 struct tcaphash_begincall_t
*p_new_tcaphash_begincall
= NULL
;
654 /* Register the transaction in the hash table
655 with the tcap transaction Id as Main Key
656 Once created, this entry will be updated later */
659 p_new_tcaphash_begin_key
= (struct tcaphash_begin_info_key_t
*)g_malloc(sizeof(struct tcaphash_begin_info_key_t
));
661 p_new_tcaphash_begin_key
= se_new(struct tcaphash_begin_info_key_t
);
663 p_new_tcaphash_begin_key
->hashKey
= p_tcaphash_begin_key
->hashKey
;
664 p_new_tcaphash_begin_key
->tid
= p_tcaphash_begin_key
->tid
;
665 p_new_tcaphash_begin_key
->opc_hash
= p_tcaphash_begin_key
->opc_hash
;
666 p_new_tcaphash_begin_key
->dpc_hash
= p_tcaphash_begin_key
->dpc_hash
;
669 p_new_tcaphash_begincall
= (struct tcaphash_begincall_t
*)g_malloc0(sizeof(struct tcaphash_begincall_t
));
671 p_new_tcaphash_begincall
= se_new0(struct tcaphash_begincall_t
);
673 p_new_tcaphash_begincall
->beginkey
=p_new_tcaphash_begin_key
;
674 p_new_tcaphash_begincall
->context
=p_tcaphash_context
;
675 p_tcaphash_context
->begincall
=p_new_tcaphash_begincall
;
676 p_new_tcaphash_begincall
->father
=TRUE
;
677 p_new_tcaphash_begincall
->next_begincall
=NULL
;
678 p_new_tcaphash_begincall
->previous_begincall
=NULL
;
681 dbg(10,"B%d ", p_new_tcaphash_begincall
->context
->session_id
);
684 g_hash_table_insert(tcaphash_begin
, p_new_tcaphash_begin_key
, p_new_tcaphash_begincall
);
685 return p_new_tcaphash_begincall
;
691 * New record to create, to identify a new transaction
693 static struct tcaphash_contcall_t
*
694 new_tcaphash_cont(struct tcaphash_cont_info_key_t
*p_tcaphash_cont_key
,
695 struct tcaphash_context_t
*p_tcaphash_context
)
697 struct tcaphash_cont_info_key_t
*p_new_tcaphash_cont_key
;
698 struct tcaphash_contcall_t
*p_new_tcaphash_contcall
= NULL
;
700 /* Register the transaction in the hash table
701 with the tcap transaction Id as Main Key
702 Once created, this entry will be updated later */
705 p_new_tcaphash_cont_key
= (struct tcaphash_cont_info_key_t
*)g_malloc(sizeof(struct tcaphash_cont_info_key_t
));
707 p_new_tcaphash_cont_key
= se_new(struct tcaphash_cont_info_key_t
);
709 p_new_tcaphash_cont_key
->hashKey
= p_tcaphash_cont_key
->hashKey
;
710 p_new_tcaphash_cont_key
->src_tid
= p_tcaphash_cont_key
->src_tid
;
711 p_new_tcaphash_cont_key
->dst_tid
= p_tcaphash_cont_key
->dst_tid
;
712 p_new_tcaphash_cont_key
->opc_hash
= p_tcaphash_cont_key
->opc_hash
;
713 p_new_tcaphash_cont_key
->dpc_hash
= p_tcaphash_cont_key
->dpc_hash
;
716 p_new_tcaphash_contcall
= (struct tcaphash_contcall_t
*)g_malloc0(sizeof(struct tcaphash_contcall_t
));
718 p_new_tcaphash_contcall
= se_new0(struct tcaphash_contcall_t
);
720 p_new_tcaphash_contcall
->contkey
=p_new_tcaphash_cont_key
;
721 p_new_tcaphash_contcall
->context
=p_tcaphash_context
;
722 p_tcaphash_context
->contcall
=p_new_tcaphash_contcall
;
723 p_new_tcaphash_contcall
->father
=TRUE
;
724 p_new_tcaphash_contcall
->next_contcall
=NULL
;
725 p_new_tcaphash_contcall
->previous_contcall
=NULL
;
728 dbg(10,"C%d ", p_new_tcaphash_contcall
->context
->session_id
);
731 g_hash_table_insert(tcaphash_cont
, p_new_tcaphash_cont_key
, p_new_tcaphash_contcall
);
732 return p_new_tcaphash_contcall
;
737 * New record to create, to identify a new transaction
739 static struct tcaphash_endcall_t
*
740 new_tcaphash_end(struct tcaphash_end_info_key_t
*p_tcaphash_end_key
,
741 struct tcaphash_context_t
*p_tcaphash_context
)
743 struct tcaphash_end_info_key_t
*p_new_tcaphash_end_key
;
744 struct tcaphash_endcall_t
*p_new_tcaphash_endcall
= NULL
;
746 /* Register the transaction in the hash table
747 with the tcap transaction Id as Main Key
748 Once created, this entry will be updated later */
751 p_new_tcaphash_end_key
= (struct tcaphash_end_info_key_t
*)g_malloc(sizeof(struct tcaphash_end_info_key_t
));
753 p_new_tcaphash_end_key
= se_new(struct tcaphash_end_info_key_t
);
755 p_new_tcaphash_end_key
->hashKey
= p_tcaphash_end_key
->hashKey
;
756 p_new_tcaphash_end_key
->tid
= p_tcaphash_end_key
->tid
;
757 p_new_tcaphash_end_key
->opc_hash
= p_tcaphash_end_key
->opc_hash
;
758 p_new_tcaphash_end_key
->dpc_hash
= p_tcaphash_end_key
->dpc_hash
;
761 p_new_tcaphash_endcall
= (struct tcaphash_endcall_t
*)g_malloc0(sizeof(struct tcaphash_endcall_t
));
763 p_new_tcaphash_endcall
= se_new0(struct tcaphash_endcall_t
);
765 p_new_tcaphash_endcall
->endkey
=p_new_tcaphash_end_key
;
766 p_new_tcaphash_endcall
->context
=p_tcaphash_context
;
767 p_tcaphash_context
->endcall
=p_new_tcaphash_endcall
;
768 p_new_tcaphash_endcall
->father
=TRUE
;
769 p_new_tcaphash_endcall
->next_endcall
=NULL
;
770 p_new_tcaphash_endcall
->previous_endcall
=NULL
;
773 dbg(10,"E%d ", p_new_tcaphash_endcall
->context
->session_id
);
776 g_hash_table_insert(tcaphash_end
, p_new_tcaphash_end_key
, p_new_tcaphash_endcall
);
777 return p_new_tcaphash_endcall
;
780 * New record to create, to identify a new transaction
782 static struct tcaphash_ansicall_t
*
783 new_tcaphash_ansi(struct tcaphash_ansi_info_key_t
*p_tcaphash_ansi_key
,
784 struct tcaphash_context_t
*p_tcaphash_context
)
786 struct tcaphash_ansi_info_key_t
*p_new_tcaphash_ansi_key
;
787 struct tcaphash_ansicall_t
*p_new_tcaphash_ansicall
= NULL
;
789 /* Register the transaction in the hash table
790 with the tcap transaction Id as Main Key
791 Once created, this entry will be updated later */
794 p_new_tcaphash_ansi_key
= (struct tcaphash_ansi_info_key_t
*)g_malloc(sizeof(struct tcaphash_ansi_info_key_t
));
796 p_new_tcaphash_ansi_key
= se_new(struct tcaphash_ansi_info_key_t
);
798 p_new_tcaphash_ansi_key
->hashKey
= p_tcaphash_ansi_key
->hashKey
;
799 p_new_tcaphash_ansi_key
->tid
= p_tcaphash_ansi_key
->tid
;
800 p_new_tcaphash_ansi_key
->opc_hash
= p_tcaphash_ansi_key
->opc_hash
;
801 p_new_tcaphash_ansi_key
->dpc_hash
= p_tcaphash_ansi_key
->dpc_hash
;
804 p_new_tcaphash_ansicall
= (struct tcaphash_ansicall_t
*)g_malloc0(sizeof(struct tcaphash_ansicall_t
));
806 p_new_tcaphash_ansicall
= se_new0(struct tcaphash_ansicall_t
);
808 p_new_tcaphash_ansicall
->ansikey
=p_new_tcaphash_ansi_key
;
809 p_new_tcaphash_ansicall
->context
=p_tcaphash_context
;
810 p_tcaphash_context
->ansicall
=p_new_tcaphash_ansicall
;
811 p_new_tcaphash_ansicall
->father
=TRUE
;
812 p_new_tcaphash_ansicall
->next_ansicall
=NULL
;
813 p_new_tcaphash_ansicall
->previous_ansicall
=NULL
;
816 dbg(10,"A%d ", p_new_tcaphash_ansicall
->context
->session_id
);
819 g_hash_table_insert(tcaphash_ansi
, p_new_tcaphash_ansi_key
, p_new_tcaphash_ansicall
);
820 return p_new_tcaphash_ansicall
;
823 static struct tcaphash_contcall_t
*
824 create_tcaphash_cont(struct tcaphash_cont_info_key_t
*p_tcaphash_cont_key
,
825 struct tcaphash_context_t
*p_tcaphash_context
)
827 struct tcaphash_contcall_t
*p_tcaphash_contcall1
= NULL
;
828 struct tcaphash_contcall_t
*p_tcaphash_contcall
= NULL
;
830 p_tcaphash_contcall1
= (struct tcaphash_contcall_t
*)
831 g_hash_table_lookup(tcaphash_cont
, p_tcaphash_cont_key
);
833 if (p_tcaphash_contcall1
) {
834 /* Walk through list of transaction with identical keys */
835 /* go the the end to insert new record */
837 if (!p_tcaphash_contcall1
->next_contcall
) {
838 p_tcaphash_contcall
=append_tcaphash_contcall(p_tcaphash_contcall1
,
842 p_tcaphash_contcall1
= p_tcaphash_contcall1
->next_contcall
;
843 } while (p_tcaphash_contcall1
!= NULL
);
845 p_tcaphash_contcall
= new_tcaphash_cont(p_tcaphash_cont_key
,
848 return p_tcaphash_contcall
;
852 static struct tcaphash_endcall_t
*
853 create_tcaphash_end(struct tcaphash_end_info_key_t
*p_tcaphash_end_key
,
854 struct tcaphash_context_t
*p_tcaphash_context
)
856 struct tcaphash_endcall_t
*p_tcaphash_endcall1
= NULL
;
857 struct tcaphash_endcall_t
*p_tcaphash_endcall
= NULL
;
859 p_tcaphash_endcall1
= (struct tcaphash_endcall_t
*)
860 g_hash_table_lookup(tcaphash_end
, p_tcaphash_end_key
);
862 if (p_tcaphash_endcall1
) {
863 /* Walk through list of transaction with identical keys */
864 /* go the the end to insert new record */
866 if (!p_tcaphash_endcall1
->next_endcall
) {
867 p_tcaphash_endcall
=append_tcaphash_endcall(p_tcaphash_endcall1
,
871 p_tcaphash_endcall1
= p_tcaphash_endcall1
->next_endcall
;
872 } while (p_tcaphash_endcall1
!= NULL
);
874 p_tcaphash_endcall
= new_tcaphash_end(p_tcaphash_end_key
,
877 return p_tcaphash_endcall
;
882 * Routine called when the TAP is initialized.
883 * so hash table are (re)created
886 tcapsrt_init_routine(void)
889 /* free hash-table for SRT */
890 if (tcaphash_context
!= NULL
) {
892 dbg(16,"Destroy hash_context \n");
894 g_hash_table_destroy(tcaphash_context
);
897 if (tcaphash_begin
!= NULL
) {
899 dbg(16,"Destroy hash_begin \n");
901 g_hash_table_destroy(tcaphash_begin
);
904 if (tcaphash_cont
!= NULL
) {
906 dbg(16,"Destroy hash_cont \n");
908 g_hash_table_destroy(tcaphash_cont
);
911 if (tcaphash_end
!= NULL
) {
913 dbg(16,"Destroy hash_end \n");
915 g_hash_table_destroy(tcaphash_end
);
918 if (tcaphash_ansi
!= NULL
) {
920 dbg(16,"Destroy hash_ansi \n");
922 g_hash_table_destroy(tcaphash_ansi
);
926 dbg(16,"Create hash \n");
928 /* create new hash-tables for SRT */
929 tcaphash_context
= g_hash_table_new(tcaphash_context_calchash
, tcaphash_context_equal
);
930 tcaphash_begin
= g_hash_table_new(tcaphash_begin_calchash
, tcaphash_begin_equal
);
931 tcaphash_cont
= g_hash_table_new(tcaphash_cont_calchash
, tcaphash_cont_equal
);
932 tcaphash_end
= g_hash_table_new(tcaphash_end_calchash
, tcaphash_end_equal
);
933 tcaphash_ansi
= g_hash_table_new(tcaphash_ansi_calchash
, tcaphash_ansi_equal
);
935 /* Reset the session counter */
936 tcapsrt_global_SessionId
=1;
938 /* Display of SRT only if Persistent Stat */
939 gtcap_DisplaySRT
=gtcap_PersistentSRT
|| gtcap_HandleSRT
>cap_StatSRT
;
943 * Service Response Time analyze
944 * Called just after dissector call
945 * Associate a TCAP context to a tcap session and display session related infomations
946 * like the first frame, the last, the session duration,
947 * and a uniq session identifier for the filtering
949 * For ETSI tcap, the TCAP context can be reached through three keys
950 * - a key (BEGIN) identifying the session according to the tcap source identifier
951 * - a key (CONT) identifying the established session (src_id and dst_id)
952 * - a key (END) identifying the session according to the tcap destination identifier
954 * For ANSI tcap, the TCAP context is reached through a uniq key
955 * - a key (ANSI) identifying the session according to the tcap identifier
957 struct tcaphash_context_t
*
958 tcapsrt_call_matching(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
959 struct tcapsrt_info_t
*p_tcapsrt_info
)
961 struct tcaphash_context_t
*tcap_context
=NULL
;
963 /* if this packet isn't loaded because of a read filter, don't output anything */
964 if(pinfo
== NULL
|| pinfo
->fd
->num
== 0) {
968 switch (p_tcapsrt_info
->ope
) {
972 dbg(1,"\nTC_BEGIN ");
974 tcap_context
=tcaphash_begin_matching(tvb
, pinfo
, tree
, p_tcapsrt_info
);
981 tcap_context
=tcaphash_cont_matching(tvb
, pinfo
, tree
, p_tcapsrt_info
);
986 dbg(1,"\nTC_ABORT ");
988 tcap_context
=tcaphash_end_matching(tvb
, pinfo
, tree
, p_tcapsrt_info
);
995 tcap_context
=tcaphash_end_matching(tvb
, pinfo
, tree
, p_tcapsrt_info
);
1000 #ifdef DEBUG_TCAPSRT
1001 dbg(1,"\nTC_ANSI ");
1003 tcap_context
=tcaphash_ansi_matching(tvb
, pinfo
, tree
, p_tcapsrt_info
);
1007 #ifdef DEBUG_TCAPSRT
1008 dbg(1,"\nUnknown %d ", p_tcapsrt_info
->ope
);
1011 } /* switch tcapop */
1012 #ifdef DEBUG_TCAPSRT
1014 dbg(1,"session %d ", tcap_context
->session_id
);
1016 return tcap_context
;
1021 * Create the record identifiying the TCAP transaction
1022 * When the identifier for the transaction is reused, check
1023 * the following criteria before to append a new record:
1024 * - a timeout corresponding to a message retransmission is detected,
1025 * - a message hast been lost
1026 * - or the previous transaction has been be closed
1028 static struct tcaphash_context_t
*
1029 tcaphash_begin_matching(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1030 struct tcapsrt_info_t
*p_tcapsrt_info
)
1032 struct tcaphash_context_t
*p_tcaphash_context
=NULL
;
1033 struct tcaphash_context_key_t tcaphash_context_key
;
1034 struct tcaphash_begincall_t
*p_tcaphash_begincall
, *p_new_tcaphash_begincall
=NULL
;
1035 struct tcaphash_begin_info_key_t tcaphash_begin_key
;
1037 proto_item
*stat_item
=NULL
;
1038 proto_tree
*stat_tree
=NULL
;
1040 /* prepare the key data */
1041 tcaphash_begin_key
.tid
= p_tcapsrt_info
->src_tid
;
1042 if (pinfo
->src
.type
== AT_SS7PC
&& pinfo
->dst
.type
== AT_SS7PC
)
1044 /* We have MTP3 PCs (so we can safely do this cast) */
1045 tcaphash_begin_key
.opc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)pinfo
->src
.data
);
1046 tcaphash_begin_key
.dpc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)pinfo
->dst
.data
);
1048 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1049 tcaphash_begin_key
.opc_hash
= g_str_hash(ep_address_to_str(&pinfo
->src
));
1050 tcaphash_begin_key
.dpc_hash
= g_str_hash(ep_address_to_str(&pinfo
->dst
));
1052 tcaphash_begin_key
.hashKey
=tcaphash_begin_calchash(&tcaphash_begin_key
);
1054 /* look up the request */
1055 #ifdef DEBUG_TCAPSRT
1056 dbg(10,"\n Hbegin #%u ", pinfo
->fd
->num
);
1057 dbg(11,"key %lx ",tcaphash_begin_key
.hashKey
);
1058 dbg(51,"PC %s %s ",ep_address_to_str(&pinfo
->src
), ep_address_to_str(&pinfo
->dst
));
1059 dbg(51,"Tid %lx \n",tcaphash_begin_key
.tid
);
1062 p_tcaphash_begincall
= (struct tcaphash_begincall_t
*)
1063 g_hash_table_lookup(tcaphash_begin
, &tcaphash_begin_key
);
1065 if (p_tcaphash_begincall
) {
1066 /* Walk through list of transaction with identical keys */
1068 /* Check if the request with this reqSeqNum has been seen, with the same Message Type */
1069 if (pinfo
->fd
->num
== p_tcaphash_begincall
->context
->first_frame
) {
1070 /* We have seen this request before -> do nothing */
1071 #ifdef DEBUG_TCAPSRT
1072 dbg(22,"Already seen ");
1074 p_tcaphash_context
=p_tcaphash_begincall
->context
;
1077 /* If the last record for Tcap transaction with identifier has not been reached */
1078 if (!p_tcaphash_begincall
->next_begincall
) {
1079 /* check if we have to create a new record or not */
1080 /* if last request has been responded (response number is known)
1081 and this request appears after last response (has bigger frame number)
1082 and last request occurred after the timeout for repetition,
1084 if last request hasn't been responded (so number unknown)
1085 and this request appears after last request (has bigger frame number)
1086 and this request occurred after the timeout for message lost */
1087 if ( ( p_tcaphash_begincall
->context
->last_frame
!= 0
1088 && pinfo
->fd
->num
> p_tcaphash_begincall
->context
->first_frame
1089 && (guint
) pinfo
->fd
->abs_ts
.secs
> (guint
)(p_tcaphash_begincall
->context
->begin_time
.secs
+ gtcap_RepetitionTimeout
)
1091 ( 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_LostTimeout
)
1097 /* we decide that we have a new request */
1098 /* Append new record to the list */
1099 #ifdef DEBUG_TCAPSRT
1100 dbg(12,"(timeout) Append key %lx ",tcaphash_begin_key
.hashKey
);
1101 dbg(12,"Frame %u rsp %u ",pinfo
->fd
->num
,p_tcaphash_begincall
->context
->last_frame
);
1103 tcaphash_context_key
.session_id
= tcapsrt_global_SessionId
++;
1104 p_tcaphash_context
= new_tcaphash_context(&tcaphash_context_key
, pinfo
);
1106 p_new_tcaphash_begincall
= append_tcaphash_begincall(p_tcaphash_begincall
,
1109 #ifdef DEBUG_TCAPSRT
1110 dbg(12,"Update key %lx ",tcaphash_begin_key
.hashKey
);
1112 update_tcaphash_begincall(p_new_tcaphash_begincall
, pinfo
);
1113 } else { /* timeout or message lost */
1115 /* If the Tid is reused for a closed Transaction */
1116 /* Or if we received an TC_BEGIN for a Transaction marked as "closed" */
1117 /* (this is the case, for pre-arranged END, the transaction is marked as closed */
1118 /* by the upper layer, thank to a callback method close) */
1119 if ( p_tcaphash_begincall
->context
->closed
) {
1120 #ifdef DEBUG_TCAPSRT
1121 dbg(12,"(closed) Append key %lu ",tcaphash_begin_key
.hashKey
);
1122 dbg(12,"Frame %u rsp %u ",pinfo
->fd
->num
,p_tcaphash_begincall
->context
->last_frame
);
1124 tcaphash_context_key
.session_id
= tcapsrt_global_SessionId
++;
1125 p_tcaphash_context
= new_tcaphash_context(&tcaphash_context_key
, pinfo
);
1126 p_new_tcaphash_begincall
= append_tcaphash_begincall(p_tcaphash_begincall
,
1130 #ifdef DEBUG_TCAPSRT
1131 dbg(12,"Update key %lu ",tcaphash_begin_key
.hashKey
);
1133 update_tcaphash_begincall(p_new_tcaphash_begincall
, pinfo
);
1136 /* the TCAP session is not closed, so, either messages have been lost */
1137 /* or it's a duplicate request. Mark it as such. */
1138 #ifdef DEBUG_TCAPSRT
1139 dbg(21,"Display_duplicate %d ",p_tcaphash_begincall
->context
->first_frame
);
1141 p_tcaphash_context
=p_tcaphash_begincall
->context
;
1142 if (gtcap_DisplaySRT
&& tree
) {
1143 stat_item
= proto_tree_add_text(tree
, tvb
, 0, -1, "Stat");
1144 PROTO_ITEM_SET_GENERATED(stat_item
);
1145 stat_tree
= proto_item_add_subtree(stat_item
, ett_tcap_stat
);
1146 pi
= proto_tree_add_uint_format(stat_tree
, hf_tcapsrt_Duplicate
, tvb
, 0, 0,
1147 p_tcaphash_context
->first_frame
,
1148 "Duplicate with session %u in frame %u",
1149 p_tcaphash_context
->session_id
,p_tcaphash_context
->first_frame
);
1150 PROTO_ITEM_SET_GENERATED(pi
);
1152 return p_tcaphash_context
;
1153 } /* Previous session closed */
1154 } /* test with Timeout or message Lost */
1156 } /* Next call is NULL */
1157 /* Repeat the tests for the next record with the same transaction identifier */
1158 p_tcaphash_begincall
= p_tcaphash_begincall
->next_begincall
;
1159 } while (p_tcaphash_begincall
!= NULL
);
1161 * End of analyze for the list be TC_BEGIN with same transaction ID
1163 } else { /* p_tcaphash_begincall has not been found */
1165 * Create a new TCAP context
1167 #ifdef DEBUG_TCAPSRT
1168 dbg(10,"New key %lx ",tcaphash_begin_key
.hashKey
);
1171 tcaphash_context_key
.session_id
= tcapsrt_global_SessionId
++;
1172 p_tcaphash_context
= new_tcaphash_context(&tcaphash_context_key
, pinfo
);
1173 p_tcaphash_begincall
= new_tcaphash_begin(&tcaphash_begin_key
, p_tcaphash_context
);
1175 #ifdef DEBUG_TCAPSRT
1176 dbg(11,"Update key %lx ",tcaphash_begin_key
.hashKey
);
1177 dbg(11,"Frame reqlink #%u ", pinfo
->fd
->num
);
1179 update_tcaphash_begincall(p_tcaphash_begincall
, pinfo
);
1182 /* display tcap session, if available */
1183 if ( gtcap_DisplaySRT
&& tree
&&
1184 p_tcaphash_context
&&
1185 p_tcaphash_context
->session_id
) {
1186 stat_item
= proto_tree_add_text(tree
, tvb
, 0, 0, "Stat");
1187 PROTO_ITEM_SET_GENERATED(stat_item
);
1188 stat_tree
= proto_item_add_subtree(stat_item
, ett_tcap_stat
);
1189 pi
= proto_tree_add_uint(stat_tree
, hf_tcapsrt_SessionId
, tvb
, 0,0, p_tcaphash_context
->session_id
);
1190 PROTO_ITEM_SET_GENERATED(pi
);
1192 /* add link to response frame, if available */
1193 /* p_tcaphash_begincall->context->last_frame) */
1194 if( p_tcaphash_context
->last_frame
!= 0 ){
1195 #ifdef DEBUG_TCAPSRT
1196 dbg(20,"Display_frameRsplink %d ",p_tcaphash_context
->last_frame
);
1198 pi
= proto_tree_add_uint_format(stat_tree
, hf_tcapsrt_BeginSession
, tvb
, 0, 0,
1199 p_tcaphash_context
->last_frame
,
1200 "End of session in frame %u",
1201 p_tcaphash_context
->last_frame
);
1202 PROTO_ITEM_SET_GENERATED(pi
);
1205 return p_tcaphash_context
;
1210 * Try to find a TCAP session according to the source and destination
1211 * Identifier given in the TC_CONT
1212 * If nothing is found, it is probably a session in opening state, so try to find
1213 * a tcap session registered with a TC_BEGIN "key", matching the destination Id of the TC_CONT
1214 * Then associate the TC_CONT "key" to the TCAP context, and create a TC_END "key"
1215 * and display the available info for the TCAP context
1217 static struct tcaphash_context_t
*
1218 tcaphash_cont_matching(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1219 struct tcapsrt_info_t
*p_tcapsrt_info
)
1221 struct tcaphash_context_t
*p_tcaphash_context
=NULL
;
1222 struct tcaphash_contcall_t
*p_tcaphash_contcall
;
1223 struct tcaphash_cont_info_key_t tcaphash_cont_key
;
1224 struct tcaphash_begin_info_key_t tcaphash_begin_key
;
1225 struct tcaphash_begincall_t
*p_tcaphash_begincall
;
1226 struct tcaphash_end_info_key_t tcaphash_end_key
;
1228 proto_item
*stat_item
=NULL
;
1229 proto_tree
*stat_tree
=NULL
;
1231 #ifdef DEBUG_TCAPSRT
1232 dbg(10,"\n Hcont #%u ", pinfo
->fd
->num
);
1235 /* look only for matching request, if matching conversation is available. */
1236 tcaphash_cont_key
.src_tid
= p_tcapsrt_info
->src_tid
;
1237 tcaphash_cont_key
.dst_tid
= p_tcapsrt_info
->dst_tid
;
1238 if (pinfo
->src
.type
== AT_SS7PC
&& pinfo
->dst
.type
== AT_SS7PC
)
1240 /* We have MTP3 PCs (so we can safely do this cast) */
1241 tcaphash_cont_key
.opc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)pinfo
->src
.data
);
1242 tcaphash_cont_key
.dpc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)pinfo
->dst
.data
);
1244 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1245 tcaphash_cont_key
.opc_hash
= g_str_hash(ep_address_to_str(&pinfo
->src
));
1246 tcaphash_cont_key
.dpc_hash
= g_str_hash(ep_address_to_str(&pinfo
->dst
));
1248 tcaphash_cont_key
.hashKey
=tcaphash_cont_calchash(&tcaphash_cont_key
);
1250 #ifdef DEBUG_TCAPSRT
1251 dbg(11,"Ckey %lx ", tcaphash_cont_key
.hashKey
);
1252 dbg(51,"PC %s %s ",ep_address_to_str(&pinfo
->src
), ep_address_to_str(&pinfo
->dst
));
1253 dbg(51,"Tid %lx %lx \n",tcaphash_cont_key
.src_tid
, tcaphash_cont_key
.dst_tid
);
1255 p_tcaphash_contcall
= find_tcaphash_cont(&tcaphash_cont_key
, pinfo
);
1256 if(p_tcaphash_contcall
) {
1257 #ifdef DEBUG_TCAPSRT
1260 p_tcaphash_context
=p_tcaphash_contcall
->context
;
1261 } else { /* cont not found */
1262 #ifdef DEBUG_TCAPSRT
1263 dbg(12,"CnotFound ");
1265 /* Find the TCAP transaction according to the TC_BEGIN */
1266 tcaphash_begin_key
.tid
= p_tcapsrt_info
->dst_tid
;
1267 if (pinfo
->src
.type
== AT_SS7PC
&& pinfo
->dst
.type
== AT_SS7PC
)
1269 /* We have MTP3 PCs (so we can safely do this cast) */
1270 tcaphash_begin_key
.opc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)pinfo
->src
.data
);
1271 tcaphash_begin_key
.dpc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)pinfo
->dst
.data
);
1273 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1274 tcaphash_begin_key
.opc_hash
= g_str_hash(ep_address_to_str(&pinfo
->src
));
1275 tcaphash_begin_key
.dpc_hash
= g_str_hash(ep_address_to_str(&pinfo
->dst
));
1277 tcaphash_begin_key
.hashKey
=tcaphash_begin_calchash(&tcaphash_begin_key
);
1279 #ifdef DEBUG_TCAPSRT
1280 dbg(11,"Bkey %lx ", tcaphash_begin_key
.hashKey
);
1281 dbg(51,"PC %s %s ",ep_address_to_str(&pinfo
->src
), ep_address_to_str(&pinfo
->dst
));
1282 dbg(51,"Tid %lx \n",tcaphash_begin_key
.tid
);
1284 p_tcaphash_begincall
= find_tcaphash_begin(&tcaphash_begin_key
, pinfo
, FALSE
);
1285 if(!p_tcaphash_begincall
){
1286 /* Do we have a continue from the same source? */
1287 tcaphash_begin_key
.tid
= p_tcapsrt_info
->src_tid
;
1288 tcaphash_begin_key
.hashKey
=tcaphash_begin_calchash(&tcaphash_begin_key
);
1289 p_tcaphash_begincall
= find_tcaphash_begin(&tcaphash_begin_key
, pinfo
,FALSE
);
1291 if(p_tcaphash_begincall
&&
1292 !p_tcaphash_begincall
->context
->contcall
) {
1293 #ifdef DEBUG_TCAPSRT
1294 dbg(12,"BFound \n");
1296 p_tcaphash_context
=p_tcaphash_begincall
->context
;
1297 p_tcaphash_context
->responded
=TRUE
;
1299 #ifdef DEBUG_TCAPSRT
1300 dbg(10,"New Ckey %lx ",tcaphash_cont_key
.hashKey
);
1301 dbg(11,"Frame reqlink #%u \n", pinfo
->fd
->num
);
1303 create_tcaphash_cont(&tcaphash_cont_key
,
1304 p_tcaphash_begincall
->context
);
1306 tcaphash_end_key
.tid
= p_tcapsrt_info
->src_tid
;
1307 if (pinfo
->src
.type
== AT_SS7PC
&& pinfo
->dst
.type
== AT_SS7PC
)
1309 /* We have MTP3 PCs (so we can safely do this cast) */
1310 tcaphash_end_key
.opc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)pinfo
->src
.data
);
1311 tcaphash_end_key
.dpc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)pinfo
->dst
.data
);
1313 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1314 tcaphash_end_key
.opc_hash
= g_str_hash(ep_address_to_str(&pinfo
->src
));
1315 tcaphash_end_key
.dpc_hash
= g_str_hash(ep_address_to_str(&pinfo
->dst
));
1317 tcaphash_end_key
.hashKey
=tcaphash_end_calchash(&tcaphash_end_key
);
1319 #ifdef DEBUG_TCAPSRT
1320 dbg(10,"New Ekey %lx ",tcaphash_end_key
.hashKey
);
1321 dbg(11,"Frame reqlink #%u ", pinfo
->fd
->num
);
1323 create_tcaphash_end(&tcaphash_end_key
,
1324 p_tcaphash_begincall
->context
);
1326 } else { /* Begin not found */
1327 #ifdef DEBUG_TCAPSRT
1328 dbg(12,"BnotFound ");
1332 /* display tcap session, if available */
1333 if (gtcap_DisplaySRT
&& tree
&&
1334 p_tcaphash_context
&&
1335 p_tcaphash_context
->session_id
) {
1336 stat_item
= proto_tree_add_text(tree
, tvb
, 0, -1, "Stat");
1337 PROTO_ITEM_SET_GENERATED(stat_item
);
1338 stat_tree
= proto_item_add_subtree(stat_item
, ett_tcap_stat
);
1339 pi
= proto_tree_add_uint(stat_tree
, hf_tcapsrt_SessionId
, tvb
, 0,0, p_tcaphash_context
->session_id
);
1340 PROTO_ITEM_SET_GENERATED(pi
);
1343 return p_tcaphash_context
;
1347 * Try to find a TCAP session according to the destination Identifier given in the TC_END/TC_ABORT
1348 * If nothing is found,
1349 * - either it is a session in opening state,
1350 * - or the session is closed/aborted by the remote, ( so we switch the src and dst tid )
1351 * so try to find a tcap session registered with a TC_BEGIN "key",
1352 * matching the destination Id of the TC_END
1353 * Then associate the TC_CONT "key" to the TCAP context
1354 * and display the available info for the TCAP context
1357 static struct tcaphash_context_t
*
1358 tcaphash_end_matching(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1359 struct tcapsrt_info_t
*p_tcapsrt_info
)
1361 struct tcaphash_context_t
*p_tcaphash_context
=NULL
;
1363 struct tcaphash_end_info_key_t tcaphash_end_key
;
1364 struct tcaphash_endcall_t
*p_tcaphash_endcall
=NULL
;
1366 struct tcaphash_begin_info_key_t tcaphash_begin_key
;
1367 struct tcaphash_begincall_t
*p_tcaphash_begincall
=NULL
;
1370 proto_item
*stat_item
=NULL
;
1371 proto_tree
*stat_tree
=NULL
;
1373 #ifdef DEBUG_TCAPSRT
1374 dbg(10,"\n Hend #%u ", pinfo
->fd
->num
);
1376 /* look only for matching request, if matching conversation is available. */
1377 tcaphash_end_key
.tid
= p_tcapsrt_info
->dst_tid
;
1378 if (pinfo
->src
.type
== AT_SS7PC
&& pinfo
->dst
.type
== AT_SS7PC
)
1380 /* We have MTP3 PCs (so we can safely do this cast) */
1381 tcaphash_end_key
.opc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)pinfo
->src
.data
);
1382 tcaphash_end_key
.dpc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)pinfo
->dst
.data
);
1384 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1385 tcaphash_end_key
.opc_hash
= g_str_hash(ep_address_to_str(&pinfo
->src
));
1386 tcaphash_end_key
.dpc_hash
= g_str_hash(ep_address_to_str(&pinfo
->dst
));
1388 tcaphash_end_key
.hashKey
=tcaphash_end_calchash(&tcaphash_end_key
);
1390 #ifdef DEBUG_TCAPSRT
1391 dbg(11,"Ekey %lx ",tcaphash_end_key
.hashKey
);
1392 dbg(11,"PC %s %s ",ep_address_to_str(&pinfo
->src
), ep_address_to_str(&pinfo
->dst
));
1393 dbg(51,"Tid %lx ",tcaphash_end_key
.tid
);
1395 p_tcaphash_endcall
= find_tcaphash_end(&tcaphash_end_key
, pinfo
,TRUE
);
1397 if(!p_tcaphash_endcall
) {
1398 #ifdef DEBUG_TCAPSRT
1399 dbg(12,"EnotFound ");
1401 tcaphash_begin_key
.tid
= p_tcapsrt_info
->dst_tid
;
1402 if (pinfo
->src
.type
== AT_SS7PC
&& pinfo
->dst
.type
== AT_SS7PC
)
1404 /* We have MTP3 PCs (so we can safely do this cast) */
1405 tcaphash_begin_key
.opc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)pinfo
->src
.data
);
1406 tcaphash_begin_key
.dpc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)pinfo
->dst
.data
);
1408 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1409 tcaphash_begin_key
.opc_hash
= g_str_hash(ep_address_to_str(&pinfo
->src
));
1410 tcaphash_begin_key
.dpc_hash
= g_str_hash(ep_address_to_str(&pinfo
->dst
));
1412 tcaphash_begin_key
.hashKey
=tcaphash_begin_calchash(&tcaphash_begin_key
);
1414 #ifdef DEBUG_TCAPSRT
1415 dbg(11,"Bkey %lx ", tcaphash_begin_key
.hashKey
);
1416 dbg(51,"PC %s %s ",ep_address_to_str(&pinfo
->src
), ep_address_to_str(&pinfo
->dst
));
1417 dbg(51,"Tid %lx ",tcaphash_begin_key
.tid
);
1419 p_tcaphash_begincall
= find_tcaphash_begin(&tcaphash_begin_key
, pinfo
,FALSE
);
1420 if(!p_tcaphash_begincall
) {
1421 #ifdef DEBUG_TCAPSRT
1422 dbg(12,"BnotFound ");
1426 if (p_tcaphash_endcall
) {
1427 /* Use the TC_BEGIN Destination reference */
1428 p_tcaphash_context
=p_tcaphash_endcall
->context
;
1429 } else if (p_tcaphash_begincall
) {
1430 /* Use the TC_BEGIN Source reference */
1431 p_tcaphash_context
=p_tcaphash_begincall
->context
;
1434 if (p_tcaphash_context
) {
1436 #ifdef DEBUG_TCAPSRT
1437 dbg(12,"Found, req=%d ",p_tcaphash_context
->first_frame
);
1439 if (gtcap_DisplaySRT
&& tree
) {
1440 stat_item
= proto_tree_add_text(tree
, tvb
, 0, -1, "Stat");
1441 PROTO_ITEM_SET_GENERATED(stat_item
);
1442 stat_tree
= proto_item_add_subtree(stat_item
, ett_tcap_stat
);
1444 pi
= proto_tree_add_uint(stat_tree
, hf_tcapsrt_SessionId
, tvb
, 0,0, p_tcaphash_context
->session_id
);
1445 PROTO_ITEM_SET_GENERATED(pi
);
1448 #ifdef DEBUG_TCAPSRT
1449 dbg(20,"Display framereqlink %d ",p_tcaphash_context
->first_frame
);
1451 /* Indicate the frame to which this is a reply. */
1452 if (gtcap_DisplaySRT
&& stat_tree
) {
1453 pi
= proto_tree_add_uint_format(stat_tree
, hf_tcapsrt_EndSession
, tvb
, 0, 0,
1454 p_tcaphash_context
->first_frame
,
1455 "Begin of session in frame %u",
1456 p_tcaphash_context
->first_frame
);
1457 PROTO_ITEM_SET_GENERATED(pi
);
1458 /* Calculate Service Response Time */
1459 nstime_delta(&delta
, &pinfo
->fd
->abs_ts
, &p_tcaphash_context
->begin_time
);
1461 /* display Service Response Time and make it filterable */
1462 pi
= proto_tree_add_time(stat_tree
, hf_tcapsrt_SessionTime
, tvb
, 0, 0, &delta
);
1463 PROTO_ITEM_SET_GENERATED(pi
);
1465 /* Close the context and remove it (if needed) */
1466 tcapsrt_close(p_tcaphash_context
,pinfo
);
1468 } else {/* context present */
1469 #ifdef DEBUG_TCAPSRT
1470 dbg(12,"Context notFound ");
1473 return p_tcaphash_context
;
1478 * Create the record identifiying the TCAP transaction
1479 * When the identifier for the transaction is reused, check
1480 * the following criteria before to append a new record:
1481 * - a timeout corresponding to a message retransmission is detected,
1482 * - a message hast been lost
1483 * - or the previous transaction has been be closed
1485 static struct tcaphash_context_t
*
1486 tcaphash_ansi_matching(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1487 struct tcapsrt_info_t
*p_tcapsrt_info
)
1489 struct tcaphash_context_t
*p_tcaphash_context
=NULL
;
1490 struct tcaphash_context_key_t tcaphash_context_key
;
1491 struct tcaphash_ansicall_t
*p_tcaphash_ansicall
, *p_new_tcaphash_ansicall
;
1492 struct tcaphash_ansi_info_key_t tcaphash_ansi_key
;
1495 gboolean isResponse
=FALSE
;
1496 proto_tree
* stat_tree
=NULL
;
1497 proto_item
* stat_item
=NULL
;
1499 /* prepare the key data */
1500 tcaphash_ansi_key
.tid
= p_tcapsrt_info
->src_tid
;
1501 if (pinfo
->src
.type
== AT_SS7PC
&& pinfo
->dst
.type
== AT_SS7PC
)
1503 /* We have MTP3 PCs (so we can safely do this cast) */
1504 tcaphash_ansi_key
.opc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)pinfo
->src
.data
);
1505 tcaphash_ansi_key
.dpc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)pinfo
->dst
.data
);
1507 /* Don't have MTP3 PCs (maybe we're over SUA?) */
1508 tcaphash_ansi_key
.opc_hash
= g_str_hash(ep_address_to_str(&pinfo
->src
));
1509 tcaphash_ansi_key
.dpc_hash
= g_str_hash(ep_address_to_str(&pinfo
->dst
));
1511 tcaphash_ansi_key
.hashKey
=tcaphash_ansi_calchash(&tcaphash_ansi_key
);
1513 /* look up the request */
1514 #ifdef DEBUG_TCAPSRT
1515 dbg(10,"\n Hansi #%u ", pinfo
->fd
->num
);
1516 dbg(11,"key %lx ",tcaphash_ansi_key
.hashKey
);
1517 dbg(51,"PC %s %s ",ep_address_to_str(&pinfo
->src
), ep_address_to_str(&pinfo
->dst
));
1518 dbg(51,"Tid %lx ",tcaphash_ansi_key
.tid
);
1520 p_tcaphash_ansicall
= (struct tcaphash_ansicall_t
*)
1521 g_hash_table_lookup(tcaphash_ansi
, &tcaphash_ansi_key
);
1523 if (p_tcaphash_ansicall
) {
1524 /* Walk through list of transaction with identical keys */
1526 /* Check if the request with this reqSeqNum has been seen */
1527 if (pinfo
->fd
->num
== p_tcaphash_ansicall
->context
->first_frame
) {
1528 /* We have seen this request before -> do nothing */
1529 #ifdef DEBUG_TCAPSRT
1530 dbg(22,"Request already seen ");
1533 p_tcaphash_context
=p_tcaphash_ansicall
->context
;
1537 /* Check if the reponse with this reqSeqNum has been seen */
1538 if (pinfo
->fd
->num
== p_tcaphash_ansicall
->context
->last_frame
) {
1539 /* We have seen this response before -> do nothing */
1540 #ifdef DEBUG_TCAPSRT
1541 dbg(22,"Response already seen ");
1544 p_tcaphash_context
=p_tcaphash_ansicall
->context
;
1548 /* Check for the first Request without Response
1549 received before this frame */
1550 if ( pinfo
->fd
->num
> p_tcaphash_ansicall
->context
->first_frame
&&
1551 p_tcaphash_ansicall
->context
->last_frame
==0 ) {
1552 /* Take it, and update the context */
1554 #ifdef DEBUG_TCAPSRT
1555 dbg(12,"Update key %lx ",tcaphash_ansi_key
.hashKey
);
1557 p_tcaphash_ansicall
->context
->last_frame
= pinfo
->fd
->num
;
1558 p_tcaphash_ansicall
->context
->responded
= TRUE
;
1559 p_tcaphash_ansicall
->context
->closed
= TRUE
;
1560 p_tcaphash_context
=p_tcaphash_ansicall
->context
;
1563 if (gtcap_DisplaySRT
&& tree
) {
1564 stat_item
= proto_tree_add_text(tree
, tvb
, 0, -1, "Stat");
1565 PROTO_ITEM_SET_GENERATED(stat_item
);
1566 stat_tree
= proto_item_add_subtree(stat_item
, ett_tcap_stat
);
1568 pi
= proto_tree_add_uint(stat_tree
, hf_tcapsrt_SessionId
, tvb
, 0,0, p_tcaphash_context
->session_id
);
1569 PROTO_ITEM_SET_GENERATED(pi
);
1571 #ifdef DEBUG_TCAPSRT
1572 dbg(20,"Display framereqlink %d ",p_tcaphash_context
->first_frame
);
1574 /* Indicate the frame to which this is a reply. */
1575 pi
= proto_tree_add_uint_format(stat_tree
, hf_tcapsrt_EndSession
, tvb
, 0, 0,
1576 p_tcaphash_context
->first_frame
,
1577 "Begin of session in frame %u",
1578 p_tcaphash_context
->first_frame
);
1579 PROTO_ITEM_SET_GENERATED(pi
);
1580 /* Calculate Service Response Time */
1581 nstime_delta(&delta
, &pinfo
->fd
->abs_ts
, &p_tcaphash_context
->begin_time
);
1583 /* display Service Response Time and make it filterable */
1584 pi
= proto_tree_add_time(stat_tree
, hf_tcapsrt_SessionTime
, tvb
, 0, 0, &delta
);
1585 PROTO_ITEM_SET_GENERATED(pi
);
1588 } /* Lastframe=0, so take it */
1591 /* If the last record for Tcap transaction with identifier has been reached */
1592 if (!p_tcaphash_ansicall
->next_ansicall
) {
1593 /* check if we have to create a new record or not */
1594 /* if last request has been responded (response number in known)
1595 and this request appears after last response (has bigger frame number)
1596 and last request occurred after the timeout for repetition,
1598 if last request hasn't been responded (so number unknown)
1599 and this request appears after last request (has bigger frame number)
1600 and this request occurred after the timeout for message lost */
1601 if ( ( p_tcaphash_ansicall
->context
->last_frame
!= 0
1602 && pinfo
->fd
->num
> p_tcaphash_ansicall
->context
->first_frame
1603 && (guint
) pinfo
->fd
->abs_ts
.secs
> (guint
)(p_tcaphash_ansicall
->context
->begin_time
.secs
+ gtcap_RepetitionTimeout
)
1605 ( p_tcaphash_ansicall
->context
->last_frame
== 0
1606 && pinfo
->fd
->num
> p_tcaphash_ansicall
->context
->first_frame
1607 && (guint
)pinfo
->fd
->abs_ts
.secs
> (guint
)(p_tcaphash_ansicall
->context
->begin_time
.secs
+ gtcap_LostTimeout
)
1611 /* we decide that we have a new request */
1612 /* Append new record to the list */
1613 #ifdef DEBUG_TCAPSRT
1614 dbg(12,"(timeout) Append key %lx ",tcaphash_ansi_key
.hashKey
);
1615 dbg(12,"Frame %u rsp %u ",pinfo
->fd
->num
,p_tcaphash_ansicall
->context
->last_frame
);
1617 tcaphash_context_key
.session_id
= tcapsrt_global_SessionId
++;
1618 p_tcaphash_context
= new_tcaphash_context(&tcaphash_context_key
, pinfo
);
1619 p_new_tcaphash_ansicall
= append_tcaphash_ansicall(p_tcaphash_ansicall
,
1623 #ifdef DEBUG_TCAPSRT
1624 dbg(12,"Update key %lx ",tcaphash_ansi_key
.hashKey
);
1626 update_tcaphash_ansicall(p_new_tcaphash_ansicall
, pinfo
);
1627 p_tcaphash_ansicall
=p_new_tcaphash_ansicall
;
1630 /* If the Tid is reused for a closed Transaction */
1631 if ( p_tcaphash_ansicall
->context
->closed
) {
1632 #ifdef DEBUG_TCAPSRT
1633 dbg(12,"(closed) Append key %lu ",tcaphash_ansi_key
.hashKey
);
1634 dbg(12,"Frame %u rsp %u ",pinfo
->fd
->num
,p_tcaphash_ansicall
->context
->last_frame
);
1636 tcaphash_context_key
.session_id
= tcapsrt_global_SessionId
++;
1637 p_tcaphash_context
= new_tcaphash_context(&tcaphash_context_key
, pinfo
);
1638 p_new_tcaphash_ansicall
= append_tcaphash_ansicall(p_tcaphash_ansicall
,
1642 #ifdef DEBUG_TCAPSRT
1643 dbg(12,"Update key %lu ",tcaphash_ansi_key
.hashKey
);
1645 update_tcaphash_ansicall(p_new_tcaphash_ansicall
, pinfo
);
1646 p_tcaphash_ansicall
=p_new_tcaphash_ansicall
;
1649 /* the Tid is reused for an opened Transaction */
1650 /* so, this is the reply to the request of our context */
1651 p_tcaphash_context
=p_tcaphash_ansicall
->context
;
1652 #ifdef DEBUG_TCAPSRT
1653 dbg(12,"Found, req=%d ",p_tcaphash_context
->first_frame
);
1656 if (gtcap_DisplaySRT
&& tree
) {
1657 stat_item
= proto_tree_add_text(tree
, tvb
, 0, -1, "Stat");
1658 PROTO_ITEM_SET_GENERATED(stat_item
);
1659 stat_tree
= proto_item_add_subtree(stat_item
, ett_tcap_stat
);
1661 pi
= proto_tree_add_uint(stat_tree
, hf_tcapsrt_SessionId
, tvb
, 0,0, p_tcaphash_context
->session_id
);
1662 PROTO_ITEM_SET_GENERATED(pi
);
1664 #ifdef DEBUG_TCAPSRT
1665 dbg(20,"Display framereqlink %d ",p_tcaphash_context
->first_frame
);
1667 /* Indicate the frame to which this is a reply. */
1668 pi
= proto_tree_add_uint_format(stat_tree
, hf_tcapsrt_EndSession
, tvb
, 0, 0,
1669 p_tcaphash_context
->first_frame
,
1670 "Begin of session in frame %u",
1671 p_tcaphash_context
->first_frame
);
1672 PROTO_ITEM_SET_GENERATED(pi
);
1673 /* Calculate Service Response Time */
1674 nstime_delta(&delta
, &pinfo
->fd
->abs_ts
, &p_tcaphash_context
->begin_time
);
1676 /* display Service Response Time and make it filterable */
1677 pi
= proto_tree_add_time(stat_tree
, hf_tcapsrt_SessionTime
, tvb
, 0, 0, &delta
);
1678 PROTO_ITEM_SET_GENERATED(pi
);
1680 p_tcaphash_context
=p_tcaphash_ansicall
->context
;
1681 } /* test with Timeout */
1684 } /* Next call is NULL */
1685 p_tcaphash_ansicall
= p_tcaphash_ansicall
->next_ansicall
;
1686 } while (p_tcaphash_ansicall
!= NULL
);
1690 } else { /* p_tcaphash_ansicall has not been found */
1691 #ifdef DEBUG_TCAPSRT
1692 dbg(10,"New key %lx ",tcaphash_ansi_key
.hashKey
);
1695 tcaphash_context_key
.session_id
= tcapsrt_global_SessionId
++;
1696 p_tcaphash_context
= new_tcaphash_context(&tcaphash_context_key
, pinfo
);
1697 p_tcaphash_ansicall
= new_tcaphash_ansi(&tcaphash_ansi_key
, p_tcaphash_context
);
1699 #ifdef DEBUG_TCAPSRT
1700 dbg(11,"Update key %lx ",tcaphash_ansi_key
.hashKey
);
1701 dbg(11,"Frame reqlink #%u ", pinfo
->fd
->num
);
1703 update_tcaphash_ansicall(p_tcaphash_ansicall
, pinfo
);
1706 /* display tcap session, if available */
1707 if ( gtcap_DisplaySRT
&& tree
&&
1708 p_tcaphash_context
&&
1709 p_tcaphash_context
->session_id
) {
1710 stat_item
= proto_tree_add_text(tree
, tvb
, 0, -1, "Stat");
1711 PROTO_ITEM_SET_GENERATED(stat_item
);
1712 stat_tree
= proto_item_add_subtree(stat_item
, ett_tcap_stat
);
1713 pi
= proto_tree_add_uint(stat_tree
, hf_tcapsrt_SessionId
, tvb
, 0,0, p_tcaphash_context
->session_id
);
1714 PROTO_ITEM_SET_GENERATED(pi
);
1718 /* add link to response frame, if available */
1719 if( gtcap_DisplaySRT
&& stat_tree
&&
1720 p_tcaphash_ansicall
->context
->last_frame
!= 0){
1721 if (!isResponse
) { /* Request */
1722 #ifdef DEBUG_TCAPSRT
1723 dbg(20,"Display_frameRsplink %d ",p_tcaphash_ansicall
->context
->last_frame
);
1725 pi
= proto_tree_add_uint_format(stat_tree
, hf_tcapsrt_BeginSession
, tvb
, 0, 0,
1726 p_tcaphash_ansicall
->context
->last_frame
,
1727 "End of session in frame %u",
1728 p_tcaphash_ansicall
->context
->last_frame
);
1729 PROTO_ITEM_SET_GENERATED(pi
);
1730 } else { /* Response */
1731 #ifdef DEBUG_TCAPSRT
1732 dbg(20,"Display framereqlink %d ",p_tcaphash_context
->first_frame
);
1734 /* Indicate the frame to which this is a reply. */
1735 if (gtcap_DisplaySRT
) {
1736 pi
= proto_tree_add_uint_format(stat_tree
, hf_tcapsrt_EndSession
, tvb
, 0, 0,
1737 p_tcaphash_context
->first_frame
,
1738 "Begin of session in frame %u",
1739 p_tcaphash_context
->first_frame
);
1740 PROTO_ITEM_SET_GENERATED(pi
);
1741 /* Calculate Service Response Time */
1742 nstime_delta(&delta
, &pinfo
->fd
->abs_ts
, &p_tcaphash_context
->begin_time
);
1744 /* display Service Response Time and make it filterable */
1745 pi
= proto_tree_add_time(stat_tree
, hf_tcapsrt_SessionTime
, tvb
, 0, 0, &delta
);
1746 PROTO_ITEM_SET_GENERATED(pi
);
1748 } /* Request or Response */
1750 return p_tcaphash_context
;
1755 * Initialize the Message Info used by the main dissector
1756 * Data are linked to a TCAP transaction
1758 struct tcapsrt_info_t
*
1759 tcapsrt_razinfo(void)
1761 struct tcapsrt_info_t
*p_tcapsrt_info
;
1763 /* Global buffer for packet extraction */
1764 tcapsrt_global_current
++;
1765 if(tcapsrt_global_current
==MAX_TCAP_INSTANCE
){
1766 tcapsrt_global_current
=0;
1769 p_tcapsrt_info
=&tcapsrt_global_info
[tcapsrt_global_current
];
1770 memset(p_tcapsrt_info
,0,sizeof(struct tcapsrt_info_t
));
1772 return p_tcapsrt_info
;
1776 tcapsrt_close(struct tcaphash_context_t
*p_tcaphash_context
,
1779 #ifdef DEBUG_TCAPSRT
1780 dbg(60,"Force close ");
1782 if (p_tcaphash_context
) {
1783 p_tcaphash_context
->responded
=TRUE
;
1784 p_tcaphash_context
->last_frame
= pinfo
->fd
->num
;
1785 p_tcaphash_context
->end_time
= pinfo
->fd
->abs_ts
;
1786 p_tcaphash_context
->closed
=TRUE
;
1788 /* If the endkey is present */
1789 if (p_tcaphash_context
->endcall
1790 && !gtcap_PersistentSRT
) {
1791 if (p_tcaphash_context
->endcall
->next_endcall
) {
1792 if (p_tcaphash_context
->endcall
->previous_endcall
) {
1793 #ifdef DEBUG_TCAPSRT
1794 dbg(20,"deplace Ehash ");
1796 p_tcaphash_context
->endcall
->previous_endcall
->next_endcall
1797 = p_tcaphash_context
->endcall
->next_endcall
;
1798 p_tcaphash_context
->endcall
->next_endcall
->previous_endcall
1799 = p_tcaphash_context
->endcall
->previous_endcall
;
1800 g_hash_table_remove(tcaphash_end
, p_tcaphash_context
->endcall
->endkey
);
1802 g_free(p_tcaphash_context
->endcall
);
1805 /* cannot remove the father */
1806 #ifdef DEBUG_TCAPSRT
1807 dbg(20,"father Ehash ");
1809 } /* no previous link, so father */
1810 } else if (!gtcap_PersistentSRT
) {
1811 #ifdef DEBUG_TCAPSRT
1812 dbg(20,"remove Ehash ");
1814 g_hash_table_remove(tcaphash_end
, p_tcaphash_context
->endcall
->endkey
);
1816 g_free(p_tcaphash_context
->endcall
->endkey
);
1817 g_free(p_tcaphash_context
->endcall
);
1820 } /* endcall without chained string */
1824 /* If the contkey is present */
1825 if (p_tcaphash_context
->contcall
1826 && !gtcap_PersistentSRT
) {
1827 if (p_tcaphash_context
->contcall
->next_contcall
) {
1828 if (p_tcaphash_context
->contcall
->previous_contcall
) {
1829 #ifdef DEBUG_TCAPSRT
1830 dbg(20,"deplace Chash ");
1832 p_tcaphash_context
->contcall
->previous_contcall
->next_contcall
1833 = p_tcaphash_context
->contcall
->next_contcall
;
1834 p_tcaphash_context
->contcall
->next_contcall
->previous_contcall
1835 = p_tcaphash_context
->contcall
->previous_contcall
;
1836 g_hash_table_remove(tcaphash_cont
, p_tcaphash_context
->contcall
->contkey
);
1838 g_free(p_tcaphash_context
->contcall
);
1841 /* cannot remove the father */
1842 #ifdef DEBUG_TCAPSRT
1843 dbg(20,"father Chash ");
1845 } /* no previous link, so father */
1846 } else if (!gtcap_PersistentSRT
) {
1847 #ifdef DEBUG_TCAPSRT
1848 dbg(20,"remove Chash ");
1850 g_hash_table_remove(tcaphash_cont
, p_tcaphash_context
->contcall
->contkey
);
1852 g_free(p_tcaphash_context
->contcall
->contkey
);
1853 g_free(p_tcaphash_context
->contcall
);
1855 } /* contcall without chained string */
1859 /* If the beginkey is present */
1860 if (p_tcaphash_context
->begincall
1861 && !gtcap_PersistentSRT
) {
1862 if (p_tcaphash_context
->begincall
->next_begincall
) {
1863 if (p_tcaphash_context
->begincall
->previous_begincall
) {
1864 #ifdef DEBUG_TCAPSRT
1865 dbg(20,"deplace Bhash ");
1867 p_tcaphash_context
->begincall
->previous_begincall
->next_begincall
1868 = p_tcaphash_context
->begincall
->next_begincall
;
1869 p_tcaphash_context
->begincall
->next_begincall
->previous_begincall
1870 = p_tcaphash_context
->begincall
->previous_begincall
;
1871 g_hash_table_remove(tcaphash_begin
, p_tcaphash_context
->begincall
->beginkey
);
1873 g_free(p_tcaphash_context
->begincall
);
1876 /* cannot remove the father */
1877 #ifdef DEBUG_TCAPSRT
1878 dbg(20,"father Bhash ");
1881 } else if (!gtcap_PersistentSRT
) {
1882 #ifdef DEBUG_TCAPSRT
1883 dbg(20,"remove Bhash ");
1885 g_hash_table_remove(tcaphash_begin
, p_tcaphash_context
->begincall
->beginkey
);
1887 g_free(p_tcaphash_context
->begincall
->beginkey
);
1888 g_free(p_tcaphash_context
->begincall
);
1890 } /* begincall without chained string */
1891 } /* no begincall */
1893 /* If the ansikey is present */
1894 if (p_tcaphash_context
->ansicall
1895 && !gtcap_PersistentSRT
) {
1896 if (p_tcaphash_context
->ansicall
->next_ansicall
) {
1897 if (p_tcaphash_context
->ansicall
->previous_ansicall
) {
1898 #ifdef DEBUG_TCAPSRT
1899 dbg(20,"deplace Ahash ");
1901 p_tcaphash_context
->ansicall
->previous_ansicall
->next_ansicall
1902 = p_tcaphash_context
->ansicall
->next_ansicall
;
1903 p_tcaphash_context
->ansicall
->next_ansicall
->previous_ansicall
1904 = p_tcaphash_context
->ansicall
->previous_ansicall
;
1905 g_hash_table_remove(tcaphash_ansi
, p_tcaphash_context
->ansicall
->ansikey
);
1907 g_free(p_tcaphash_context
->ansicall
);
1910 /* cannot remove the father */
1911 #ifdef DEBUG_TCAPSRT
1912 dbg(20,"father Ahash ");
1915 } else if (!gtcap_PersistentSRT
) {
1916 #ifdef DEBUG_TCAPSRT
1917 dbg(20,"remove Ahash ");
1919 g_hash_table_remove(tcaphash_ansi
, p_tcaphash_context
->ansicall
->ansikey
);
1921 g_free(p_tcaphash_context
->ansicall
->ansikey
);
1922 g_free(p_tcaphash_context
->ansicall
);
1924 } /* ansicall without chained string */
1927 if (!gtcap_PersistentSRT
) {
1928 #ifdef DEBUG_TCAPSRT
1929 dbg(20,"remove context ");
1931 g_hash_table_remove(tcaphash_context
, p_tcaphash_context
->key
);
1933 g_free(p_tcaphash_context
->key
);
1934 g_free(p_tcaphash_context
);
1937 } else { /* no context */
1938 #ifdef DEBUG_TCAPSRT
1939 dbg(20,"No context to remove ");