Remove some GTK+-only code.
[metze/wireshark/wip.git] / ui / voip_calls.c
1 /* voip_calls.c
2  * VoIP calls summary addition for Wireshark
3  *
4  * Copyright 2004, Ericsson, Spain
5  * By Francisco Alcoba <francisco.alcoba@ericsson.com>
6  *
7  * based on h323_calls.c
8  * Copyright 2004, Iskratel, Ltd, Kranj
9  * By Miha Jemec <m.jemec@iskratel.si>
10  *
11  * H323, RTP, RTP Event, MGCP, AudioCodes (ISDN PRI and CAS), T38 and Graph Support
12  * By Alejandro Vaquero, alejandro.vaquero@verso.com
13  * Copyright 2005, Verso Technologies Inc.
14  *
15  * Wireshark - Network traffic analyzer
16  * By Gerald Combs <gerald@wireshark.org>
17  * Copyright 1998 Gerald Combs
18  *
19  * SPDX-License-Identifier: GPL-2.0-or-later
20  */
21
22 #include "config.h"
23
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "epan/epan_dissect.h"
28 #include "epan/packet.h"
29 #include "epan/proto_data.h"
30 #include "epan/to_str.h"
31 #include "epan/dissectors/packet-sip.h"
32 #include "epan/dissectors/packet-h225.h"
33 #include "epan/dissectors/packet-h245.h"
34 #include "epan/dissectors/packet-isup.h"
35 #include "epan/dissectors/packet-sdp.h"
36 #include "epan/dissectors/packet-mgcp.h"
37 #include "epan/dissectors/packet-mtp3.h"
38 #include "epan/dissectors/packet-actrace.h"
39 #include "epan/dissectors/packet-q931.h"
40 #include "epan/dissectors/packet-rtp.h"
41 #include "epan/dissectors/packet-rtp-events.h"
42 #include "epan/dissectors/packet-t38.h"
43 #include "epan/dissectors/packet-t30.h"
44 #include "epan/dissectors/packet-h248.h"
45 #include "epan/dissectors/packet-sccp.h"
46 #include "plugins/epan/unistim/packet-unistim.h"
47 #include "epan/dissectors/packet-skinny.h"
48 #include "epan/dissectors/packet-iax2.h"
49 #include "epan/rtp_pt.h"
50
51 #include "ui/rtp_stream.h"
52 #include "ui/simple_dialog.h"
53 #include "ui/ws_ui_util.h"
54 #include "ui/voip_calls.h"
55
56 #define DUMP_PTR1(p) printf("#=> %p\n",(void *)p)
57 #define DUMP_PTR2(p) printf("==> %p\n",(void *)p)
58
59 const char *voip_call_state_name[8]={
60     "",
61     "CALL SETUP",
62     "RINGING",
63     "IN CALL",
64     "CANCELLED",
65     "COMPLETED",
66     "REJECTED",
67     "UNKNOWN"
68 };
69
70 /* defines whether we can consider the call active */
71 const char *voip_protocol_name[]={
72     "SIP",
73     "ISUP",
74     "H.323",
75     "MGCP",
76     "AC_ISDN",
77     "AC_CAS",
78     "T.38",
79     "H.248",
80     "SCCP",
81     "BSSMAP",
82     "RANAP",
83     "UNISTIM",
84     "SKINNY",
85     "IAX2",
86     "VoIP"
87 };
88
89 /*
90  * Tap IDs must be unique. Since different taps need to share the
91  * same voip_calls_tapinfo_t *, make it unique by offsetting its
92  * value.
93  */
94 enum {
95     tap_id_offset_actrace_,
96     tap_id_offset_h225_,
97     tap_id_offset_h245dg_,
98     tap_id_offset_h248_,
99     tap_id_offset_iax2_,
100     tap_id_offset_isup_,
101     tap_id_offset_m3ua_,
102     tap_id_offset_megaco_,
103     tap_id_offset_mgcp_,
104     tap_id_offset_mtp3_,
105     tap_id_offset_q931_,
106     tap_id_offset_rtp_,
107     tap_id_offset_rtp_event_,
108     tap_id_offset_sccp_,
109     tap_id_offset_sdp_,
110     tap_id_offset_sip_,
111     tap_id_offset_skinny_,
112     tap_id_offset_sua_,
113     tap_id_offset_t38_,
114     tap_id_offset_unistim_,
115     tap_id_offset_voip_
116 };
117
118 #define REDRAW_ACTRACE   (1 << tap_id_offset_actrace_)
119 #define REDRAW_H225      (1 << tap_id_offset_h225_)
120 #define REDRAW_H245DG    (1 << tap_id_offset_h245dg_)
121 #define REDRAW_H248      (1 << tap_id_offset_h248_)
122 #define REDRAW_IAX2      (1 << tap_id_offset_iax2_)
123 #define REDRAW_ISUP      (1 << tap_id_offset_isup_)
124 #define REDRAW_M3UA      (1 << tap_id_offset_m3ua_)
125 #define REDRAW_MEGACO    (1 << tap_id_offset_megaco_)
126 #define REDRAW_MGCP      (1 << tap_id_offset_mgcp_)
127 #define REDRAW_MTP3      (1 << tap_id_offset_mtp3_)
128 #define REDRAW_Q931      (1 << tap_id_offset_q931_)
129 #define REDRAW_RTP       (1 << tap_id_offset_rtp_)
130 #define REDRAW_RTP_EVENT (1 << tap_id_offset_rtp_event_)
131 #define REDRAW_SCCP      (1 << tap_id_offset_sccp_)
132 #define REDRAW_SDP       (1 << tap_id_offset_sdp_)
133 #define REDRAW_SIP       (1 << tap_id_offset_sip_)
134 #define REDRAW_SKINNY    (1 << tap_id_offset_skinny_)
135 #define REDRAW_SUA       (1 << tap_id_offset_sua_)
136 #define REDRAW_T38       (1 << tap_id_offset_t38_)
137 #define REDRAW_UNISTIM   (1 << tap_id_offset_unistim_)
138 #define REDRAW_VOIP      (1 << tap_id_offset_voip_)
139
140 static inline void *
141 tap_base_to_id(voip_calls_tapinfo_t* tap_base, int offset) {
142     return GSIZE_TO_POINTER(GPOINTER_TO_SIZE(tap_base) + offset);
143 }
144
145 static inline voip_calls_tapinfo_t *
146 tap_id_to_base(void* tap_id, int offset) {
147     return (voip_calls_tapinfo_t *) GSIZE_TO_POINTER(GPOINTER_TO_SIZE(tap_id) - offset);
148 }
149
150 typedef struct {
151     gchar *frame_label;
152     gchar *comment;
153 } graph_str;
154
155 #define H245_MAX 6
156
157 typedef struct _h245_labels {
158     guint32   frame_num;
159     gint8     labels_count;
160     graph_str labels[H245_MAX];
161 } h245_labels_t;
162
163 static void actrace_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
164 static void h225_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
165 static void h245dg_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
166 static void h248_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
167 static void iax2_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
168 static void isup_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
169 static void mgcp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
170 static void mtp3_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
171 static void q931_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
172 static void rtp_event_init_tap(voip_calls_tapinfo_t *tap_id_base);
173 static void rtp_init_tap(voip_calls_tapinfo_t *tap_id_base);
174 static void sccp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
175 static void sdp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
176 static void sip_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
177 static void skinny_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
178 static void t38_init_tap(voip_calls_tapinfo_t *tap_id_base);
179 static void unistim_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
180 static void voip_calls_init_tap(voip_calls_tapinfo_t *tap_id_base);
181
182 void
183 voip_calls_init_all_taps(voip_calls_tapinfo_t *tap_id_base)
184 {
185     actrace_calls_init_tap(tap_id_base);
186     h225_calls_init_tap(tap_id_base);
187     h245dg_calls_init_tap(tap_id_base);
188     h248_calls_init_tap(tap_id_base);
189     iax2_calls_init_tap(tap_id_base);
190     isup_calls_init_tap(tap_id_base);
191     mgcp_calls_init_tap(tap_id_base);
192     mtp3_calls_init_tap(tap_id_base);
193     q931_calls_init_tap(tap_id_base);
194     rtp_event_init_tap(tap_id_base);
195     rtp_init_tap(tap_id_base); /* This calls tap_reset_cb, tap_packet_cb, and tap_draw_cb */
196     sccp_calls_init_tap(tap_id_base);
197     sdp_calls_init_tap(tap_id_base);
198     sip_calls_init_tap(tap_id_base);
199     skinny_calls_init_tap(tap_id_base);
200     t38_init_tap(tap_id_base);
201     /* We don't register this tap if we don't have the unistim plugin loaded.*/
202     if (find_tap_id("unistim")) {
203         unistim_calls_init_tap(tap_id_base);
204     }
205     if (find_tap_id("voip")) {
206         voip_calls_init_tap(tap_id_base);
207     }
208 }
209
210 static void remove_tap_listener_actrace_calls(voip_calls_tapinfo_t *tap_id_base);
211 static void remove_tap_listener_h225_calls(voip_calls_tapinfo_t *tap_id_base);
212 static void remove_tap_listener_h245dg_calls(voip_calls_tapinfo_t *tap_id_base);
213 static void remove_tap_listener_h248_calls(voip_calls_tapinfo_t *tap_id_base);
214 static void remove_tap_listener_iax2_calls(voip_calls_tapinfo_t *tap_id_base);
215 static void remove_tap_listener_isup_calls(voip_calls_tapinfo_t *tap_id_base);
216 static void remove_tap_listener_mgcp_calls(voip_calls_tapinfo_t *tap_id_base);
217 static void remove_tap_listener_mtp3_calls(voip_calls_tapinfo_t *tap_id_base);
218 static void remove_tap_listener_q931_calls(voip_calls_tapinfo_t *tap_id_base);
219 static void remove_tap_listener_rtp(voip_calls_tapinfo_t *tap_id_base);
220 static void remove_tap_listener_rtp_event(voip_calls_tapinfo_t *tap_id_base);
221 static void remove_tap_listener_sccp_calls(voip_calls_tapinfo_t *tap_id_base);
222 static void remove_tap_listener_sdp_calls(voip_calls_tapinfo_t *tap_id_base);
223 static void remove_tap_listener_sip_calls(voip_calls_tapinfo_t *tap_id_base);
224 static void remove_tap_listener_skinny_calls(voip_calls_tapinfo_t *tap_id_base);
225 static void remove_tap_listener_t38(voip_calls_tapinfo_t *tap_id_base);
226 static void remove_tap_listener_unistim_calls(voip_calls_tapinfo_t *tap_id_base);
227 static void remove_tap_listener_voip_calls(voip_calls_tapinfo_t *tap_id_base);
228
229 void voip_calls_remove_all_tap_listeners(voip_calls_tapinfo_t *tap_id_base)
230 {
231     /* Remove the calls tap listener */
232     remove_tap_listener_actrace_calls(tap_id_base);
233     remove_tap_listener_h225_calls(tap_id_base);
234     remove_tap_listener_h245dg_calls(tap_id_base);
235     remove_tap_listener_h248_calls(tap_id_base);
236     remove_tap_listener_iax2_calls(tap_id_base);
237     remove_tap_listener_isup_calls(tap_id_base);
238     remove_tap_listener_mgcp_calls(tap_id_base);
239     remove_tap_listener_mtp3_calls(tap_id_base);
240     remove_tap_listener_q931_calls(tap_id_base);
241     remove_tap_listener_rtp(tap_id_base);
242     remove_tap_listener_rtp_event(tap_id_base);
243     remove_tap_listener_sccp_calls(tap_id_base);
244     remove_tap_listener_sdp_calls(tap_id_base);
245     remove_tap_listener_sip_calls(tap_id_base);
246     remove_tap_listener_skinny_calls(tap_id_base);
247     remove_tap_listener_t38(tap_id_base);
248     if (find_tap_id("unistim")) { /* The plugin may be missing */
249         remove_tap_listener_unistim_calls(tap_id_base);
250     }
251     if (find_tap_id("voip")) {
252         remove_tap_listener_voip_calls(tap_id_base);
253     }
254 }
255
256 /****************************************************************************/
257 /* when there is a [re]reading of packet's */
258 void
259 voip_calls_reset_all_taps(voip_calls_tapinfo_t *tapinfo)
260 {
261     voip_calls_info_t *callsinfo;
262     rtp_stream_info_t *strinfo;
263     GList *list = NULL;
264
265     /* VOIP_CALLS_DEBUG("reset packets: %d streams: %d", tapinfo->npackets, tapinfo->nrtp_streams); */
266
267     /* free the data items first */
268     list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
269     while (list)
270     {
271         callsinfo = (voip_calls_info_t *)list->data;
272         g_free(callsinfo->call_id);
273         g_free(callsinfo->from_identity);
274         g_free(callsinfo->to_identity);
275         free_address(&callsinfo->initial_speaker);
276         g_free(callsinfo->protocol_name);
277         g_free(callsinfo->call_comment);
278
279         if (callsinfo->free_prot_info && callsinfo->prot_info)
280             callsinfo->free_prot_info(callsinfo->prot_info);
281
282         g_free(list->data);
283         list = g_list_next(list);
284     }
285     g_queue_clear(tapinfo->callsinfos);
286     /* free the SIP_HASH */
287     if(NULL!=tapinfo->callsinfo_hashtable[SIP_HASH])
288         g_hash_table_remove_all (tapinfo->callsinfo_hashtable[SIP_HASH]);
289
290     /* free the strinfo data items first */
291     list = g_list_first(tapinfo->rtp_stream_list);
292     while(list)
293     {
294         strinfo = (rtp_stream_info_t *)list->data;
295         wmem_free(NULL, strinfo->payload_type_name);
296         wmem_free(NULL, strinfo->ed137_info);
297         list = g_list_next(list);
298     }
299     g_list_free(tapinfo->rtp_stream_list);
300     tapinfo->rtp_stream_list = NULL;
301
302     if (tapinfo->h245_labels) {
303         memset(tapinfo->h245_labels, 0, sizeof(h245_labels_t));
304     }
305
306     tapinfo->ncalls = 0;
307     tapinfo->start_packets = 0;
308     tapinfo->completed_calls = 0;
309     tapinfo->rejected_calls = 0;
310
311     return;
312 }
313
314 /****************************************************************************/
315 /* Add a new item into the graph */
316 static void
317 add_to_graph(voip_calls_tapinfo_t *tapinfo, packet_info *pinfo, epan_dissect_t *edt, const gchar *frame_label, const gchar *comment, guint16 call_num, address *src_addr, address *dst_addr, guint16 line_style)
318 {
319     seq_analysis_item_t *gai;
320     gchar time_str[COL_MAX_LEN];
321
322     if (!tapinfo->graph_analysis) {
323         return;
324     }
325
326     gai = (seq_analysis_item_t *)g_malloc0(sizeof(seq_analysis_item_t));
327     gai->frame_number = pinfo->num;
328     copy_address(&(gai->src_addr),src_addr);
329     copy_address(&(gai->dst_addr),dst_addr);
330
331     gai->port_src=pinfo->srcport;
332     gai->port_dst=pinfo->destport;
333
334     if (frame_label != NULL)
335         gai->frame_label = g_strdup(frame_label);
336     else
337         gai->frame_label = g_strdup("");
338
339     if (comment != NULL)
340         gai->comment = g_strdup(comment);
341     else
342         gai->comment = g_strdup("");
343
344     gai->conv_num=call_num;
345     gai->line_style=line_style;
346     set_fd_time(edt->session, pinfo->fd, time_str);
347     gai->time_str = g_strdup(time_str);
348     gai->display=FALSE;
349
350     g_queue_push_tail(tapinfo->graph_analysis->items, gai);
351     g_hash_table_insert(tapinfo->graph_analysis->ht, &gai->frame_number, gai);
352 }
353
354 /****************************************************************************/
355 /* Append str to frame_label and comment in a graph item */
356 /* return 0 if the frame_num is not in the graph list */
357 static int append_to_frame_graph(voip_calls_tapinfo_t *tapinfo, guint32 frame_num, const gchar *new_frame_label, const gchar *new_comment)
358 {
359     seq_analysis_item_t *gai=NULL;
360     gchar *frame_label = NULL;
361     gchar *comment = NULL;
362
363     if(tapinfo->graph_analysis && NULL!=tapinfo->graph_analysis->ht)
364         gai=(seq_analysis_item_t *)g_hash_table_lookup(tapinfo->graph_analysis->ht, &frame_num);
365     if(gai) {
366         frame_label = gai->frame_label;
367         comment = gai->comment;
368
369         if (new_frame_label != NULL) {
370             gai->frame_label = g_strdup_printf("%s %s", frame_label, new_frame_label);
371             g_free(frame_label);
372         }
373
374         if (new_comment != NULL) {
375             gai->comment = g_strdup_printf("%s %s", comment, new_comment);
376             g_free(comment);
377         }
378     }
379
380     return gai? 1 : 0;
381 }
382
383 /****************************************************************************/
384 /* Change the frame_label and comment in a graph item if not NULL*/
385 /* return 0 if the frame_num is not in the graph list */
386 static int change_frame_graph(voip_calls_tapinfo_t *tapinfo, guint32 frame_num, const gchar *new_frame_label, const gchar *new_comment)
387 {
388     seq_analysis_item_t *gai=NULL;
389     gchar *frame_label = NULL;
390     gchar *comment = NULL;
391
392     if(tapinfo->graph_analysis && NULL!=tapinfo->graph_analysis->ht)
393         gai=(seq_analysis_item_t *)g_hash_table_lookup(tapinfo->graph_analysis->ht, &frame_num);
394     if(gai) {
395         frame_label = gai->frame_label;
396         comment = gai->comment;
397
398         if (new_frame_label != NULL) {
399             gai->frame_label = g_strdup(new_frame_label);
400             g_free(frame_label);
401         }
402
403         if (new_comment != NULL) {
404             gai->comment = g_strdup(new_comment);
405             g_free(comment);
406         }
407     }
408
409     return gai? 1 : 0;
410 }
411
412 /****************************************************************************/
413 /* Change all the graph items with call_num to new_call_num */
414 static guint change_call_num_graph(voip_calls_tapinfo_t *tapinfo, guint16 call_num, guint16 new_call_num)
415 {
416     seq_analysis_item_t *gai;
417     GList *list;
418     guint  items_changed;
419
420     items_changed = 0;
421     if(tapinfo->graph_analysis){
422         list = g_queue_peek_nth_link(tapinfo->graph_analysis->items, 0);
423         while (list)
424         {
425             gai = (seq_analysis_item_t *)list->data;
426             if (gai->conv_num == call_num) {
427                 gai->conv_num = new_call_num;
428                 items_changed++;
429             }
430             list = g_list_next(list);
431         }
432     }
433     return items_changed;
434 }
435
436 /****************************************************************************/
437 /* Insert the item in the graph list */
438 static void insert_to_graph_t38(voip_calls_tapinfo_t *tapinfo, packet_info *pinfo, epan_dissect_t *edt, const gchar *frame_label, const gchar *comment, guint16 call_num, address *src_addr, address *dst_addr, guint16 line_style, guint32 frame_num)
439 {
440     seq_analysis_item_t *gai, *new_gai;
441     GList    *list;
442     guint     item_num;
443     gboolean  inserted;
444     gchar     time_str[COL_MAX_LEN];
445
446     new_gai = (seq_analysis_item_t *)g_malloc0(sizeof(seq_analysis_item_t));
447     new_gai->frame_number = frame_num;
448     copy_address(&(new_gai->src_addr),src_addr);
449     copy_address(&(new_gai->dst_addr),dst_addr);
450
451     new_gai->port_src=pinfo->srcport;
452     new_gai->port_dst=pinfo->destport;
453     if (frame_label != NULL)
454         new_gai->frame_label = g_strdup(frame_label);
455     else
456         new_gai->frame_label = g_strdup("");
457
458     if (comment != NULL)
459         new_gai->comment = g_strdup(comment);
460     else
461         new_gai->comment = g_strdup("");
462     new_gai->conv_num=call_num;
463     new_gai->line_style=line_style;
464     set_fd_time(edt->session, pinfo->fd, time_str);
465     new_gai->time_str = g_strdup(time_str);
466     new_gai->display=FALSE;
467
468     item_num = 0;
469     inserted = FALSE;
470     if(tapinfo->graph_analysis){
471         list = g_queue_peek_nth_link(tapinfo->graph_analysis->items, 0);
472         while (list)
473         {
474             gai = (seq_analysis_item_t *)list->data;
475             if (gai->frame_number > frame_num) {
476                 g_queue_insert_before(tapinfo->graph_analysis->items, list, new_gai);
477                 g_hash_table_insert(tapinfo->graph_analysis->ht, &new_gai->frame_number, new_gai);
478                 inserted = TRUE;
479                 break;
480             }
481             list = g_list_next(list);
482             item_num++;
483         }
484
485         if (!inserted) {
486             g_queue_push_tail(tapinfo->graph_analysis->items, new_gai);
487             g_hash_table_insert(tapinfo->graph_analysis->ht, &new_gai->frame_number, new_gai);
488         }
489     }
490 }
491
492 /****************************************************************************/
493 /* ***************************TAP for RTP Events*****************************/
494 /****************************************************************************/
495
496 /*static guint32 rtp_evt_setup_frame_num = 0;*/
497
498 /****************************************************************************/
499 /* whenever a rtp event packet is seen by the tap listener */
500 static int
501 rtp_event_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt _U_, const void *rtp_event_info)
502 {
503     voip_calls_tapinfo_t         *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_event_);
504     const struct _rtp_event_info *pi      = (const struct _rtp_event_info *)rtp_event_info;
505
506     /* do not consider RTP events packets without a setup frame */
507     if (pi->info_setup_frame_num == 0) {
508         return FALSE;
509     }
510
511     tapinfo->rtp_evt_frame_num = pinfo->num;
512     tapinfo->rtp_evt = pi->info_rtp_evt;
513     tapinfo->rtp_evt_end = pi->info_end;
514
515     return FALSE;
516 }
517
518 /****************************************************************************/
519 void
520 rtp_event_init_tap(voip_calls_tapinfo_t *tap_id_base)
521 {
522     GString *error_string;
523
524     error_string = register_tap_listener("rtpevent", tap_base_to_id(tap_id_base, tap_id_offset_rtp_event_),
525             NULL,
526             0,
527             NULL,
528             rtp_event_packet,
529             NULL
530             );
531
532     if (error_string != NULL) {
533         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
534                 "%s", error_string->str);
535         g_string_free(error_string, TRUE);
536     }
537 }
538
539 /****************************************************************************/
540
541 void
542 remove_tap_listener_rtp_event(voip_calls_tapinfo_t *tap_id_base)
543 {
544     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_rtp_event_));
545 }
546
547 /****************************************************************************/
548 /* ***************************TAP for RTP **********************************/
549 /****************************************************************************/
550
551 /****************************************************************************/
552 /* when there is a [re]reading of RTP packets */
553 static void
554 rtp_reset(void *tap_offset_ptr)
555 {
556     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_);
557     GList *list;
558
559     /* free the data items first */
560     list = g_list_first(tapinfo->rtp_stream_list);
561     while (list)
562     {
563         g_free(list->data);
564         list = g_list_next(list);
565     }
566     g_list_free(tapinfo->rtp_stream_list);
567     tapinfo->rtp_stream_list = NULL;
568     tapinfo->nrtp_streams = 0;
569
570     if (tapinfo->tap_reset) {
571         tapinfo->tap_reset(tapinfo);
572     }
573
574     return;
575 }
576
577 /****************************************************************************/
578 /* whenever a RTP packet is seen by the tap listener */
579 static gboolean
580 rtp_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, void const *rtp_info_ptr)
581 {
582     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_);
583     rtp_stream_info_t    *tmp_listinfo;
584     rtp_stream_info_t    *strinfo = NULL;
585     GList                *list;
586     struct _rtp_conversation_info *p_conv_data = NULL;
587
588     const struct _rtp_info *rtp_info = (const struct _rtp_info *)rtp_info_ptr;
589
590     /* do not consider RTP packets without a setup frame */
591     if (rtp_info->info_setup_frame_num == 0) {
592         return FALSE;
593     }
594
595     if (tapinfo->tap_packet) {
596         tapinfo->tap_packet(tapinfo, pinfo, edt, rtp_info_ptr);
597     }
598
599     /* check whether we already have a RTP stream with this setup frame and ssrc in the list */
600     list = g_list_first(tapinfo->rtp_stream_list);
601     while (list)
602     {
603         tmp_listinfo=(rtp_stream_info_t *)list->data;
604         if ( (tmp_listinfo->setup_frame_number == rtp_info->info_setup_frame_num)
605                 && (tmp_listinfo->ssrc == rtp_info->info_sync_src) && (tmp_listinfo->end_stream == FALSE)) {
606             /* if the payload type has changed, we mark the stream as finished to create a new one
607                this is to show multiple payload changes in the Graph for example for DTMF RFC2833 */
608             if ( tmp_listinfo->payload_type != rtp_info->info_payload_type ) {
609                 tmp_listinfo->end_stream = TRUE;
610             } else if ( ( ( tmp_listinfo->ed137_info == NULL ) && (rtp_info->info_ed137_info != NULL) ) ||
611                         ( ( tmp_listinfo->ed137_info != NULL ) && (rtp_info->info_ed137_info == NULL) ) ||
612                         ( ( tmp_listinfo->ed137_info != NULL ) && (rtp_info->info_ed137_info != NULL) &&
613                           ( 0!=strcmp(tmp_listinfo->ed137_info, rtp_info->info_ed137_info) )
614                         )
615                       ) {
616             /* if ed137_info has changed, create new stream */
617                 tmp_listinfo->end_stream = TRUE;
618             } else {
619                 strinfo = (rtp_stream_info_t*)(list->data);
620                 break;
621             }
622         }
623         list = g_list_next(list);
624     }
625
626     /* if this is a duplicated RTP Event End, just return */
627     if ((tapinfo->rtp_evt_frame_num == pinfo->num) && !strinfo && (tapinfo->rtp_evt_end == TRUE)) {
628         return FALSE;
629     }
630
631     /* not in the list? then create a new entry */
632     if (strinfo==NULL) {
633         strinfo = (rtp_stream_info_t *)g_malloc0(sizeof(rtp_stream_info_t));
634         copy_address(&(strinfo->src_addr), &(pinfo->src));
635         strinfo->src_port = pinfo->srcport;
636         copy_address(&(strinfo->dest_addr), &(pinfo->dst));
637         strinfo->dest_port = pinfo->destport;
638         strinfo->ssrc = rtp_info->info_sync_src;
639         strinfo->payload_type = rtp_info->info_payload_type;
640         strinfo->is_srtp = rtp_info->info_is_srtp;
641         /* if it is dynamic payload, let use the conv data to see if it is defined */
642         if ( (strinfo->payload_type >= PT_UNDF_96) && (strinfo->payload_type <= PT_UNDF_127) ) {
643             /* Use existing packet info if available */
644             p_conv_data = (struct _rtp_conversation_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_get_id_by_filter_name("rtp"), 0);
645             if (p_conv_data && p_conv_data->rtp_dyn_payload) {
646                 const gchar *encoding_name = rtp_dyn_payload_get_name(p_conv_data->rtp_dyn_payload, strinfo->payload_type);
647                 if (encoding_name) {
648                     strinfo->payload_type_name = wmem_strdup(NULL, encoding_name);
649                 }
650             }
651         }
652         if (!strinfo->payload_type_name) strinfo->payload_type_name = (gchar*)val_to_str_ext_wmem(NULL, strinfo->payload_type, &rtp_payload_type_short_vals_ext, "%u");
653         strinfo->start_fd = pinfo->fd;
654         strinfo->start_rel_time = pinfo->rel_ts;
655         strinfo->setup_frame_number = rtp_info->info_setup_frame_num;
656         strinfo->call_num = -1;
657         strinfo->rtp_event = -1;
658         if (rtp_info->info_ed137_info != NULL) {
659             strinfo->ed137_info = wmem_strdup(NULL, rtp_info->info_ed137_info);
660         } else {
661             strinfo->ed137_info = NULL;
662         }
663         tapinfo->rtp_stream_list = g_list_prepend(tapinfo->rtp_stream_list, strinfo);
664     }
665
666     /* Add the info to the existing RTP stream */
667     strinfo->packet_count++;
668     strinfo->stop_fd = pinfo->fd;
669     strinfo->stop_rel_time = pinfo->rel_ts;
670
671     /* process RTP Event */
672     if (tapinfo->rtp_evt_frame_num == pinfo->num) {
673         strinfo->rtp_event = tapinfo->rtp_evt;
674         if (tapinfo->rtp_evt_end == TRUE) {
675             strinfo->end_stream = TRUE;
676         }
677     }
678
679     tapinfo->redraw |= REDRAW_RTP;
680
681     return FALSE;
682 }
683
684 /****************************************************************************/
685 /* whenever a redraw in the RTP tap listener */
686 static void
687 rtp_draw(void *tap_offset_ptr)
688 {
689     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_);
690     GList                *rtp_streams_list;
691     rtp_stream_info_t    *rtp_listinfo;
692     /* GList *voip_calls_graph_list; */
693     seq_analysis_item_t  *gai     = NULL;
694     seq_analysis_item_t  *new_gai;
695     guint16               conv_num;
696     guint32               duration;
697     gchar                 time_str[COL_MAX_LEN];
698
699     /* add each rtp stream to the graph */
700     rtp_streams_list = g_list_first(tapinfo->rtp_stream_list);
701     while (rtp_streams_list)
702     {
703         rtp_listinfo = (rtp_stream_info_t *)rtp_streams_list->data;
704
705         /* using the setup frame number of the RTP stream, we get the call number that it belongs to*/
706         /* voip_calls_graph_list = g_list_first(tapinfo->graph_analysis->list); */
707         if(tapinfo->graph_analysis){
708             gai = (seq_analysis_item_t *)g_hash_table_lookup(tapinfo->graph_analysis->ht, &rtp_listinfo->setup_frame_number);
709         }
710         if(gai != NULL) {
711             const char *comment_fmt = "%s, %u packets. Duration: %u.%03us SSRC: 0x%X";
712             /* Found the setup frame*/
713             conv_num = gai->conv_num;
714             /* if RTP was already in the Graph, just update the comment information */
715             gai = (seq_analysis_item_t *)g_hash_table_lookup(tapinfo->graph_analysis->ht, &rtp_listinfo->start_fd->num);
716             if (gai != NULL) {
717                 duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_rel_time) - nstime_to_msec(&rtp_listinfo->start_rel_time));
718                 g_free(gai->comment);
719                 gai->comment = g_strdup_printf(comment_fmt,
720                         (rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->packet_count,
721                         duration/1000,(duration%1000), rtp_listinfo->ssrc);
722             } else {
723                 new_gai = (seq_analysis_item_t *)g_malloc0(sizeof(seq_analysis_item_t));
724                 new_gai->frame_number = rtp_listinfo->start_fd->num;
725                 copy_address(&(new_gai->src_addr),&(rtp_listinfo->src_addr));
726                 copy_address(&(new_gai->dst_addr),&(rtp_listinfo->dest_addr));
727                 new_gai->port_src = rtp_listinfo->src_port;
728                 new_gai->port_dst = rtp_listinfo->dest_port;
729                 duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_rel_time) - nstime_to_msec(&rtp_listinfo->start_rel_time));
730                 new_gai->frame_label = g_strdup_printf("%s (%s) %s%s%s",
731                         (rtp_listinfo->is_srtp)?"SRTP":"RTP",
732                         rtp_listinfo->payload_type_name,
733                         (rtp_listinfo->rtp_event == -1)?
734                         "":val_to_str_ext_const(rtp_listinfo->rtp_event, &rtp_event_type_values_ext, "Unknown RTP Event"),
735                         (rtp_listinfo->ed137_info!=NULL?" ":""),
736                         (rtp_listinfo->ed137_info!=NULL?rtp_listinfo->ed137_info:"")
737                 );
738                 new_gai->comment = g_strdup_printf(comment_fmt,
739                         (rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->packet_count,
740                         duration/1000,(duration%1000), rtp_listinfo->ssrc);
741                 new_gai->conv_num = conv_num;
742                 set_fd_time(tapinfo->session, rtp_listinfo->start_fd, time_str);
743                 new_gai->time_str = g_strdup(time_str);
744                 new_gai->display=FALSE;
745                 new_gai->line_style = 2;  /* the arrow line will be 2 pixels width */
746                 g_queue_push_tail(tapinfo->graph_analysis->items, new_gai);
747                 g_hash_table_insert(tapinfo->graph_analysis->ht, &rtp_listinfo->start_fd, new_gai);
748             }
749         }
750         rtp_streams_list = g_list_next(rtp_streams_list);
751     } /* while (rtp_streams_list) */
752
753     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_RTP)) {
754         tapinfo->tap_draw(tapinfo);
755         tapinfo->redraw &= ~REDRAW_RTP;
756     }
757 }
758 #if 0
759 static void
760 rtp_packet_draw(void *tap_offset_ptr)
761 {
762     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_);
763     GList                *rtp_streams_list;
764     rtp_stream_info_t    *rtp_listinfo;
765     GList                *voip_calls_graph_list;
766     guint                 item;
767     seq_analysis_item_t  *gai;
768     seq_analysis_item_t  *new_gai;
769     guint16               conv_num;
770     guint32               duration;
771     gchar                 time_str[COL_MAX_LEN];
772
773     /* add each rtp stream to the graph */
774     rtp_streams_list = g_list_first(tapinfo->stream_list);
775     while (rtp_streams_list)
776     {
777         rtp_listinfo = rtp_streams_list->data;
778
779         /* using the setup frame number of the RTP stream, we get the call number that it belongs to*/
780         voip_calls_graph_list = g_list_first(tapinfo->graph_analysis->list);
781         while (voip_calls_graph_list)
782         {
783             gai = voip_calls_graph_list->data;
784             conv_num = gai->conv_num;
785             /* if we get the setup frame number, then get the time position to graph the RTP arrow */
786             if (rtp_listinfo->setup_frame_number == gai->frame_number) {
787                 /* look again from the beginning because there are cases where the Setup frame is after the RTP */
788                 voip_calls_graph_list = g_list_first(tapinfo->graph_analysis->list);
789                 item = 0;
790                 while(voip_calls_graph_list) {
791                     gai = voip_calls_graph_list->data;
792                     /* if RTP was already in the Graph, just update the comment information */
793                     if (rtp_listinfo->start_fd->num == gai->frame_number) {
794                         duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_fd->rel_ts) - nstime_to_msec(&rtp_listinfo->start_fd->rel_ts));
795                         g_free(gai->comment);
796                         gai->comment = g_strdup_printf("%s Num packets:%u  Duration:%u.%03us SSRC:0x%X",
797                                                        (rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->npackets,
798                                                        duration/1000,(duration%1000), rtp_listinfo->ssrc);
799                         break;
800                     }
801
802                     /* we increment the list here to be able to check if it is the last item in this calls, which means the RTP is after so we have to draw it */
803                     voip_calls_graph_list = g_list_next(voip_calls_graph_list);
804                     if (!voip_calls_graph_list) item++;
805
806                     /* add the RTP item to the graph if was not there*/
807                     if (rtp_listinfo->start_fd->num<gai->frame_number || !voip_calls_graph_list) {
808                         new_gai = g_malloc0(sizeof(seq_analysis_item_t));
809                         new_gai->frame_number = rtp_listinfo->start_fd->num;
810                         copy_address(&(new_gai->src_addr),&(rtp_listinfo->src_addr));
811                         copy_address(&(new_gai->dst_addr),&(rtp_listinfo->dest_addr));
812                         new_gai->port_src = rtp_listinfo->src_port;
813                         new_gai->port_dst = rtp_listinfo->dest_port;
814                         new_gai->protocol = g_strdup(port_type_to_str(pinfo->ptype));
815                         duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_fd->rel_ts) - nstime_to_msec(&rtp_listinfo->start_fd->rel_ts));
816                         new_gai->frame_label = g_strdup_printf("%s (%s) %s",
817                                                                (rtp_listinfo->is_srtp)?"SRTP":"RTP",
818                                                                rtp_listinfo->payload_type_str,
819                                                                (rtp_listinfo->rtp_event == -1)?
820                                                                "":val_to_str_ext_const(rtp_listinfo->rtp_event, &rtp_event_type_values_ext, "Unknown RTP Event"));
821                         new_gai->comment = g_strdup_printf("%s Num packets:%u  Duration:%u.%03us SSRC:0x%X",
822                                                            (rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->npackets,
823                                                            duration/1000,(duration%1000), rtp_listinfo->ssrc);
824                         new_gai->conv_num = conv_num;
825                         set_fd_time(cfile.epan, rtp_listinfo->start_fd, time_str);
826                         new_gai->time_str = g_strdup(time_str);
827                         new_gai->display=FALSE;
828                         new_gai->line_style = 2;  /* the arrow line will be 2 pixels width */
829                         tapinfo->graph_analysis->list = g_list_insert(tapinfo->graph_analysis->list, new_gai, item);
830                         break;
831                     }
832                     if (voip_calls_graph_list) item++;
833                 }
834                 break;
835             }
836             voip_calls_graph_list = g_list_next(voip_calls_graph_list);
837         }
838         rtp_streams_list = g_list_next(rtp_streams_list);
839     }
840 }
841 #endif
842
843 /****************************************************************************/
844 void
845 rtp_init_tap(voip_calls_tapinfo_t *tap_id_base)
846 {
847     GString *error_string;
848
849     error_string = register_tap_listener("rtp", tap_base_to_id(tap_id_base, tap_id_offset_rtp_), NULL,
850             0,
851             rtp_reset,
852             rtp_packet,
853             rtp_draw
854             );
855     if (error_string != NULL) {
856         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
857                 "%s", error_string->str);
858         g_string_free(error_string, TRUE);
859     }
860 }
861
862 /****************************************************************************/
863 void
864 remove_tap_listener_rtp(voip_calls_tapinfo_t *tap_id_base)
865 {
866     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_rtp_));
867 }
868
869 /****************************************************************************/
870 /******************************TAP for T38 **********************************/
871 /****************************************************************************/
872
873 /****************************************************************************/
874 /* whenever a T38 packet is seen by the tap listener */
875 static gboolean
876 t38_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *t38_info_ptr)
877 {
878     voip_calls_tapinfo_t *tapinfo               = tap_id_to_base(tap_offset_ptr, tap_id_offset_t38_);
879
880     voip_calls_info_t    *callsinfo             = NULL;
881     voip_calls_info_t    *tmp_listinfo;
882     GList                *voip_calls_graph_list = NULL;
883     GList                *list;
884     gchar                *frame_label           = NULL;
885     gchar                *comment               = NULL;
886     seq_analysis_item_t  *tmp_gai, *gai         = NULL;
887     gchar                *tmp_str1, *tmp_str2;
888     guint16               line_style            = 2;
889     double                duration;
890     int                   conv_num              = -1;
891
892     const t38_packet_info *t38_info = (const t38_packet_info *)t38_info_ptr;
893
894     if  (t38_info->setup_frame_number != 0) {
895         /* using the setup frame number of the T38 packet, we get the call number that it belongs */
896         if(tapinfo->graph_analysis){
897             voip_calls_graph_list = g_queue_peek_nth_link(tapinfo->graph_analysis->items, 0);
898         }
899         while (voip_calls_graph_list)
900         {
901             tmp_gai = (seq_analysis_item_t *)voip_calls_graph_list->data;
902             if (t38_info->setup_frame_number == tmp_gai->frame_number) {
903                 gai = tmp_gai;
904                 break;
905             }
906             voip_calls_graph_list = g_list_next(voip_calls_graph_list);
907         }
908         if (gai) conv_num = (int) gai->conv_num;
909     }
910
911     /* if setup_frame_number in the t38 packet is 0, it means it was not set using an SDP or H245 sesion, which means we don't
912      * have the associated Voip calls. It probably means the the packet was decoded using the default t38 port, or using "Decode as.."
913      * in this case we create a "voip" call that only have t38 media (no signaling)
914      * OR if we have not found the Setup message in the graph.
915      */
916     if ( (t38_info->setup_frame_number == 0) || (gai == NULL) ) {
917         /* check whether we already have a call with these parameters in the list */
918         list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
919         while (list)
920         {
921             tmp_listinfo=(voip_calls_info_t *)list->data;
922             if (tmp_listinfo->protocol == MEDIA_T38) {
923                 callsinfo = (voip_calls_info_t*)(list->data);
924                 break;
925             }
926             list = g_list_next (list);
927         }
928
929         /* not in the list? then create a new entry */
930         if (callsinfo==NULL) {
931             callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
932             callsinfo->call_active_state = VOIP_ACTIVE;
933             callsinfo->call_state = VOIP_UNKNOWN;
934             callsinfo->from_identity=g_strdup("T38 Media only");
935             callsinfo->to_identity=g_strdup("T38 Media only");
936             copy_address(&(callsinfo->initial_speaker),&(pinfo->src));
937             callsinfo->start_fd = pinfo->fd;
938             callsinfo->start_rel_ts = pinfo->rel_ts;
939             callsinfo->protocol=MEDIA_T38;
940             callsinfo->prot_info=NULL;
941             callsinfo->free_prot_info = NULL;
942             callsinfo->npackets = 0;
943             callsinfo->call_num = tapinfo->ncalls++;
944             g_queue_push_tail(tapinfo->callsinfos, callsinfo);
945         }
946         callsinfo->stop_fd = pinfo->fd;
947         callsinfo->stop_rel_ts = pinfo->rel_ts;
948         ++(callsinfo->npackets);
949         /* increment the packets counter of all calls */
950         ++(tapinfo->npackets);
951
952         conv_num = (int) callsinfo->call_num;
953     }
954
955     /* at this point we should have found the call num for this t38 packets belong */
956     if (conv_num == -1) {
957         return FALSE;
958     }
959
960     /* add the item to the graph list */
961     if (t38_info->type_msg == 0) { /* 0=t30-indicator */
962         tmp_str1 = val_to_str_wmem(NULL, t38_info->t30ind_value, t38_T30_indicator_vals, "Ukn (0x%02X)");
963         frame_label = g_strdup(tmp_str1);
964         comment = g_strdup_printf("t38:t30 Ind:%s", tmp_str1);
965         wmem_free(NULL, tmp_str1);
966         line_style = 1;
967     } else if (t38_info->type_msg == 1) {  /* 1=data */
968         switch(t38_info->Data_Field_field_type_value) {
969             case 0: /* hdlc-data */
970                 break;
971             case 2: /* hdlc-fcs-OK */
972             case 4: /* hdlc-fcs-OK-sig-end */
973                 tmp_str1 = val_to_str_ext_wmem(NULL, t38_info->t30_Facsimile_Control & 0x7F,
974                             &t30_facsimile_control_field_vals_short_ext,
975                             "Ukn (0x%02X)");
976                 frame_label = g_strdup_printf("%s %s",
977                         tmp_str1,
978                         t38_info->desc);
979                 wmem_free(NULL, tmp_str1);
980
981                 tmp_str1 = val_to_str_ext_wmem(NULL, t38_info->t30_Facsimile_Control & 0x7F,
982                             &t30_facsimile_control_field_vals_ext,
983                             "Ukn (0x%02X)");
984                 tmp_str2 = val_to_str_wmem(NULL, t38_info->data_value,
985                             t38_T30_data_vals,
986                             "Ukn (0x%02X)");
987                 comment      = g_strdup_printf("t38:%s:HDLC:%s", tmp_str2, tmp_str1);
988                 wmem_free(NULL, tmp_str1);
989                 wmem_free(NULL, tmp_str2);
990                 break;
991             case 3: /* hdlc-fcs-BAD */
992             case 5: /* hdlc-fcs-BAD-sig-end */
993                 frame_label = g_strdup(t38_info->Data_Field_field_type_value == 3 ? "fcs-BAD" : "fcs-BAD-sig-end");
994                 tmp_str1    = val_to_str_wmem(NULL, t38_info->data_value, t38_T30_data_vals, "Ukn (0x%02X)");
995                 comment    = g_strdup_printf("WARNING: received t38:%s:HDLC:%s",
996                         tmp_str1,
997                         t38_info->Data_Field_field_type_value == 3 ? "fcs-BAD" : "fcs-BAD-sig-end");
998                 wmem_free(NULL, tmp_str1);
999                 break;
1000             case 7: /* t4-non-ecm-sig-end */
1001                 duration = nstime_to_sec(&pinfo->rel_ts) - t38_info->time_first_t4_data;
1002                 tmp_str1    = val_to_str_wmem(NULL, t38_info->data_value, t38_T30_data_vals, "Ukn (0x%02X)");
1003                 frame_label = g_strdup_printf("t4-non-ecm-data:%s", tmp_str1);
1004                 comment     = g_strdup_printf("t38:t4-non-ecm-data:%s Duration: %.2fs %s",
1005                         tmp_str1, duration, t38_info->desc_comment );
1006                 insert_to_graph_t38(tapinfo, pinfo, edt, frame_label, comment,
1007                         (guint16)conv_num, &(pinfo->src), &(pinfo->dst),
1008                         line_style, t38_info->frame_num_first_t4_data);
1009                 wmem_free(NULL, tmp_str1);
1010                 break;
1011         }
1012     }
1013
1014     if (frame_label && !(t38_info->Data_Field_field_type_value == 7 && t38_info->type_msg == 1)) {
1015         add_to_graph(tapinfo, pinfo, edt, frame_label, comment, (guint16)conv_num, &(pinfo->src), &(pinfo->dst), line_style);
1016     }
1017
1018     g_free(comment);
1019     g_free(frame_label);
1020
1021     tapinfo->redraw |= REDRAW_T38;
1022
1023     return TRUE;  /* refresh output */
1024 }
1025
1026 /****************************************************************************/
1027 static void
1028 t38_draw(void *tap_offset_ptr)
1029 {
1030     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_t38_);
1031
1032     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_T38)) {
1033         tapinfo->tap_draw(tapinfo);
1034         tapinfo->redraw &= ~REDRAW_T38;
1035     }
1036 }
1037
1038 /****************************************************************************/
1039 void
1040 t38_init_tap(voip_calls_tapinfo_t *tap_id_base)
1041 {
1042     GString *error_string;
1043
1044     error_string = register_tap_listener("t38", tap_base_to_id(tap_id_base, tap_id_offset_t38_), NULL,
1045             0,
1046             NULL,
1047             t38_packet,
1048             t38_draw
1049             );
1050     if (error_string != NULL) {
1051         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1052                 "%s", error_string->str);
1053         g_string_free(error_string, TRUE);
1054     }
1055 }
1056
1057 /****************************************************************************/
1058 void
1059 remove_tap_listener_t38(voip_calls_tapinfo_t *tap_id_base)
1060 {
1061     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_t38_));
1062 }
1063
1064
1065 /****************************************************************************/
1066 /* ***************************TAP for SIP **********************************/
1067 /****************************************************************************/
1068
1069 static void
1070 free_sip_info(gpointer p) {
1071     sip_calls_info_t *si = (sip_calls_info_t *)p;
1072
1073     g_free(si->call_identifier);
1074     g_free(si);
1075 }
1076
1077 /****************************************************************************/
1078 /* whenever a SIP packet is seen by the tap listener */
1079 static gboolean
1080 sip_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt , const void *SIPinfo)
1081 {
1082     voip_calls_tapinfo_t *tapinfo     = tap_id_to_base(tap_offset_ptr, tap_id_offset_sip_);
1083     /* we just take note of the ISUP data here; when we receive the MTP3 part everything will
1084        be compared with existing calls */
1085
1086     voip_calls_info_t    *callsinfo   = NULL;
1087     sip_calls_info_t     *tmp_sipinfo = NULL;
1088     address               tmp_src, tmp_dst;
1089     gchar                *frame_label = NULL;
1090     gchar                *comment     = NULL;
1091     gchar                *old_comment = NULL;
1092     gchar                *key         = NULL;
1093
1094     const sip_info_value_t *pi = (const sip_info_value_t *)SIPinfo;
1095
1096     tapinfo->sip_frame_num = pinfo->num;
1097
1098     /* do not consider packets without call_id */
1099     if (pi->tap_call_id ==NULL) {
1100         return FALSE;
1101     }
1102     key=pi->tap_call_id;
1103     /* init the hash table */
1104     if(NULL==tapinfo->callsinfo_hashtable[SIP_HASH]) {
1105         /* TODO: check how efficient g_str_hash is for sip call ids */
1106         tapinfo->callsinfo_hashtable[SIP_HASH]=g_hash_table_new_full(g_str_hash,
1107                 g_str_equal,
1108                 NULL, /* key_destroy_func */
1109                 NULL);/* value_destroy_func */
1110     }
1111     /* search the call information in the SIP_HASH */
1112     callsinfo = (voip_calls_info_t *)g_hash_table_lookup(tapinfo->callsinfo_hashtable[SIP_HASH], key);
1113
1114     /* Create a new flow entry if the message is INVITE in case of FLOW_ONLY_INVITES,
1115        Create a new flow entry for all messages which have a method in case of FLOW_ALL.
1116        Flows for REGISTER, OPTIONS, MESSAGE and other SIP methods can be seen. */
1117
1118     if ((callsinfo==NULL) && (pi->request_method!=NULL)) {
1119
1120         /* check VoIPcalls_get_flow_show_option() == FLOW_ALL or FLOW_ONLY_INVITES */
1121
1122         if (tapinfo->fs_option == FLOW_ALL ||
1123                 (tapinfo->fs_option == FLOW_ONLY_INVITES &&
1124                  strcmp(pi->request_method,"INVITE")==0)) {
1125             callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
1126             callsinfo->call_active_state = VOIP_ACTIVE;
1127             callsinfo->call_state = VOIP_CALL_SETUP;
1128             callsinfo->from_identity=g_strdup(pi->tap_from_addr);
1129             callsinfo->to_identity=g_strdup(pi->tap_to_addr);
1130             copy_address(&(callsinfo->initial_speaker),&(pinfo->src));
1131             callsinfo->start_fd=pinfo->fd;
1132             callsinfo->start_rel_ts=pinfo->rel_ts;
1133             callsinfo->protocol=VOIP_SIP;
1134             callsinfo->prot_info=g_malloc(sizeof(sip_calls_info_t));
1135             callsinfo->free_prot_info = free_sip_info;
1136             callsinfo->call_id = g_strdup(pi->tap_call_id);
1137             tmp_sipinfo = (sip_calls_info_t *)callsinfo->prot_info;
1138             tmp_sipinfo->call_identifier = g_strdup(pi->tap_call_id);
1139             tmp_sipinfo->sip_state = SIP_INVITE_SENT;
1140             tmp_sipinfo->invite_cseq = pi->tap_cseq_number;
1141             callsinfo->npackets = 0;
1142             callsinfo->call_num = tapinfo->ncalls++;
1143
1144             /* show method in comment in conversation list dialog, user can discern different conversation types */
1145             callsinfo->call_comment=g_strdup(pi->request_method);
1146
1147             g_queue_push_tail(tapinfo->callsinfos, callsinfo);
1148             /* insert the call information in the SIP_HASH */
1149             g_hash_table_insert(tapinfo->callsinfo_hashtable[SIP_HASH],
1150                     tmp_sipinfo->call_identifier, callsinfo);
1151         }
1152     }
1153
1154     if (callsinfo != NULL) {
1155         tmp_sipinfo = (sip_calls_info_t *)callsinfo->prot_info;
1156
1157         /* let's analyze the call state */
1158
1159         copy_address(&(tmp_src), &(pinfo->src));
1160         copy_address(&(tmp_dst), &(pinfo->dst));
1161
1162         if (pi->request_method == NULL) {
1163             frame_label = g_strdup_printf("%u %s", pi->response_code, pi->reason_phrase );
1164             comment = g_strdup_printf("SIP Status %u %s", pi->response_code, pi->reason_phrase );
1165
1166             if ((tmp_sipinfo && pi->tap_cseq_number == tmp_sipinfo->invite_cseq)&&(addresses_equal(&tmp_dst,&(callsinfo->initial_speaker)))) {
1167                 if ((pi->response_code > 199) && (pi->response_code<300) && (tmp_sipinfo->sip_state == SIP_INVITE_SENT)) {
1168                     tmp_sipinfo->sip_state = SIP_200_REC;
1169                 }
1170                 else if ((pi->response_code>299)&&(tmp_sipinfo->sip_state == SIP_INVITE_SENT)) {
1171                     callsinfo->call_state = VOIP_REJECTED;
1172                     tapinfo->rejected_calls++;
1173                 }
1174
1175                 /* UPDATE comment in conversation list dialog with response code and reason.
1176                    Multiple code(+reason) may be appended, so skip over intermediate codes (100 trying, 183 ringing, e.t.c.)
1177 TODO: is useful but not perfect, what is appended is truncated when displayed in dialog window */
1178                 if (pi->response_code >= 200) {
1179                     old_comment = callsinfo->call_comment;
1180                     callsinfo->call_comment=g_strdup_printf("%s %u",
1181                             callsinfo->call_comment,
1182                             pi->response_code/*, pi->reason_phrase*/);
1183
1184                     g_free(old_comment);
1185                 }
1186
1187             }
1188
1189         }
1190         else {
1191             frame_label = g_strdup(pi->request_method);
1192
1193             if ((strcmp(pi->request_method,"INVITE")==0)&&(addresses_equal(&tmp_src,&(callsinfo->initial_speaker)))) {
1194                 tmp_sipinfo->invite_cseq = pi->tap_cseq_number;
1195                 callsinfo->call_state = VOIP_CALL_SETUP;
1196                 /* TODO: sometimes truncated when displayed in dialog window */
1197                 comment = g_strdup_printf("SIP INVITE From: %s To:%s Call-ID:%s CSeq:%d",
1198                         callsinfo->from_identity, callsinfo->to_identity,
1199                         callsinfo->call_id, pi->tap_cseq_number);
1200             }
1201             else if ((strcmp(pi->request_method,"ACK")==0)&&(pi->tap_cseq_number == tmp_sipinfo->invite_cseq)
1202                     &&(addresses_equal(&tmp_src,&(callsinfo->initial_speaker)))&&(tmp_sipinfo->sip_state==SIP_200_REC)
1203                     &&(callsinfo->call_state == VOIP_CALL_SETUP)) {
1204                 callsinfo->call_state = VOIP_IN_CALL;
1205                 comment = g_strdup_printf("SIP Request INVITE ACK 200 CSeq:%d", pi->tap_cseq_number);
1206             }
1207             else if (strcmp(pi->request_method,"BYE")==0) {
1208                 callsinfo->call_state = VOIP_COMPLETED;
1209                 tapinfo->completed_calls++;
1210                 comment = g_strdup_printf("SIP Request BYE CSeq:%d", pi->tap_cseq_number);
1211             }
1212             else if ((strcmp(pi->request_method,"CANCEL")==0)&&(pi->tap_cseq_number == tmp_sipinfo->invite_cseq)
1213                     &&(addresses_equal(&tmp_src,&(callsinfo->initial_speaker)))&&(callsinfo->call_state==VOIP_CALL_SETUP)) {
1214                 callsinfo->call_state = VOIP_CANCELLED;
1215                 tmp_sipinfo->sip_state = SIP_CANCEL_SENT;
1216                 comment = g_strdup_printf("SIP Request CANCEL CSeq:%d", pi->tap_cseq_number);
1217             } else {
1218                 /* comment = g_strdup_printf("SIP %s", pi->request_method); */
1219                 comment = g_strdup_printf("SIP %s From: %s To:%s CSeq:%d",
1220                         pi->request_method,
1221                         callsinfo->from_identity,
1222                         callsinfo->to_identity, pi->tap_cseq_number);
1223             }
1224         }
1225
1226         callsinfo->stop_fd = pinfo->fd;
1227         callsinfo->stop_rel_ts = pinfo->rel_ts;
1228         ++(callsinfo->npackets);
1229         /* increment the packets counter of all calls */
1230         ++(tapinfo->npackets);
1231
1232         /* add to the graph */
1233         add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
1234         g_free(comment);
1235         g_free(frame_label);
1236         free_address(&tmp_src);
1237         free_address(&tmp_dst);
1238
1239         /* add SDP info if apply */
1240         if ( (tapinfo->sdp_summary != NULL) && (tapinfo->sdp_frame_num == pinfo->num) ) {
1241             append_to_frame_graph(tapinfo, pinfo->num, tapinfo->sdp_summary, NULL);
1242             g_free(tapinfo->sdp_summary);
1243             tapinfo->sdp_summary = NULL;
1244         }
1245
1246     }
1247
1248     tapinfo->redraw |= REDRAW_SIP;
1249
1250     return TRUE;  /* refresh output */
1251 }
1252
1253 /****************************************************************************/
1254 static void
1255 sip_calls_draw(void *tap_offset_ptr)
1256 {
1257     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sip_);
1258
1259     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_SIP)) {
1260         tapinfo->tap_draw(tapinfo);
1261         tapinfo->redraw &= ~REDRAW_SIP;
1262     }
1263 }
1264
1265 /****************************************************************************/
1266 /* TAP INTERFACE */
1267 /****************************************************************************/
1268
1269 void
1270 sip_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
1271 {
1272     GString *error_string;
1273
1274     error_string = register_tap_listener("sip", tap_base_to_id(tap_id_base, tap_id_offset_sip_), NULL,
1275             0,
1276             NULL,
1277             sip_calls_packet,
1278             sip_calls_draw
1279             );
1280     if (error_string != NULL) {
1281         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1282                 "%s", error_string->str);
1283         g_string_free(error_string, TRUE);
1284     }
1285 }
1286
1287 /****************************************************************************/
1288 void
1289 remove_tap_listener_sip_calls(voip_calls_tapinfo_t *tap_id_base)
1290 {
1291     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_sip_));
1292 }
1293
1294 /****************************************************************************/
1295 /* ***************************TAP for ISUP **********************************/
1296 /****************************************************************************/
1297
1298 /****************************************************************************/
1299 /* whenever a isup_ packet is seen by the tap listener */
1300 static gboolean
1301 isup_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *isup_info)
1302 {
1303     voip_calls_tapinfo_t *tapinfo     = tap_id_to_base(tap_offset_ptr, tap_id_offset_isup_);
1304     voip_calls_info_t    *tmp_listinfo;
1305     voip_calls_info_t    *callsinfo   = NULL;
1306     isup_calls_info_t    *tmp_isupinfo;
1307     gboolean              found       = FALSE;
1308     gboolean              forward     = FALSE;
1309     gboolean              right_pair;
1310     GList                *list;
1311     gchar                *frame_label = NULL;
1312     gchar                *comment     = NULL;
1313
1314     const isup_tap_rec_t *pi = (const isup_tap_rec_t *)isup_info;
1315
1316     /* check if the lower layer is MTP matching the frame number */
1317     if (tapinfo->mtp3_frame_num != pinfo->num)
1318         return FALSE;
1319
1320     /* check whether we already have a call with these parameters in the list */
1321     list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1322     while (list)
1323     {
1324         right_pair = TRUE;
1325         tmp_listinfo=(voip_calls_info_t *)list->data;
1326         if ((tmp_listinfo->protocol == VOIP_ISUP)&&(tmp_listinfo->call_active_state==VOIP_ACTIVE)) {
1327             tmp_isupinfo = (isup_calls_info_t *)tmp_listinfo->prot_info;
1328             if ((tmp_isupinfo->cic == pi->circuit_id)&&(tmp_isupinfo->ni == tapinfo->mtp3_ni)) {
1329                 if ((tmp_isupinfo->opc == tapinfo->mtp3_opc)&&(tmp_isupinfo->dpc == tapinfo->mtp3_dpc)) {
1330                     forward = TRUE;
1331                 } else if ((tmp_isupinfo->dpc == tapinfo->mtp3_opc)&&(tmp_isupinfo->opc == tapinfo->mtp3_dpc)) {
1332                     forward = FALSE;
1333                 } else {
1334                     right_pair = FALSE;
1335                 }
1336
1337                 if (right_pair) {
1338                     /* if there is an IAM for a call that is not in setup state, that means the previous call in the same
1339                        cic is no longer active */
1340                     if (tmp_listinfo->call_state == VOIP_CALL_SETUP) {
1341                         found = TRUE;
1342                     } else if (pi->message_type != 1) {
1343                         found = TRUE;
1344                     } else {
1345                         tmp_listinfo->call_active_state=VOIP_INACTIVE;
1346                     }
1347                 }
1348
1349                 if (found) {
1350                     callsinfo = (voip_calls_info_t*)(list->data);
1351                     break;
1352                 }
1353             }
1354         }
1355         list = g_list_next (list);
1356     }
1357
1358     /* not in the list? then create a new entry if the message is IAM
1359        -i.e. if this session is a call*/
1360
1361     if ((callsinfo==NULL) &&(pi->message_type==1)) {
1362         callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
1363         callsinfo->call_active_state = VOIP_ACTIVE;
1364         callsinfo->call_state = VOIP_UNKNOWN;
1365         copy_address(&(callsinfo->initial_speaker),&(pinfo->src));
1366         callsinfo->start_fd       = pinfo->fd;
1367         callsinfo->start_rel_ts   = pinfo->rel_ts;
1368         callsinfo->protocol       = VOIP_ISUP;
1369         callsinfo->from_identity  = g_strdup(pi->calling_number);
1370         callsinfo->to_identity    = g_strdup(pi->called_number);
1371         callsinfo->prot_info      = g_malloc(sizeof(isup_calls_info_t));
1372         callsinfo->free_prot_info = g_free;
1373         tmp_isupinfo              = (isup_calls_info_t *)callsinfo->prot_info;
1374         tmp_isupinfo->opc         = tapinfo->mtp3_opc;
1375         tmp_isupinfo->dpc         = tapinfo->mtp3_dpc;
1376         tmp_isupinfo->ni          = tapinfo->mtp3_ni;
1377         tmp_isupinfo->cic         = pi->circuit_id;
1378         callsinfo->npackets       = 0;
1379         callsinfo->call_num       = tapinfo->ncalls++;
1380         g_queue_push_tail(tapinfo->callsinfos, callsinfo);
1381     }
1382
1383
1384     if (callsinfo!=NULL) {
1385         callsinfo->stop_fd = pinfo->fd;
1386         callsinfo->stop_rel_ts = pinfo->rel_ts;
1387         ++(callsinfo->npackets);
1388
1389         /* Let's analyze the call state */
1390
1391         frame_label = g_strdup(val_to_str_ext_const(pi->message_type, &isup_message_type_value_acro_ext, "Unknown"));
1392
1393         if (callsinfo->npackets == 1) { /* this is the first packet, that must be an IAM */
1394
1395             if ((pi->calling_number!=NULL)&&(pi->called_number !=NULL)) {
1396                 comment = g_strdup_printf("Call from %s to %s",
1397                         pi->calling_number, pi->called_number);
1398             }
1399         } else if (callsinfo->npackets == 2) { /* in the second packet we show the SPs */
1400             if (forward) {
1401                 comment = g_strdup_printf("%i-%i -> %i-%i. Cic:%i",
1402                         tapinfo->mtp3_ni, tapinfo->mtp3_opc,
1403                         tapinfo->mtp3_ni, tapinfo->mtp3_dpc, pi->circuit_id);
1404             } else {
1405                 comment = g_strdup_printf("%i-%i -> %i-%i. Cic:%i",
1406                         tapinfo->mtp3_ni, tapinfo->mtp3_dpc,
1407                         tapinfo->mtp3_ni, tapinfo->mtp3_opc, pi->circuit_id);
1408             }
1409         }
1410
1411         switch(pi->message_type) {
1412             case 1: /* IAM */
1413                 callsinfo->call_state=VOIP_CALL_SETUP;
1414                 break;
1415             case 7: /* CONNECT */
1416             case 9: /* ANSWER */
1417                 callsinfo->call_state=VOIP_IN_CALL;
1418                 break;
1419             case 12: /* RELEASE */
1420                 if (callsinfo->call_state==VOIP_CALL_SETUP) {
1421                     if (forward) {
1422                         callsinfo->call_state=VOIP_CANCELLED;
1423                     }
1424                     else {
1425                         callsinfo->call_state=VOIP_REJECTED;
1426                         tapinfo->rejected_calls++;
1427                     }
1428                 }
1429                 else if (callsinfo->call_state == VOIP_IN_CALL) {
1430                     callsinfo->call_state = VOIP_COMPLETED;
1431                     tapinfo->completed_calls++;
1432                 }
1433                 comment = g_strdup_printf("Cause %i - %s",
1434                         pi->cause_value,
1435                         val_to_str_ext_const(pi->cause_value, &q931_cause_code_vals_ext, "(Unknown)"));
1436                 break;
1437         }
1438
1439         /* increment the packets counter of all calls */
1440         ++(tapinfo->npackets);
1441
1442         /* add to the graph */
1443         add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
1444         g_free(comment);
1445         g_free(frame_label);
1446     }
1447
1448     tapinfo->redraw |= REDRAW_ISUP;
1449
1450     return TRUE;  /* refresh output */
1451 }
1452
1453 /****************************************************************************/
1454 static void
1455 isup_calls_draw(void *tap_offset_ptr)
1456 {
1457     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_isup_);
1458
1459     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_ISUP)) {
1460         tapinfo->tap_draw(tapinfo);
1461         tapinfo->redraw &= ~REDRAW_ISUP;
1462     }
1463 }
1464
1465 /****************************************************************************/
1466
1467 void
1468 isup_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
1469 {
1470     GString *error_string;
1471
1472     error_string = register_tap_listener("isup", tap_base_to_id(tap_id_base, tap_id_offset_isup_),
1473             NULL,
1474             0,
1475             NULL,
1476             isup_calls_packet,
1477             isup_calls_draw
1478             );
1479
1480     if (error_string != NULL) {
1481         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1482                 "%s", error_string->str);
1483         g_string_free(error_string, TRUE);
1484     }
1485 }
1486
1487 /****************************************************************************/
1488
1489 void
1490 remove_tap_listener_isup_calls(voip_calls_tapinfo_t *tap_id_base)
1491 {
1492     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_isup_));
1493 }
1494
1495 /****************************************************************************/
1496 /* ***************************TAP for MTP3 **********************************/
1497 /****************************************************************************/
1498
1499
1500 /****************************************************************************/
1501 /* whenever a mtp3_ packet is seen by the tap listener */
1502 static gboolean
1503 mtp3_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt _U_, const void *mtp3_info)
1504 {
1505     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_mtp3_);
1506     const mtp3_tap_rec_t *pi      = (const mtp3_tap_rec_t *)mtp3_info;
1507
1508     /* keep the data in memory to use when the ISUP information arrives */
1509
1510     tapinfo->mtp3_opc = pi->addr_opc.pc;
1511     tapinfo->mtp3_dpc = pi->addr_dpc.pc;
1512     tapinfo->mtp3_ni = pi->addr_opc.ni;
1513     tapinfo->mtp3_frame_num = pinfo->num;
1514
1515     return FALSE;
1516 }
1517
1518 static gboolean
1519 m3ua_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt _U_, const void *mtp3_info)
1520 {
1521     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_m3ua_);
1522     const mtp3_tap_rec_t *pi = (const mtp3_tap_rec_t *)mtp3_info;
1523
1524     /* keep the data in memory to use when the ISUP information arrives */
1525
1526     tapinfo->mtp3_opc = pi->addr_opc.pc;
1527     tapinfo->mtp3_dpc = pi->addr_dpc.pc;
1528     tapinfo->mtp3_ni = pi->addr_opc.ni;
1529     tapinfo->mtp3_frame_num = pinfo->num;
1530
1531     return FALSE;
1532 }
1533
1534 /****************************************************************************/
1535
1536 void
1537 mtp3_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
1538 {
1539     GString *error_string;
1540
1541     error_string = register_tap_listener("mtp3", tap_base_to_id(tap_id_base, tap_id_offset_mtp3_),
1542             NULL,
1543             0,
1544             NULL,
1545             mtp3_calls_packet,
1546             NULL
1547             );
1548
1549     if (error_string != NULL) {
1550         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1551                 "%s", error_string->str);
1552         g_string_free(error_string, TRUE);
1553     }
1554
1555     error_string = register_tap_listener("m3ua", tap_base_to_id(tap_id_base, tap_id_offset_m3ua_),
1556             NULL,
1557             0,
1558             NULL,
1559             m3ua_calls_packet,
1560             NULL
1561             );
1562
1563     if (error_string != NULL) {
1564         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1565                 "%s", error_string->str);
1566         g_string_free(error_string, TRUE);
1567     }
1568
1569 }
1570
1571 /****************************************************************************/
1572
1573 void
1574 remove_tap_listener_mtp3_calls(voip_calls_tapinfo_t *tap_id_base)
1575 {
1576     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_mtp3_));
1577     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_m3ua_));
1578 }
1579
1580 /****************************************************************************/
1581 /* ***************************TAP for Q931 **********************************/
1582 /****************************************************************************/
1583 static void h245_add_to_graph(voip_calls_tapinfo_t *tapinfo, guint32 new_frame_num);
1584 static const e_guid_t guid_allzero = {0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };
1585 /* defines specific H323 data */
1586
1587 /****************************************************************************/
1588 /* whenever a q931_ packet is seen by the tap listener */
1589 static gboolean
1590 q931_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *q931_info)
1591 {
1592     GList                     *list,*list2;
1593     voip_calls_tapinfo_t      *tapinfo   = tap_id_to_base(tap_offset_ptr, tap_id_offset_q931_);
1594     h323_calls_info_t         *tmp_h323info,*tmp2_h323info;
1595     actrace_isdn_calls_info_t *tmp_actrace_isdn_info;
1596     voip_calls_info_t         *tmp_listinfo;
1597     voip_calls_info_t         *callsinfo = NULL;
1598     h245_address_t            *h245_add  = NULL;
1599     gchar                     *comment, *tmp_str;
1600
1601     const q931_packet_info *pi = (const q931_packet_info *)q931_info;
1602
1603     /* free previously allocated q931_calling/ed_number */
1604     g_free(tapinfo->q931_calling_number);
1605     g_free(tapinfo->q931_called_number);
1606
1607     if (pi->calling_number!=NULL)
1608         tapinfo->q931_calling_number = g_strdup(pi->calling_number);
1609     else
1610         tapinfo->q931_calling_number = g_strdup("");
1611
1612     if (pi->called_number!=NULL)
1613         tapinfo->q931_called_number = g_strdup(pi->called_number);
1614     else
1615         tapinfo->q931_called_number = g_strdup("");
1616     tapinfo->q931_cause_value = pi->cause_value;
1617     tapinfo->q931_frame_num = pinfo->num;
1618     tapinfo->q931_crv = pi->crv;
1619
1620
1621     /* add staff to H323 calls */
1622     if (tapinfo->h225_frame_num == tapinfo->q931_frame_num) {
1623         tmp_h323info = NULL;
1624         list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1625         while (list)
1626         {
1627             tmp_listinfo=(voip_calls_info_t *)list->data;
1628             if ( (tmp_listinfo->protocol == VOIP_H323) && (tmp_listinfo->call_num == tapinfo->h225_call_num) ) {
1629                 tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info;
1630                 callsinfo = (voip_calls_info_t*)(list->data);
1631
1632                 /* Add the CRV to the h323 call */
1633                 if (tmp_h323info->q931_crv == -1) {
1634                     tmp_h323info->q931_crv = tapinfo->q931_crv;
1635                 } else if (tmp_h323info->q931_crv != tapinfo->q931_crv) {
1636                     tmp_h323info->q931_crv2 = tapinfo->q931_crv;
1637                 }
1638                 break;
1639             }
1640             list = g_list_next (list);
1641         }
1642
1643         if (callsinfo != NULL) {
1644             comment = NULL;
1645             if (tapinfo->h225_cstype == H225_SETUP) {
1646                 /* set te calling and called number from the Q931 packet */
1647                 if (tapinfo->q931_calling_number != NULL) {
1648                     g_free(callsinfo->from_identity);
1649                     callsinfo->from_identity=g_strdup(tapinfo->q931_calling_number);
1650                 }
1651                 if (tapinfo->q931_called_number != NULL) {
1652                     g_free(callsinfo->to_identity);
1653                     callsinfo->to_identity=g_strdup(tapinfo->q931_called_number);
1654                 }
1655
1656                 /* check if there is an LRQ/LCF that match this Setup */
1657                 /* TODO: we are just checking the DialedNumer in LRQ/LCF against the Setup
1658                    we should also check if the h225 signaling IP and port match the destination
1659                    Setup ip and port */
1660                 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1661                 while (list)
1662                 {
1663                     tmp_listinfo=(voip_calls_info_t *)list->data;
1664                     if (tmp_listinfo->protocol == VOIP_H323) {
1665                         tmp2_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info;
1666
1667                         /* check if the called number match a LRQ/LCF */
1668                         if ( (strcmp(callsinfo->to_identity, tmp_listinfo->to_identity)==0)
1669                                 && (memcmp(tmp2_h323info->guid, &guid_allzero, GUID_LEN) == 0) ) {
1670                             /* change the call graph to the LRQ/LCF to belong to this call */
1671                             callsinfo->npackets += change_call_num_graph(tapinfo, tmp_listinfo->call_num, callsinfo->call_num);
1672
1673                             /* remove this LRQ/LCF call entry because we have found the Setup that match them */
1674                             g_free(tmp_listinfo->from_identity);
1675                             g_free(tmp_listinfo->to_identity);
1676                             DUMP_PTR2(tmp2_h323info->guid);
1677                             g_free(tmp2_h323info->guid);
1678
1679                             list2 = g_list_first(tmp2_h323info->h245_list);
1680                             while (list2)
1681                             {
1682                                 h245_add=(h245_address_t *)list2->data;
1683                                 free_address(&h245_add->h245_address);
1684                                 g_free(list2->data);
1685                                 list2 = g_list_next(list2);
1686                             }
1687                             g_list_free(tmp_h323info->h245_list);
1688                             tmp_h323info->h245_list = NULL;
1689                             g_free(tmp_listinfo->prot_info);
1690                             g_queue_unlink(tapinfo->callsinfos, list);
1691                             break;
1692                         }
1693                     }
1694                     list = g_list_next (list);
1695                 }
1696
1697                 comment = g_strdup_printf("H225 From: %s To:%s  TunnH245:%s FS:%s", callsinfo->from_identity, callsinfo->to_identity, (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
1698                         (tapinfo->h225_is_faststart==TRUE?"on":"off"));
1699             } else if (tapinfo->h225_cstype == H225_RELEASE_COMPLET) {
1700                 /* get the Q931 Release cause code */
1701                 if (tapinfo->q931_cause_value != 0xFF) {
1702                     comment = g_strdup_printf("H225 Q931 Rel Cause (%i):%s", tapinfo->q931_cause_value,
1703                             val_to_str_ext_const(tapinfo->q931_cause_value, &q931_cause_code_vals_ext, "<unknown>"));
1704                 } else { /* Cause not set */
1705                     comment = g_strdup("H225 No Q931 Rel Cause");
1706                 }
1707             }
1708             /* change the graph comment for this new one */
1709             if (comment != NULL) {
1710                 change_frame_graph(tapinfo, tapinfo->h225_frame_num, NULL, comment);
1711                 g_free(comment);
1712             }
1713         }
1714         /* we reset the h225_frame_num to 0 because there could be empty h225 in the same frame
1715            as non empty h225 (e.g connect), so we don't have to be here twice */
1716         tapinfo->h225_frame_num = 0;
1717
1718         /* add staff to H245 */
1719     } else if (tapinfo->h245_labels->frame_num == tapinfo->q931_frame_num) {
1720         /* there are empty H225 frames that don't have guid (guaid=0) but they have h245 info,
1721            so the only way to match those frames is with the Q931 CRV number */
1722         list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1723         while (list)
1724         {
1725             tmp_listinfo=(voip_calls_info_t *)list->data;
1726             if (tmp_listinfo->protocol == VOIP_H323) {
1727                 tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info;
1728                 if ( ((tmp_h323info->q931_crv == tapinfo->q931_crv) || (tmp_h323info->q931_crv2 == tapinfo->q931_crv)) && (tapinfo->q931_crv!=-1)) {
1729                     /* if the frame number exists in graph, append to it*/
1730                     if (!append_to_frame_graph(tapinfo, tapinfo->q931_frame_num, NULL, NULL)) {
1731                         /* if not exist, add to the graph */
1732                         add_to_graph(tapinfo, pinfo, edt, NULL, NULL, tmp_listinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
1733                         ++(tmp_listinfo->npackets);
1734                         /* increment the packets counter of all calls */
1735                         ++(tapinfo->npackets);
1736                     }
1737
1738                     /* Add the H245 info if exists to the Graph */
1739                     h245_add_to_graph(tapinfo, pinfo->num);
1740                     break;
1741                 }
1742             }
1743             list = g_list_next (list);
1744         }
1745     /* SIP-Q */
1746     } else if (tapinfo->sip_frame_num == tapinfo->q931_frame_num) {
1747          /* Do nothing for now */
1748     /* add stuff to ACTRACE */
1749     } else {
1750         address pstn_add;
1751
1752         comment = NULL;
1753         callsinfo = NULL;
1754         list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1755         while (list)
1756         {
1757             tmp_listinfo=(voip_calls_info_t *)list->data;
1758             if ( tmp_listinfo->protocol == VOIP_AC_ISDN ) {
1759                 tmp_actrace_isdn_info = (actrace_isdn_calls_info_t *)tmp_listinfo->prot_info;
1760                 /* TODO: Also check the IP of the Blade, and if the call is complete (no active) */
1761                 if ( (tmp_actrace_isdn_info->crv == tapinfo->q931_crv) && (tmp_actrace_isdn_info->trunk == tapinfo->actrace_trunk) ) {
1762                     callsinfo = (voip_calls_info_t*)(list->data);
1763                     break;
1764                 }
1765             }
1766             list = g_list_next (list);
1767         }
1768
1769         set_address(&pstn_add, AT_STRINGZ, 5, g_strdup("PSTN"));
1770
1771         /* if it is a new call, add it to the list */
1772         if (!callsinfo) {
1773             callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
1774             callsinfo->call_active_state = VOIP_ACTIVE;
1775             callsinfo->call_state = VOIP_CALL_SETUP;
1776             callsinfo->from_identity=g_strdup(tapinfo->q931_calling_number);
1777             callsinfo->to_identity=g_strdup(tapinfo->q931_called_number);
1778             copy_address(&(callsinfo->initial_speaker),tapinfo->actrace_direction?&pstn_add:&(pinfo->src));
1779             callsinfo->start_fd=pinfo->fd;
1780             callsinfo->start_rel_ts=pinfo->rel_ts;
1781             callsinfo->protocol=VOIP_AC_ISDN;
1782             callsinfo->prot_info=g_malloc(sizeof(actrace_isdn_calls_info_t));
1783             callsinfo->free_prot_info = g_free;
1784             tmp_actrace_isdn_info=(actrace_isdn_calls_info_t *)callsinfo->prot_info;
1785             tmp_actrace_isdn_info->crv=tapinfo->q931_crv;
1786             tmp_actrace_isdn_info->trunk=tapinfo->actrace_trunk;
1787             callsinfo->npackets = 0;
1788             callsinfo->call_num = tapinfo->ncalls++;
1789             g_queue_push_tail(tapinfo->callsinfos, callsinfo);
1790         }
1791
1792         callsinfo->stop_fd = pinfo->fd;
1793         callsinfo->stop_rel_ts = pinfo->rel_ts;
1794         ++(callsinfo->npackets);
1795         /* increment the packets counter of all calls */
1796         ++(tapinfo->npackets);
1797
1798         switch(pi->message_type) {
1799             case Q931_SETUP:
1800                 comment = g_strdup_printf("AC_ISDN trunk:%u Calling: %s  Called:%s", tapinfo->actrace_trunk, tapinfo->q931_calling_number, tapinfo->q931_called_number);
1801                 callsinfo->call_state=VOIP_CALL_SETUP;
1802                 break;
1803             case Q931_CONNECT:
1804                 callsinfo->call_state=VOIP_IN_CALL;
1805                 break;
1806             case Q931_RELEASE_COMPLETE:
1807             case Q931_RELEASE:
1808             case Q931_DISCONNECT:
1809                 if (callsinfo->call_state==VOIP_CALL_SETUP) {
1810                     if (addresses_equal(&(callsinfo->initial_speaker), tapinfo->actrace_direction?&pstn_add:&(pinfo->src) )) {  /* forward direction */
1811                         callsinfo->call_state=VOIP_CANCELLED;
1812                     }
1813                     else { /* reverse */
1814                         callsinfo->call_state=VOIP_REJECTED;
1815                         tapinfo->rejected_calls++;
1816                     }
1817                 } else if ( (callsinfo->call_state!=VOIP_CANCELLED) && (callsinfo->call_state!=VOIP_REJECTED) ) {
1818                     callsinfo->call_state=VOIP_COMPLETED;
1819                     tapinfo->completed_calls++;
1820                 }
1821                 if (tapinfo->q931_cause_value != 0xFF) {
1822                     comment = g_strdup_printf("AC_ISDN trunk:%u Q931 Rel Cause (%i):%s", tapinfo->actrace_trunk, tapinfo->q931_cause_value,
1823                             val_to_str_ext_const(tapinfo->q931_cause_value, &q931_cause_code_vals_ext, "<unknown>"));
1824                 } else { /* Cause not set */
1825                     comment = g_strdup("AC_ISDN No Q931 Rel Cause");
1826                 }
1827                 break;
1828         }
1829
1830         if (!comment)
1831             comment = g_strdup_printf("AC_ISDN  trunk:%u", tapinfo->actrace_trunk );
1832
1833         tmp_str = val_to_str_wmem(NULL, pi->message_type, q931_message_type_vals, "<unknown (%d)>");
1834         add_to_graph(tapinfo, pinfo, edt, tmp_str, comment, callsinfo->call_num,
1835                 tapinfo->actrace_direction?&pstn_add:&(pinfo->src),
1836                 tapinfo->actrace_direction?&(pinfo->src):&pstn_add,
1837                 1 );
1838         wmem_free(NULL, tmp_str);
1839
1840         g_free(comment);
1841         free_address(&pstn_add);
1842     }
1843
1844     tapinfo->redraw |= REDRAW_Q931;
1845
1846     return TRUE;  /* refresh output */
1847 }
1848
1849 /****************************************************************************/
1850 static void
1851 q931_calls_draw(void *tap_offset_ptr)
1852 {
1853     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_q931_);
1854
1855     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_Q931)) {
1856         tapinfo->tap_draw(tapinfo);
1857         tapinfo->redraw &= ~REDRAW_Q931;
1858     }
1859 }
1860
1861 /****************************************************************************/
1862
1863 void
1864 q931_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
1865 {
1866     GString *error_string;
1867
1868     error_string = register_tap_listener("q931", tap_base_to_id(tap_id_base, tap_id_offset_q931_),
1869             NULL,
1870             0,
1871             NULL,
1872             q931_calls_packet,
1873             q931_calls_draw
1874             );
1875
1876     if (error_string != NULL) {
1877         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1878                 "%s", error_string->str);
1879         g_string_free(error_string, TRUE);
1880     }
1881 }
1882
1883 /****************************************************************************/
1884
1885 void
1886 remove_tap_listener_q931_calls(voip_calls_tapinfo_t *tap_id_base)
1887 {
1888     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_q931_));
1889 }
1890
1891 /****************************************************************************/
1892 /****************************TAP for H323 ***********************************/
1893 /****************************************************************************/
1894
1895 static void
1896 add_h245_Address(h323_calls_info_t *h323info,  h245_address_t *h245_address)
1897 {
1898     h323info->h245_list = g_list_prepend(h323info->h245_list, h245_address);
1899 }
1900
1901
1902 static void
1903 free_h225_info(gpointer p) {
1904     h323_calls_info_t *tmp_h323info = (h323_calls_info_t *)p;
1905
1906     DUMP_PTR2(tmp_h323info->guid);
1907     g_free(tmp_h323info->guid);
1908
1909     if (tmp_h323info->h245_list) {
1910         GList *list2 = g_list_first(tmp_h323info->h245_list);
1911         while (list2)
1912         {
1913             h245_address_t *h245_add=(h245_address_t *)list2->data;
1914             free_address(&h245_add->h245_address);
1915             g_free(list2->data);
1916             list2 = g_list_next(list2);
1917         }
1918
1919         g_list_free(tmp_h323info->h245_list);
1920
1921     }
1922
1923     g_free(p);
1924 }
1925 /****************************************************************************/
1926 /* whenever a H225 packet is seen by the tap listener */
1927 static gboolean
1928 h225_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *H225info)
1929 {
1930     voip_calls_tapinfo_t *tapinfo      = tap_id_to_base(tap_offset_ptr, tap_id_offset_h225_);
1931     voip_calls_info_t    *tmp_listinfo;
1932     voip_calls_info_t    *callsinfo    = NULL;
1933     h323_calls_info_t    *tmp_h323info = NULL;
1934     gchar                *frame_label;
1935     gchar                *comment;
1936     GList                *list;
1937     h245_address_t       *h245_add     = NULL;
1938
1939     const h225_packet_info *pi = (const h225_packet_info *)H225info;
1940
1941     /* if not guid and RAS and not LRQ, LCF or LRJ return because did not belong to a call */
1942     /* OR, if not guid and is H225 return because doesn't belong to a call */
1943     if ((memcmp(&pi->guid, &guid_allzero, GUID_LEN) == 0))
1944         if ( ((pi->msg_type == H225_RAS) && ((pi->msg_tag < 18) || (pi->msg_tag > 20))) || (pi->msg_type != H225_RAS) )
1945             return FALSE;
1946
1947     /* if it is RAS LCF or LRJ*/
1948     if ( (pi->msg_type == H225_RAS) && ((pi->msg_tag == 19) || (pi->msg_tag == 20))) {
1949         /* if the LCF/LRJ doesn't match to a LRQ, just return */
1950         if (!pi->request_available) return FALSE;
1951
1952         /* check whether we already have a call with this request SeqNum */
1953         list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1954         while (list)
1955         {
1956             tmp_listinfo=(voip_calls_info_t *)list->data;
1957             g_assert(tmp_listinfo != NULL);
1958             if (tmp_listinfo->protocol == VOIP_H323) {
1959                 tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info;
1960                 if (tmp_h323info->requestSeqNum == pi->requestSeqNum) {
1961                     callsinfo = (voip_calls_info_t*)(list->data);
1962                     break;
1963                 }
1964             }
1965             list = g_list_next (list);
1966         }
1967     } else {
1968         /* check whether we already have a call with this guid in the list */
1969         list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1970         while (list)
1971         {
1972             tmp_listinfo=(voip_calls_info_t *)list->data;
1973             if (tmp_listinfo->protocol == VOIP_H323) {
1974                 tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info;
1975                 g_assert(tmp_h323info != NULL);
1976                 if ( (memcmp(tmp_h323info->guid, &guid_allzero, GUID_LEN) != 0) && (memcmp(tmp_h323info->guid, &pi->guid,GUID_LEN)==0) ) {
1977                     callsinfo = (voip_calls_info_t*)(list->data);
1978                     break;
1979                 }
1980             }
1981             list = g_list_next (list);
1982         }
1983     }
1984
1985     tapinfo->h225_cstype = pi->cs_type;
1986     tapinfo->h225_is_faststart = pi->is_faststart;
1987
1988     /* not in the list? then create a new entry */
1989     if (callsinfo==NULL) {
1990         callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
1991         callsinfo->call_active_state = VOIP_ACTIVE;
1992         callsinfo->call_state = VOIP_UNKNOWN;
1993         callsinfo->from_identity=g_strdup("");
1994         callsinfo->to_identity=g_strdup("");
1995         copy_address(&(callsinfo->initial_speaker),&(pinfo->src));
1996         callsinfo->start_fd=pinfo->fd;
1997         callsinfo->start_rel_ts=pinfo->rel_ts;
1998         callsinfo->protocol=VOIP_H323;
1999         callsinfo->prot_info=g_malloc(sizeof(h323_calls_info_t));
2000         callsinfo->free_prot_info = free_h225_info;
2001
2002         tmp_h323info = (h323_calls_info_t *)callsinfo->prot_info;
2003         g_assert(tmp_h323info != NULL);
2004         tmp_h323info->guid = (e_guid_t *)g_memdup(&pi->guid, sizeof pi->guid);
2005         DUMP_PTR1(tmp_h323info->guid);
2006
2007         clear_address(&tmp_h323info->h225SetupAddr);
2008         tmp_h323info->h245_list = NULL;
2009         tmp_h323info->is_faststart_Setup = FALSE;
2010         tmp_h323info->is_faststart_Proc = FALSE;
2011         tmp_h323info->is_h245Tunneling = FALSE;
2012         tmp_h323info->is_h245 = FALSE;
2013         tmp_h323info->q931_crv = -1;
2014         tmp_h323info->q931_crv2 = -1;
2015         tmp_h323info->requestSeqNum = 0;
2016         callsinfo->call_num = tapinfo->ncalls++;
2017         callsinfo->npackets = 0;
2018
2019         g_queue_push_tail(tapinfo->callsinfos, callsinfo);
2020     }
2021
2022     tapinfo->h225_frame_num = pinfo->num;
2023     tapinfo->h225_call_num = callsinfo->call_num;
2024
2025     /* let's analyze the call state */
2026
2027     callsinfo->stop_fd = pinfo->fd;
2028     callsinfo->stop_rel_ts = pinfo->rel_ts;
2029     ++(callsinfo->npackets);
2030     /* increment the packets counter of all calls */
2031     ++(tapinfo->npackets);
2032
2033
2034     /* XXX: it is supposed to be initialized isn't it? */
2035     g_assert(tmp_h323info != NULL);
2036
2037     /* change the status */
2038     if (pi->msg_type == H225_CS) {
2039
2040         /* this is still IPv4 only, because the dissector is */
2041         if (pi->is_h245 == TRUE) {
2042             h245_add = (h245_address_t *)g_malloc(sizeof (h245_address_t));
2043             alloc_address_wmem(NULL, &h245_add->h245_address, AT_IPv4, 4, &pi->h245_address);
2044             h245_add->h245_port = pi->h245_port;
2045             add_h245_Address(tmp_h323info, h245_add);
2046         }
2047
2048         if (pi->cs_type != H225_RELEASE_COMPLET) tmp_h323info->is_h245Tunneling = pi->is_h245Tunneling;
2049
2050         frame_label = g_strdup(pi->frame_label);
2051
2052         switch(pi->cs_type) {
2053             case H225_SETUP:
2054                 tmp_h323info->is_faststart_Setup = pi->is_faststart;
2055
2056                 /* Set the Setup address if it was not set */
2057                 if (tmp_h323info->h225SetupAddr.type == AT_NONE)
2058                     copy_address(&(tmp_h323info->h225SetupAddr), &(pinfo->src));
2059                 callsinfo->call_state=VOIP_CALL_SETUP;
2060                 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
2061                         (pi->is_faststart==TRUE?"on":"off"));
2062                 break;
2063             case H225_CONNECT:
2064                 callsinfo->call_state=VOIP_IN_CALL;
2065                 if (pi->is_faststart == TRUE) tmp_h323info->is_faststart_Proc = TRUE;
2066                 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
2067                         (pi->is_faststart==TRUE?"on":"off"));
2068                 break;
2069             case H225_RELEASE_COMPLET:
2070                 if (callsinfo->call_state==VOIP_CALL_SETUP) {
2071                     if (addresses_equal(&(tmp_h323info->h225SetupAddr),&(pinfo->src))) {  /* forward direction */
2072                         callsinfo->call_state=VOIP_CANCELLED;
2073                     }
2074                     else { /* reverse */
2075                         callsinfo->call_state=VOIP_REJECTED;
2076                         tapinfo->rejected_calls++;
2077                     }
2078                 } else {
2079                     callsinfo->call_state=VOIP_COMPLETED;
2080                     tapinfo->completed_calls++;
2081                 }
2082                 comment = g_strdup("H225 No Q931 Rel Cause");
2083                 break;
2084             case H225_PROGRESS:
2085             case H225_ALERTING:
2086             case H225_CALL_PROCEDING:
2087                 if (pi->is_faststart == TRUE) tmp_h323info->is_faststart_Proc = TRUE;
2088                 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
2089                         (pi->is_faststart==TRUE?"on":"off"));
2090                 break;
2091             default:
2092                 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
2093                         (pi->is_faststart==TRUE?"on":"off"));
2094
2095         }
2096     }
2097     else if (pi->msg_type == H225_RAS) {
2098         switch(pi->msg_tag) {
2099             case 18:  /* LRQ */
2100                 if (!pi->is_duplicate) {
2101                     g_free(callsinfo->to_identity);
2102                     callsinfo->to_identity=g_strdup(pi->dialedDigits);
2103                     tmp_h323info->requestSeqNum = pi->requestSeqNum;
2104                 }
2105                 /* Fall Through */
2106             case 19: /* LCF */
2107                 if (strlen(pi->dialedDigits))
2108                     comment = g_strdup_printf("H225 RAS dialedDigits: %s", pi->dialedDigits);
2109                 else
2110                     comment = g_strdup("H225 RAS");
2111                 break;
2112             default:
2113                 comment = g_strdup("H225 RAS");
2114         }
2115         frame_label = g_strdup(val_to_str_const(pi->msg_tag, h225_RasMessage_vals, "<unknown>"));
2116     } else {
2117         frame_label = g_strdup("H225: Unknown");
2118         comment = NULL;
2119     }
2120
2121     /* add to graph analysis */
2122
2123     /* if the frame number exists in graph, append to it*/
2124     if (!append_to_frame_graph(tapinfo, pinfo->num, pi->frame_label, comment)) {
2125         /* if not exist, add to the graph */
2126         add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
2127     }
2128
2129     /* Add the H245 info if exists to the Graph */
2130     h245_add_to_graph(tapinfo, pinfo->num);
2131
2132     g_free(frame_label);
2133     g_free(comment);
2134
2135     tapinfo->redraw |= REDRAW_H225;
2136
2137     return TRUE;  /* refresh output */
2138 }
2139
2140 /****************************************************************************/
2141 static void
2142 h225_calls_draw(void *tap_offset_ptr)
2143 {
2144     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_h225_);
2145
2146     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_H225)) {
2147         tapinfo->tap_draw(tapinfo);
2148         tapinfo->redraw &= ~REDRAW_H225;
2149     }
2150 }
2151
2152 /****************************************************************************/
2153 /* TAP INTERFACE */
2154 /****************************************************************************/
2155 void
2156 h225_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
2157 {
2158     GString *error_string;
2159
2160     error_string = register_tap_listener("h225", tap_base_to_id(tap_id_base, tap_id_offset_h225_), NULL,
2161             0,
2162             NULL,
2163             h225_calls_packet,
2164             h225_calls_draw
2165             );
2166
2167     if (error_string != NULL) {
2168         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2169                 "%s", error_string->str);
2170         g_string_free(error_string, TRUE);
2171     }
2172 }
2173
2174 /****************************************************************************/
2175 void
2176 remove_tap_listener_h225_calls(voip_calls_tapinfo_t *tap_id_base)
2177 {
2178     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_h225_));
2179 }
2180
2181 /* Add the h245 label info to the graph */
2182 void
2183 h245_add_to_graph(voip_calls_tapinfo_t *tapinfo, guint32 new_frame_num)
2184 {
2185     gint8 n;
2186
2187     if (new_frame_num != tapinfo->h245_labels->frame_num) return;
2188
2189     for (n=0; n<tapinfo->h245_labels->labels_count; n++) {
2190         append_to_frame_graph(tapinfo, new_frame_num, tapinfo->h245_labels->labels[n].frame_label, tapinfo->h245_labels->labels[n].comment);
2191         g_free(tapinfo->h245_labels->labels[n].frame_label);
2192         tapinfo->h245_labels->labels[n].frame_label = NULL;
2193         g_free(tapinfo->h245_labels->labels[n].comment);
2194         tapinfo->h245_labels->labels[n].comment = NULL;
2195     }
2196     tapinfo->h245_labels->frame_num = 0;
2197     tapinfo->h245_labels->labels_count = 0;
2198 }
2199
2200 /* free the h245_labels if the frame number is different */
2201 static void
2202 h245_free_labels(voip_calls_tapinfo_t *tapinfo, guint32 new_frame_num)
2203 {
2204     gint8 n;
2205
2206     if (new_frame_num == tapinfo->h245_labels->frame_num) return;
2207
2208     for (n=0; n<tapinfo->h245_labels->labels_count; n++) {
2209         g_free(tapinfo->h245_labels->labels[n].frame_label);
2210         tapinfo->h245_labels->labels[n].frame_label = NULL;
2211         g_free(tapinfo->h245_labels->labels[n].comment);
2212         tapinfo->h245_labels->labels[n].comment = NULL;
2213     }
2214     tapinfo->h245_labels->frame_num = 0;
2215     tapinfo->h245_labels->labels_count = 0;
2216 }
2217
2218 /* add the frame_label and comment to h245_labels and free the actual one if it is different frame num */
2219 static void
2220 h245_add_label(voip_calls_tapinfo_t *tapinfo, guint32 new_frame_num, const gchar *frame_label, const gchar *comment)
2221 {
2222     h245_free_labels(tapinfo, new_frame_num);
2223
2224     tapinfo->h245_labels->frame_num = new_frame_num;
2225     tapinfo->h245_labels->labels[tapinfo->h245_labels->labels_count].frame_label = g_strdup(frame_label);
2226     tapinfo->h245_labels->labels[tapinfo->h245_labels->labels_count].comment = g_strdup(comment);
2227
2228     if (tapinfo->h245_labels->labels_count < (H245_MAX-1))
2229         tapinfo->h245_labels->labels_count++;
2230
2231 }
2232
2233 /****************************************************************************/
2234 /* whenever a H245dg packet is seen by the tap listener (when H245 tunneling is ON) */
2235 static gboolean
2236 h245dg_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *H245info)
2237 {
2238     voip_calls_tapinfo_t *tapinfo   = tap_id_to_base(tap_offset_ptr, tap_id_offset_h245dg_);
2239     voip_calls_info_t    *tmp_listinfo;
2240     voip_calls_info_t    *callsinfo = NULL;
2241     h323_calls_info_t    *tmp_h323info;
2242     GList                *list;
2243     GList                *list2;
2244     h245_address_t       *h245_add  = NULL;
2245
2246     const h245_packet_info *pi = (const h245_packet_info *)H245info;
2247
2248     /* check if Tunneling is OFF and we have a call with this H245 add */
2249     list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
2250     while (list)
2251     {
2252         tmp_listinfo=(voip_calls_info_t *)list->data;
2253         if (tmp_listinfo->protocol == VOIP_H323) {
2254             tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info;
2255
2256             list2 = g_list_first(tmp_h323info->h245_list);
2257             while (list2)
2258             {
2259                 h245_add=(h245_address_t *)list2->data;
2260                 if ( (addresses_equal(&(h245_add->h245_address),&(pinfo->src)) && (h245_add->h245_port == pinfo->srcport))
2261                         || (addresses_equal(&(h245_add->h245_address),&(pinfo->dst)) && (h245_add->h245_port == pinfo->destport)) ) {
2262                     callsinfo = (voip_calls_info_t*)(list->data);
2263
2264                     ++(callsinfo->npackets);
2265                     /* increment the packets counter of all calls */
2266                     ++(tapinfo->npackets);
2267
2268                     break;
2269                 }
2270                 list2 = g_list_next(list2);
2271             }
2272             if (callsinfo!=NULL) break;
2273         }
2274         list = g_list_next(list);
2275     }
2276
2277     /* Tunnel is OFF, and we matched the h245 add so we add it to graph */
2278     if (callsinfo!=NULL) {
2279         ++(callsinfo->npackets);
2280         /* increment the packets counter of all calls */
2281         ++(tapinfo->npackets);
2282         /* if the frame number exists in graph, append to it*/
2283         if (!append_to_frame_graph(tapinfo, pinfo->num, pi->frame_label, pi->comment)) {
2284             /* if not exist, add to the graph */
2285             add_to_graph(tapinfo, pinfo, edt, pi->frame_label, pi->comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
2286         }
2287     } else {
2288         /* Tunnel is ON, so we save the label info to use it into h225 or q931 tap. OR may be
2289            tunnel OFF but we did not matched the h245 add, in this case nobady will set this label
2290            since the frame_num will not match */
2291
2292         h245_add_label(tapinfo, pinfo->num, pi->frame_label, pi->comment);
2293     }
2294
2295     tapinfo->redraw |= REDRAW_H245DG;
2296
2297     return TRUE;  /* refresh output */
2298 }
2299
2300 /****************************************************************************/
2301 static void
2302 h245dg_calls_draw(void *tap_offset_ptr)
2303 {
2304     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_h245dg_);
2305
2306     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_H245DG)) {
2307         tapinfo->tap_draw(tapinfo);
2308         tapinfo->redraw &= ~REDRAW_H245DG;
2309     }
2310 }
2311
2312 /****************************************************************************/
2313 /* TAP INTERFACE */
2314 /****************************************************************************/
2315 void
2316 h245dg_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
2317 {
2318     GString *error_string;
2319
2320     if (!tap_id_base->h245_labels) {
2321         tap_id_base->h245_labels = g_new0(h245_labels_t, 1);
2322     }
2323
2324     error_string = register_tap_listener("h245dg", tap_base_to_id(tap_id_base, tap_id_offset_h245dg_), NULL,
2325             0,
2326             NULL,
2327             h245dg_calls_packet,
2328             h245dg_calls_draw
2329             );
2330
2331     if (error_string != NULL) {
2332         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2333                 "%s", error_string->str);
2334         g_string_free(error_string, TRUE);
2335     }
2336 }
2337
2338 /****************************************************************************/
2339 void
2340 remove_tap_listener_h245dg_calls(voip_calls_tapinfo_t *tap_id_base)
2341 {
2342     if (tap_id_base->h245_labels) {
2343         g_free(tap_id_base->h245_labels);
2344         tap_id_base->h245_labels = NULL;
2345     }
2346     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_h245dg_));
2347 }
2348
2349 /****************************************************************************/
2350 /****************************TAP for SDP PROTOCOL ***************************/
2351 /****************************************************************************/
2352 /* whenever a SDP packet is seen by the tap listener */
2353 static gboolean
2354 sdp_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt _U_, const void *SDPinfo)
2355 {
2356     voip_calls_tapinfo_t  *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sdp_);
2357     const sdp_packet_info *pi      = (const sdp_packet_info *)SDPinfo;
2358
2359     /* There are protocols like MGCP/SIP where the SDP is called before the tap for the
2360        MGCP/SIP packet, in those cases we assign the SPD summary to global lastSDPsummary
2361        to use it later
2362      */
2363     g_free(tapinfo->sdp_summary);
2364     tapinfo->sdp_frame_num = pinfo->num;
2365     /* Append to graph the SDP summary if the packet exists */
2366     tapinfo->sdp_summary = g_strdup_printf("SDP (%s)", pi->summary_str);
2367     append_to_frame_graph(tapinfo, pinfo->num, tapinfo->sdp_summary, NULL);
2368
2369     tapinfo->redraw |= REDRAW_SDP;
2370
2371     return TRUE;  /* refresh output */
2372 }
2373
2374 /****************************************************************************/
2375 static void
2376 sdp_calls_draw(void *tap_offset_ptr)
2377 {
2378     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sdp_);
2379
2380     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_SDP)) {
2381         tapinfo->tap_draw(tapinfo);
2382         tapinfo->redraw &= ~REDRAW_SDP;
2383     }
2384 }
2385
2386 /****************************************************************************/
2387 /* TAP INTERFACE */
2388 /****************************************************************************/
2389 void
2390 sdp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
2391 {
2392     GString *error_string;
2393
2394     error_string = register_tap_listener("sdp", tap_base_to_id(tap_id_base, tap_id_offset_sdp_), NULL,
2395             0,
2396             NULL,
2397             sdp_calls_packet,
2398             sdp_calls_draw
2399             );
2400
2401     if (error_string != NULL) {
2402         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2403                 "%s", error_string->str);
2404         g_string_free(error_string, TRUE);
2405     }
2406 }
2407
2408 /****************************************************************************/
2409 void
2410 remove_tap_listener_sdp_calls(voip_calls_tapinfo_t *tap_id_base)
2411 {
2412     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_sdp_));
2413 }
2414
2415 /****************************************************************************/
2416 /* ***************************TAP for MGCP **********************************/
2417 /****************************************************************************/
2418
2419 /*
2420    This function will look for a signal/event in the SignalReq/ObsEvent string
2421    and return true if it is found
2422 */
2423 static gboolean
2424 is_mgcp_signal(const gchar *signal_str_p, const gchar *signalStr)
2425 {
2426     gint    i;
2427     gchar **resultArray;
2428
2429     /* if there is no signalStr, just return false */
2430     if (signalStr == NULL) return FALSE;
2431
2432     /* if are both "blank" return true */
2433     if ( (*signal_str_p == '\0') &&  (*signalStr == '\0') ) return TRUE;
2434
2435     /* look for signal in signalStr */
2436     resultArray = g_strsplit(signalStr, ",", 10);
2437
2438     for (i = 0; resultArray[i]; i++) {
2439         g_strstrip(resultArray[i]);
2440         if (strcmp(resultArray[i], signal_str_p) == 0) return TRUE;
2441     }
2442
2443     g_strfreev(resultArray);
2444
2445     return FALSE;
2446 }
2447
2448 /*
2449    This function will get the Caller ID info and replace the current string
2450    This is how it looks the caller Id: rg, ci(02/16/08/29, "3035550002","Ale Sipura 2")
2451 */
2452 static void
2453 mgcp_caller_id(gchar *signalStr, gchar **callerId)
2454 {
2455     gchar **arrayStr;
2456
2457     /* if there is no signalStr, just return false */
2458     if (signalStr == NULL) return;
2459
2460     arrayStr = g_strsplit(signalStr, "\"", 3);
2461
2462     /* look for the ci signal */
2463     if (g_strv_length(arrayStr) == 3 && strstr(arrayStr[0], "ci(")) {
2464         /* free the previous "From" field of the call, and assign the new */
2465         g_free(*callerId);
2466         *callerId = g_strdup(arrayStr[1]);
2467     }
2468     g_strfreev(arrayStr);
2469 }
2470
2471 /*
2472    This function will get the Dialed Digits and replace the current string
2473    This is how it looks the dialed digits 5,5,5,0,0,0,2,#,*
2474 */
2475 static void
2476 mgcp_dialed_digits(gchar *signalStr, gchar **dialedDigits)
2477 {
2478     gchar *tmpStr;
2479     gchar *resultStr;
2480     gint   i,j;
2481
2482     /* start with 1 for the null-terminator */
2483     guint resultStrLen = 1;
2484
2485     /* if there is no signalStr, just return false */
2486     if (signalStr == NULL) return;
2487
2488     tmpStr = g_strdup(signalStr);
2489
2490     for ( i = 0 ; tmpStr[i] ; i++) {
2491         switch (tmpStr[i]) {
2492             case '0' : case '1' : case '2' : case '3' : case '4' :
2493             case '5' : case '6' : case '7' : case '8' : case '9' :
2494             case '#' : case '*' :
2495                 resultStrLen++;
2496                 break;
2497             default:
2498                 tmpStr[i] = '?';
2499                 break;
2500         }
2501     }
2502
2503     if (resultStrLen == 1) {
2504         g_free(tmpStr);
2505         return;
2506     }
2507
2508     resultStr = (gchar *)g_malloc(resultStrLen);
2509
2510     for (i = 0, j = 0; tmpStr[i]; i++) {
2511         if (tmpStr[i] != '?')
2512             resultStr[j++] = tmpStr[i];
2513     }
2514     resultStr[j] = '\0';
2515
2516     g_free(*dialedDigits);
2517     g_free(tmpStr);
2518
2519     *dialedDigits = resultStr;
2520
2521     return;
2522 }
2523
2524
2525
2526 /****************************************************************************/
2527 /* whenever a MGCP packet is seen by the tap listener */
2528 static gboolean
2529 mgcp_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *MGCPinfo)
2530 {
2531     voip_calls_tapinfo_t *tapinfo      = tap_id_to_base(tap_offset_ptr, tap_id_offset_mgcp_);
2532     voip_calls_info_t    *tmp_listinfo;
2533     voip_calls_info_t    *callsinfo    = NULL;
2534     mgcp_calls_info_t    *tmp_mgcpinfo = NULL;
2535     GList                *list;
2536     GList                *listGraph    = NULL;
2537     gchar                *frame_label  = NULL;
2538     gchar                *comment      = NULL;
2539     seq_analysis_item_t  *gai          = NULL;
2540     gboolean              newcall      = FALSE;
2541     gboolean              fromEndpoint = FALSE; /* true for calls originated in Endpoints, false for calls from MGC */
2542     gdouble               diff_time;
2543
2544     const mgcp_info_t *pi = (const mgcp_info_t *)MGCPinfo;
2545
2546
2547     if ((pi->mgcp_type == MGCP_REQUEST) && !pi->is_duplicate ) {
2548         /* check whether we already have a call with this Endpoint and it is active*/
2549         list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
2550         while (list)
2551         {
2552             tmp_listinfo=(voip_calls_info_t *)list->data;
2553             if ((tmp_listinfo->protocol == VOIP_MGCP) && (tmp_listinfo->call_active_state == VOIP_ACTIVE)) {
2554                 tmp_mgcpinfo = (mgcp_calls_info_t *)tmp_listinfo->prot_info;
2555                 if (pi->endpointId != NULL) {
2556                     if (g_ascii_strcasecmp(tmp_mgcpinfo->endpointId,pi->endpointId) == 0) {
2557                         /*
2558                            check first if it is an ended call. We can still match packets to this Endpoint 2 seconds
2559                            after the call has been released
2560                          */
2561                         diff_time = nstime_to_sec(&pinfo->rel_ts) - nstime_to_sec(&tmp_listinfo->stop_rel_ts);
2562                         if ( ((tmp_listinfo->call_state == VOIP_CANCELLED) ||
2563                                     (tmp_listinfo->call_state == VOIP_COMPLETED)  ||
2564                                     (tmp_listinfo->call_state == VOIP_REJECTED)) &&
2565                                 (diff_time > 2) )
2566                         {
2567                             tmp_listinfo->call_active_state = VOIP_INACTIVE;
2568                         } else {
2569                             callsinfo = (voip_calls_info_t*)(list->data);
2570                             break;
2571                         }
2572                     }
2573                 }
2574             }
2575             list = g_list_next (list);
2576         }
2577
2578         /* there is no call with this Endpoint, lets see if this a new call or not */
2579         if (callsinfo == NULL) {
2580             if ( (strcmp(pi->code, "NTFY") == 0) && is_mgcp_signal("hd", pi->observedEvents) ) { /* off hook transition */
2581                 /* this is a new call from the Endpoint */
2582                 fromEndpoint = TRUE;
2583                 newcall = TRUE;
2584             } else if (strcmp(pi->code, "CRCX") == 0) {
2585                 /* this is a new call from the MGC */
2586                 fromEndpoint = FALSE;
2587                 newcall = TRUE;
2588             }
2589             if (!newcall) return FALSE;
2590         }
2591     } else if ( ((pi->mgcp_type == MGCP_RESPONSE) && pi->request_available) ||
2592             ((pi->mgcp_type == MGCP_REQUEST) && pi->is_duplicate) ) {
2593         /* if it is a response OR if it is a duplicated Request, lets look in the Graph to see
2594            if there is a request that matches */
2595         if(tapinfo->graph_analysis){
2596             listGraph = g_queue_peek_nth_link(tapinfo->graph_analysis->items, 0);
2597         }
2598         while (listGraph)
2599         {
2600             gai = (seq_analysis_item_t *)listGraph->data;
2601             if (gai->frame_number == pi->req_num) {
2602                 /* there is a request that match, so look the associated call with this call_num */
2603                 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
2604                 while (list)
2605                 {
2606                     tmp_listinfo=(voip_calls_info_t *)list->data;
2607                     if (tmp_listinfo->protocol == VOIP_MGCP) {
2608                         if (tmp_listinfo->call_num == gai->conv_num) {
2609                             tmp_mgcpinfo = (mgcp_calls_info_t *)tmp_listinfo->prot_info;
2610                             callsinfo = (voip_calls_info_t*)(list->data);
2611                             break;
2612                         }
2613                     }
2614                     list = g_list_next (list);
2615                 }
2616                 if (callsinfo != NULL) break;
2617             }
2618             listGraph = g_list_next(listGraph);
2619         }
2620         /* if there is not a matching request, just return */
2621         if (callsinfo == NULL) return FALSE;
2622     } else return FALSE;
2623
2624     /* not in the list? then create a new entry */
2625     if (callsinfo==NULL) {
2626         callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
2627         callsinfo->call_active_state = VOIP_ACTIVE;
2628         callsinfo->call_state = VOIP_CALL_SETUP;
2629         if (fromEndpoint) {
2630             callsinfo->from_identity=g_strdup(pi->endpointId);
2631             callsinfo->to_identity=g_strdup("");
2632         } else {
2633             callsinfo->from_identity=g_strdup("");
2634             callsinfo->to_identity=g_strdup(pi->endpointId);
2635         }
2636         copy_address(&(callsinfo->initial_speaker),&(pinfo->src));
2637         callsinfo->start_fd=pinfo->fd;
2638         callsinfo->start_rel_ts=pinfo->rel_ts;
2639         callsinfo->protocol=VOIP_MGCP;
2640         callsinfo->prot_info=g_malloc(sizeof(mgcp_calls_info_t));
2641         callsinfo->free_prot_info = g_free;
2642         tmp_mgcpinfo=(mgcp_calls_info_t *)callsinfo->prot_info;
2643         tmp_mgcpinfo->endpointId = g_strdup(pi->endpointId);
2644         tmp_mgcpinfo->fromEndpoint = fromEndpoint;
2645         callsinfo->npackets = 0;
2646         callsinfo->call_num = tapinfo->ncalls++;
2647         g_queue_push_tail(tapinfo->callsinfos, callsinfo);
2648     }
2649
2650     g_assert(tmp_mgcpinfo != NULL);
2651
2652     /* change call state and add to graph */
2653     switch (pi->mgcp_type)
2654     {
2655         case MGCP_REQUEST:
2656             if ( (strcmp(pi->code, "NTFY") == 0) && (pi->observedEvents != NULL) ) {
2657                 frame_label = g_strdup_printf("%s ObsEvt:%s",pi->code, pi->observedEvents);
2658
2659                 if (tmp_mgcpinfo->fromEndpoint) {
2660                     /* use the Dialed digits to fill the "To" for the call, but use the first NTFY */
2661                     if (callsinfo->to_identity[0] == '\0') mgcp_dialed_digits(pi->observedEvents, &(callsinfo->to_identity));
2662
2663                     /* from MGC and the user picked up, the call is connected */
2664                 } else if (is_mgcp_signal("hd", pi->observedEvents))
2665                     callsinfo->call_state=VOIP_IN_CALL;
2666
2667                 /* hung up signal */
2668                 if (is_mgcp_signal("hu", pi->observedEvents)) {
2669                     if ((callsinfo->call_state == VOIP_CALL_SETUP) || (callsinfo->call_state == VOIP_RINGING)) {
2670                         callsinfo->call_state = VOIP_CANCELLED;
2671                     } else {
2672                         callsinfo->call_state = VOIP_COMPLETED;
2673                     }
2674                 }
2675
2676             } else if (strcmp(pi->code, "RQNT") == 0) {
2677                 /* for calls from Endpoint: if there is a "no signal" RQNT and the call was RINGING, we assume this is the CONNECT */
2678                 if ( tmp_mgcpinfo->fromEndpoint && is_mgcp_signal("", pi->signalReq) && (callsinfo->call_state == VOIP_RINGING) ) {
2679                     callsinfo->call_state = VOIP_IN_CALL;
2680                 }
2681
2682                 /* if there is ringback or ring tone, change state to ringing */
2683                 if ( is_mgcp_signal("rg", pi->signalReq) || is_mgcp_signal("rt", pi->signalReq) ) {
2684                     callsinfo->call_state = VOIP_RINGING;
2685                 }
2686
2687                 /* if there is a Busy or ReorderTone, and the call was Ringing or Setup the call is Rejected */
2688                 if ( (is_mgcp_signal("ro", pi->signalReq) || is_mgcp_signal("bz", pi->signalReq)) && ((callsinfo->call_state == VOIP_CALL_SETUP) || (callsinfo->call_state == VOIP_RINGING)) ) {
2689                     callsinfo->call_state = VOIP_REJECTED;
2690                 }
2691
2692                 if (pi->signalReq != NULL)
2693                     frame_label = g_strdup_printf("%s%sSigReq:%s",pi->code, (pi->hasDigitMap == TRUE)?" DigitMap ":"", pi->signalReq);
2694                 else
2695                     frame_label = g_strdup_printf("%s%s",pi->code, (pi->hasDigitMap == TRUE)?" DigitMap ":"");
2696
2697                 /* use the CallerID info to fill the "From" for the call */
2698                 if (!tmp_mgcpinfo->fromEndpoint) mgcp_caller_id(pi->signalReq, &(callsinfo->from_identity));
2699
2700             } else if (strcmp(pi->code, "DLCX") == 0) {
2701                 /*
2702                    if there is a DLCX in a call To an Endpoint and the call was not connected, we use
2703                    the DLCX as the end of the call
2704                  */
2705                 if (!tmp_mgcpinfo->fromEndpoint) {
2706                     if ((callsinfo->call_state == VOIP_CALL_SETUP) || (callsinfo->call_state == VOIP_RINGING)) {
2707                         callsinfo->call_state = VOIP_CANCELLED;
2708                     }
2709                 }
2710             }
2711
2712             if (frame_label == NULL) frame_label = g_strdup(pi->code);
2713             break;
2714         case MGCP_RESPONSE:
2715             frame_label = g_strdup_printf("%u (%s)",pi->rspcode, pi->code);
2716             break;
2717         case MGCP_OTHERS:
2718             /* XXX what to do? */
2719             break;
2720     }
2721
2722     comment = g_strdup_printf("MGCP %s %s%s", tmp_mgcpinfo->endpointId, (pi->mgcp_type == MGCP_REQUEST)?"Request":"Response", pi->is_duplicate?" Duplicate":"");
2723
2724     callsinfo->stop_fd = pinfo->fd;
2725     callsinfo->stop_rel_ts = pinfo->rel_ts;
2726     ++(callsinfo->npackets);
2727     /* increment the packets counter of all calls */
2728     ++(tapinfo->npackets);
2729
2730     /* add to the graph */
2731     add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
2732     g_free(comment);
2733     g_free(frame_label);
2734
2735     /* add SDP info if apply */
2736     if ( (tapinfo->sdp_summary != NULL) && (tapinfo->sdp_frame_num == pinfo->num) ) {
2737         append_to_frame_graph(tapinfo, pinfo->num, tapinfo->sdp_summary, NULL);
2738         g_free(tapinfo->sdp_summary);
2739         tapinfo->sdp_summary = NULL;
2740     }
2741
2742     tapinfo->redraw |= REDRAW_MGCP;
2743
2744     return TRUE;  /* refresh output */
2745 }
2746
2747 /****************************************************************************/
2748 static void
2749 mgcp_calls_draw(void *tap_offset_ptr)
2750 {
2751     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_mgcp_);
2752
2753     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_MGCP)) {
2754         tapinfo->tap_draw(tapinfo);
2755         tapinfo->redraw &= ~REDRAW_MGCP;
2756     }
2757 }
2758
2759 /****************************************************************************/
2760 /* TAP INTERFACE */
2761 /****************************************************************************/
2762 void
2763 mgcp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
2764 {
2765     GString *error_string;
2766
2767     /*
2768      * We set TL_REQUIRES_PROTO_TREE to force a non-null "tree"
2769      * in the MGCP dissector; otherwise, the dissector
2770      * doesn't fill in the info passed to the tap's packet
2771      * routine.
2772      */
2773     error_string = register_tap_listener("mgcp",
2774             tap_base_to_id(tap_id_base, tap_id_offset_mgcp_),
2775             NULL,
2776             TL_REQUIRES_PROTO_TREE,
2777             NULL,
2778             mgcp_calls_packet,
2779             mgcp_calls_draw
2780             );
2781     if (error_string != NULL) {
2782         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2783                 "%s", error_string->str);
2784         g_string_free(error_string, TRUE);
2785     }
2786 }
2787
2788 /****************************************************************************/
2789 void
2790 remove_tap_listener_mgcp_calls(voip_calls_tapinfo_t *tap_id_base)
2791 {
2792     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_mgcp_));
2793 }
2794
2795 /****************************************************************************/
2796 /****************************TAP for ACTRACE (AudioCodes trace)**************/
2797 /****************************************************************************/
2798
2799 /* whenever a ACTRACE packet is seen by the tap listener */
2800 static gboolean
2801 actrace_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *ACTRACEinfo)
2802 {
2803     voip_calls_tapinfo_t     *tapinfo   = tap_id_to_base(tap_offset_ptr, tap_id_offset_actrace_);
2804     const actrace_info_t     *pi        = (const actrace_info_t *)ACTRACEinfo;
2805     GList                    *list;
2806     actrace_cas_calls_info_t *tmp_actrace_cas_info;
2807     voip_calls_info_t        *tmp_listinfo;
2808     voip_calls_info_t        *callsinfo = NULL;
2809
2810     tapinfo->actrace_frame_num = pinfo->num;
2811     tapinfo->actrace_trunk = pi->trunk;
2812     tapinfo->actrace_direction = pi->direction;
2813
2814     if (pi->type == 1) { /* is CAS protocol */
2815         address pstn_add;
2816         gchar *comment = NULL;
2817
2818         callsinfo = NULL;
2819         list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
2820         while (list)
2821         {
2822             tmp_listinfo=(voip_calls_info_t *)list->data;
2823             if ( tmp_listinfo->protocol == VOIP_AC_CAS ) {
2824                 tmp_actrace_cas_info = (actrace_cas_calls_info_t *)tmp_listinfo->prot_info;
2825                 /* TODO: Also check the IP of the Blade, and if the call is complete (no active) */
2826                 if ( (tmp_actrace_cas_info->bchannel == pi->cas_bchannel) && (tmp_actrace_cas_info->trunk == tapinfo->actrace_trunk) ) {
2827                     callsinfo = (voip_calls_info_t*)(list->data);
2828                     break;
2829                 }
2830             }
2831             list = g_list_next (list);
2832         }
2833
2834         set_address(&pstn_add, AT_STRINGZ, 5, "PSTN");
2835
2836         /* if it is a new call, add it to the list */
2837         if (!callsinfo) {
2838             callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
2839             callsinfo->call_active_state = VOIP_ACTIVE;
2840             callsinfo->call_state = VOIP_CALL_SETUP;
2841             callsinfo->from_identity=g_strdup("N/A");
2842             callsinfo->to_identity=g_strdup("N/A");
2843             copy_address(&(callsinfo->initial_speaker),tapinfo->actrace_direction?&pstn_add:&(pinfo->src));
2844             callsinfo->start_fd=pinfo->fd;
2845             callsinfo->start_rel_ts=pinfo->rel_ts;
2846             callsinfo->protocol=VOIP_AC_CAS;
2847             callsinfo->prot_info=g_malloc(sizeof(actrace_cas_calls_info_t));
2848             callsinfo->free_prot_info = g_free;
2849
2850             tmp_actrace_cas_info=(actrace_cas_calls_info_t *)callsinfo->prot_info;
2851             tmp_actrace_cas_info->bchannel=pi->cas_bchannel;
2852             tmp_actrace_cas_info->trunk=tapinfo->actrace_trunk;
2853             callsinfo->npackets = 0;
2854             callsinfo->call_num = tapinfo->ncalls++;
2855             g_queue_push_tail(tapinfo->callsinfos, callsinfo);
2856         }
2857
2858         callsinfo->stop_fd = pinfo->fd;
2859         callsinfo->stop_rel_ts = pinfo->rel_ts;
2860         ++(callsinfo->npackets);
2861         /* increment the packets counter of all calls */
2862         ++(tapinfo->npackets);
2863
2864         comment = g_strdup_printf("AC_CAS  trunk:%u", tapinfo->actrace_trunk);
2865
2866         add_to_graph(tapinfo, pinfo, edt, pi->cas_frame_label, comment, callsinfo->call_num,
2867                 tapinfo->actrace_direction?&pstn_add:&(pinfo->src),
2868                 tapinfo->actrace_direction?&(pinfo->src):&pstn_add,
2869                 1 );
2870
2871         g_free(comment);
2872     }
2873
2874     tapinfo->redraw |= REDRAW_ACTRACE;
2875
2876     return TRUE;  /* refresh output */
2877 }
2878
2879 /****************************************************************************/
2880 static void
2881 actrace_calls_draw(void *tap_offset_ptr)
2882 {
2883     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_actrace_);
2884
2885     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_ACTRACE)) {
2886         tapinfo->tap_draw(tapinfo);
2887         tapinfo->redraw &= ~REDRAW_ACTRACE;
2888     }
2889 }
2890
2891 /****************************************************************************/
2892 /* TAP INTERFACE */
2893 /****************************************************************************/
2894 void
2895 actrace_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
2896 {
2897     GString *error_string;
2898
2899     error_string = register_tap_listener("actrace", tap_base_to_id(tap_id_base, tap_id_offset_actrace_), NULL,
2900             0,
2901             NULL,
2902             actrace_calls_packet,
2903             actrace_calls_draw
2904             );
2905
2906     if (error_string != NULL) {
2907         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2908                 "%s", error_string->str);
2909         g_string_free(error_string, TRUE);
2910     }
2911 }
2912
2913 /****************************************************************************/
2914 void
2915 remove_tap_listener_actrace_calls(voip_calls_tapinfo_t *tap_id_base)
2916 {
2917     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_actrace_));
2918 }
2919
2920
2921 /****************************************************************************/
2922 /**************************** TAP for H248/MEGACO **********************************/
2923 /****************************************************************************/
2924
2925 #define gcp_is_req(type) ( type == GCP_CMD_ADD_REQ || type == GCP_CMD_MOVE_REQ || type == GCP_CMD_MOD_REQ || \
2926                            type == GCP_CMD_SUB_REQ || type == GCP_CMD_AUDITCAP_REQ || type == GCP_CMD_AUDITVAL_REQ || \
2927                            type == GCP_CMD_NOTIFY_REQ || type == GCP_CMD_SVCCHG_REQ || type == GCP_CMD_TOPOLOGY_REQ || \
2928                            type == GCP_CMD_CTX_ATTR_AUDIT_REQ )
2929
2930
2931 static gboolean
2932 h248_calls_packet_common(voip_calls_tapinfo_t *tapinfo, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info, guint32 redraw_bit) {
2933     const gcp_cmd_t      *cmd       = (const gcp_cmd_t *)prot_info;
2934     GList                *list;
2935     voip_calls_info_t    *callsinfo = NULL;
2936     address              *mgw;
2937     address              *mgc;
2938     gchar                 mgw_addr[128];
2939
2940     if (cmd->ctx->id == NULL_CONTEXT || cmd->ctx->id == ALL_CONTEXTS ) {
2941         return FALSE;
2942     }
2943
2944     if ( gcp_is_req(cmd->type) ) {
2945         mgw = &(pinfo->dst);
2946         mgc = &(pinfo->src);
2947     } else {
2948         mgc = &(pinfo->dst);
2949         mgw = &(pinfo->src);
2950     }
2951
2952     address_to_str_buf(mgw, mgw_addr, 128);
2953
2954     /* check whether we already have this context in the list */
2955     list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
2956     while (list)
2957     {
2958         voip_calls_info_t* tmp_listinfo = (voip_calls_info_t *)list->data;
2959
2960         if (tmp_listinfo->protocol == TEL_H248) {
2961             if (tmp_listinfo->prot_info == cmd->ctx) {
2962                 callsinfo = (voip_calls_info_t*)(list->data);
2963                 break;
2964             }
2965         }
2966         list = g_list_next (list);
2967     }
2968
2969     if (callsinfo==NULL) {
2970
2971         callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
2972         callsinfo->call_state = VOIP_NO_STATE;
2973         callsinfo->call_active_state = VOIP_ACTIVE;
2974         callsinfo->from_identity = g_strdup_printf("%s : %.8x", mgw_addr, cmd->ctx->id);
2975         callsinfo->to_identity = g_strdup("");
2976         callsinfo->prot_info = cmd->ctx;
2977         callsinfo->free_prot_info = NULL;
2978
2979         callsinfo->npackets = 1;
2980
2981         copy_address(&(callsinfo->initial_speaker), mgc);
2982
2983         callsinfo->protocol = TEL_H248;
2984         callsinfo->call_num = tapinfo->ncalls++;
2985         callsinfo->start_fd = pinfo->fd;
2986         callsinfo->start_rel_ts = pinfo->rel_ts;
2987         callsinfo->stop_fd = pinfo->fd;
2988         callsinfo->stop_rel_ts = pinfo->rel_ts;
2989
2990         g_queue_push_tail(tapinfo->callsinfos, callsinfo);
2991
2992     } else {
2993         GString *s = g_string_new("");
2994         gcp_terms_t *ctx_term;
2995
2996         g_free(callsinfo->from_identity);
2997         callsinfo->from_identity = g_strdup_printf("%s : %.8x", mgw_addr, ((gcp_ctx_t*)callsinfo->prot_info)->id);
2998
2999         g_free(callsinfo->to_identity);
3000
3001         for (ctx_term = ((gcp_ctx_t*)callsinfo->prot_info)->terms.next;
3002                 ctx_term;
3003                 ctx_term = ctx_term->next ) {
3004             if ( ctx_term->term && ctx_term->term->str) {
3005                 g_string_append_printf(s," %s",ctx_term->term->str);
3006             }
3007         }
3008
3009         callsinfo->to_identity = g_string_free(s,FALSE);
3010
3011         callsinfo->stop_fd = pinfo->fd;
3012         callsinfo->stop_rel_ts = pinfo->rel_ts;
3013         ++(callsinfo->npackets);
3014     }
3015
3016     add_to_graph(tapinfo, pinfo, edt, cmd->str ? cmd->str : "unknown Msg",
3017             wmem_strdup_printf(wmem_packet_scope(), "TrxId = %u, CtxId = %.8x",cmd->trx->id,cmd->ctx->id),
3018             callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3019
3020     ++(tapinfo->npackets);
3021
3022     tapinfo->redraw |= redraw_bit;
3023
3024     return TRUE;
3025 }
3026
3027 static gboolean
3028 h248_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info) {
3029     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_h248_);
3030
3031     return h248_calls_packet_common(tapinfo, pinfo, edt, prot_info, REDRAW_H248);
3032 }
3033
3034 static void
3035 h248_calls_draw(void *tap_offset_ptr)
3036 {
3037     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_h248_);
3038
3039     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_H248)) {
3040         tapinfo->tap_draw(tapinfo);
3041         tapinfo->redraw &= ~REDRAW_H248;
3042     }
3043 }
3044
3045 static gboolean
3046 megaco_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info) {
3047     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_megaco_);
3048
3049     return h248_calls_packet_common(tapinfo, pinfo, edt, prot_info, REDRAW_MEGACO);
3050 }
3051
3052 static void
3053 megaco_calls_draw(void *tap_offset_ptr)
3054 {
3055     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_megaco_);
3056
3057     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_MEGACO)) {
3058         tapinfo->tap_draw(tapinfo);
3059         tapinfo->redraw &= ~REDRAW_MEGACO;
3060     }
3061 }
3062
3063 void
3064 h248_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
3065 {
3066     GString *error_string;
3067
3068     error_string = register_tap_listener("megaco", tap_base_to_id(tap_id_base, tap_id_offset_megaco_),
3069             NULL,
3070             0,
3071             NULL,
3072             megaco_calls_packet,
3073             megaco_calls_draw);
3074
3075     if (error_string != NULL) {
3076         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3077                 "%s", error_string->str);
3078         g_string_free(error_string, TRUE);
3079     }
3080
3081     error_string = register_tap_listener("h248", tap_base_to_id(tap_id_base, tap_id_offset_h248_),
3082             NULL,
3083             0,
3084             NULL,
3085             h248_calls_packet,
3086             h248_calls_draw);
3087
3088     if (error_string != NULL) {
3089         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3090                 "%s", error_string->str);
3091         g_string_free(error_string, TRUE);
3092     }
3093 }
3094
3095 void
3096 remove_tap_listener_h248_calls(voip_calls_tapinfo_t *tap_id_base)
3097 {
3098     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_h248_));
3099     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_megaco_));
3100 }
3101
3102 /****************************************************************************/
3103 /**************************** TAP for SCCP and SUA **********************************/
3104 /**************************** ( RANAP and BSSAP ) **********************************/
3105 /****************************************************************************/
3106
3107 static const voip_protocol sccp_proto_map[] = {
3108     TEL_SCCP,
3109     TEL_BSSMAP,
3110     TEL_RANAP
3111 };
3112 #define SP2VP(ap) ((ap) < SCCP_PLOAD_NUM_PLOADS ? sccp_proto_map[(ap)] : TEL_SCCP)
3113 const value_string* sccp_payload_values;
3114
3115 static gboolean
3116 sccp_calls(voip_calls_tapinfo_t *tapinfo, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info, guint32 redraw_bit) {
3117     const sccp_msg_info_t*  msg       = (const sccp_msg_info_t *)prot_info;
3118     sccp_assoc_info_t*      assoc     = msg->data.co.assoc;
3119     GList                  *list;
3120     voip_calls_info_t      *callsinfo = NULL;
3121     gchar                  *label     = NULL;
3122     const gchar            *comment   = NULL;
3123     /* check whether we already have this assoc in the list */
3124
3125     for(list = g_queue_peek_nth_link(tapinfo->callsinfos, 0) ; list ; list = g_list_next (list) ) {
3126         if ( ((voip_calls_info_t*)(list->data))->prot_info == assoc ) {
3127             callsinfo = (voip_calls_info_t*)(list->data);
3128             break;
3129         }
3130     }
3131
3132     if (callsinfo==NULL) {
3133         callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
3134         callsinfo->call_state = VOIP_CALL_SETUP;
3135         callsinfo->call_active_state = VOIP_ACTIVE;
3136         if ( assoc->calling_party ) {
3137             callsinfo->from_identity =  g_strdup(assoc->calling_party);
3138         } else {
3139             callsinfo->from_identity =  g_strdup("Unknown");
3140         }
3141
3142         if ( assoc->called_party ) {
3143             callsinfo->to_identity =  g_strdup(assoc->called_party);
3144         } else {
3145             callsinfo->to_identity =  g_strdup("Unknown");
3146         }
3147
3148         callsinfo->prot_info = (void*)assoc;
3149         callsinfo->free_prot_info = NULL;
3150
3151         callsinfo->npackets = 1;
3152
3153         copy_address(&(callsinfo->initial_speaker), &(pinfo->src));
3154
3155         callsinfo->protocol =   SP2VP(assoc->payload);
3156         /* Store frame data which holds time and frame number */
3157         callsinfo->start_fd = pinfo->fd;
3158         callsinfo->start_rel_ts = pinfo->rel_ts;
3159         callsinfo->stop_fd = pinfo->fd;
3160         callsinfo->stop_rel_ts = pinfo->rel_ts;
3161
3162         callsinfo->call_num = tapinfo->ncalls++;
3163
3164         g_queue_push_tail(tapinfo->callsinfos, callsinfo);
3165     } else {
3166
3167         if ( assoc->calling_party ) {
3168             g_free(callsinfo->from_identity);
3169             callsinfo->from_identity =  g_strdup(assoc->calling_party);
3170         }
3171
3172         if ( assoc->called_party ) {
3173             g_free(callsinfo->to_identity);
3174             callsinfo->to_identity =  g_strdup(assoc->called_party);
3175         }
3176
3177         callsinfo->protocol =  SP2VP(assoc->payload);
3178         /* Store frame data which holds stop time and frame number */
3179         callsinfo->stop_fd = pinfo->fd;
3180         callsinfo->stop_rel_ts = pinfo->rel_ts;
3181         ++(callsinfo->npackets);
3182
3183         switch (msg->type) {
3184             case SCCP_MSG_TYPE_CC:
3185                 callsinfo->call_state = VOIP_IN_CALL;
3186                 break;
3187             case SCCP_MSG_TYPE_RLC:
3188                 callsinfo->call_state = VOIP_COMPLETED;
3189                 callsinfo->call_active_state = VOIP_INACTIVE;
3190                 break;
3191             default:
3192                 break;
3193         }
3194     }
3195
3196     if (msg->data.co.label) {
3197         label = wmem_strdup(NULL, msg->data.co.label);
3198     } else {
3199         label = val_to_str_wmem(NULL, msg->type, sccp_payload_values, "Unknown(%d)");
3200     }
3201
3202     if (msg->data.co.comment) {
3203         comment = msg->data.co.comment;
3204     } else {
3205         comment = NULL;
3206     }
3207
3208     add_to_graph(tapinfo, pinfo, edt, label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3209     wmem_free(NULL, label);
3210
3211     ++(tapinfo->npackets);
3212
3213     tapinfo->redraw |= redraw_bit;
3214
3215     return TRUE;
3216 }
3217
3218 static gboolean
3219 sccp_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info) {
3220     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sccp_);
3221
3222     sccp_payload_values = sccp_message_type_acro_values;
3223     return sccp_calls(tapinfo, pinfo, edt, prot_info, REDRAW_SCCP);
3224 }
3225
3226 static void
3227 sccp_calls_draw(void *tap_offset_ptr)
3228 {
3229     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sccp_);
3230
3231     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_SCCP)) {
3232         tapinfo->tap_draw(tapinfo);
3233         tapinfo->redraw &= ~REDRAW_SCCP;
3234     }
3235 }
3236
3237 static gboolean
3238 sua_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info) {
3239     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sua_);
3240
3241     sccp_payload_values = sua_co_class_type_acro_values;
3242     return sccp_calls(tapinfo, pinfo, edt, prot_info, REDRAW_SUA);
3243 }
3244
3245 static void
3246 sua_calls_draw(void *tap_offset_ptr)
3247 {
3248     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sua_);
3249
3250     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_SUA)) {
3251         tapinfo->tap_draw(tapinfo);
3252         tapinfo->redraw &= ~REDRAW_SUA;
3253     }
3254 }
3255
3256 void sccp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
3257 {
3258     GString *error_string;
3259
3260     error_string = register_tap_listener("sccp", tap_base_to_id(tap_id_base, tap_id_offset_sccp_),
3261             NULL,
3262             0,
3263             NULL,
3264             sccp_calls_packet,
3265             sccp_calls_draw);
3266
3267     if (error_string != NULL) {
3268         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3269                 "%s", error_string->str);
3270         g_string_free(error_string, TRUE);
3271     }
3272
3273     error_string = register_tap_listener("sua", tap_base_to_id(tap_id_base, tap_id_offset_sua_),
3274             NULL,
3275             0,
3276             NULL,
3277             sua_calls_packet,
3278             sua_calls_draw);
3279
3280     if (error_string != NULL) {
3281         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3282                 "%s", error_string->str);
3283         g_string_free(error_string, TRUE);
3284     }
3285 }
3286
3287 void
3288 remove_tap_listener_sccp_calls(voip_calls_tapinfo_t *tap_id_base)
3289 {
3290     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_sccp_));
3291     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_sua_));
3292 }
3293
3294
3295 /****************************************************************************/
3296 /****************************TAP for UNISTIM ********************************/
3297 /****************************************************************************/
3298
3299 static gboolean
3300 unistim_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *unistim_info)
3301 {
3302     voip_calls_tapinfo_t *tapinfo          = tap_id_to_base(tap_offset_ptr, tap_id_offset_unistim_);
3303     voip_calls_info_t    *tmp_listinfo;
3304     voip_calls_info_t    *callsinfo        = NULL;
3305     unistim_info_t       *tmp_unistim_info = NULL;
3306     GList                *list             = NULL;
3307     GString              *g_tmp            = NULL;
3308     const gchar          *frame_label      = NULL;
3309     gchar                *comment          = NULL;
3310
3311     /* Fetch specific packet infos */
3312     const unistim_info_t *pi = (const unistim_info_t *)unistim_info;
3313
3314     /* Init gstring */
3315     g_tmp = g_string_new(NULL);
3316
3317     /* Check to see if this is a dup */
3318     list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
3319
3320     while(list)
3321     {
3322         tmp_listinfo = (voip_calls_info_t *)list->data;
3323
3324         if(tmp_listinfo->protocol == VOIP_UNISTIM) {
3325
3326             tmp_unistim_info = (unistim_info_t *)tmp_listinfo->prot_info;
3327
3328             /* Search by termid if possible, otherwise use ni/it ip + port.. */
3329             if(pi->termid != 0) {
3330                 if(tmp_unistim_info->termid == pi->termid) {
3331                     /* If the call has ended, then we can reuse it.. */
3332                     if(tmp_listinfo->call_state == VOIP_COMPLETED || tmp_listinfo->call_state == VOIP_UNKNOWN) {
3333                         /* Do nothing */
3334                     } else {
3335                         callsinfo = (voip_calls_info_t*)(list->data);
3336                         break;
3337                     }
3338                 }
3339             } else {
3340                 /* If no term id use ips / port to find entry */
3341                 if(addresses_equal(&tmp_unistim_info->it_ip, &pinfo->dst) && addresses_equal(&tmp_unistim_info->ni_ip,&pinfo->src) && (tmp_unistim_info->it_port == pinfo->destport)) {
3342                     if(tmp_listinfo->call_state == VOIP_COMPLETED || tmp_listinfo->call_state == VOIP_UNKNOWN) {
3343                         /* Do nothing previous call */
3344                     } else {
3345                         callsinfo = (voip_calls_info_t*)(list->data);
3346                         break;
3347                     }
3348                 }
3349                 else if(addresses_equal(&tmp_unistim_info->it_ip, &pinfo->src) && addresses_equal(&tmp_unistim_info->ni_ip,&pinfo->dst) && (tmp_unistim_info->it_port == pinfo->srcport)) {
3350                     if(tmp_listinfo->call_state == VOIP_COMPLETED || tmp_listinfo->call_state == VOIP_UNKNOWN) {
3351                         /* Do nothing, it ain't our call.. */
3352                     } else {
3353                         callsinfo = (voip_calls_info_t*)(list->data);
3354                         break;
3355                     }
3356                 }
3357             }
3358         }
3359
3360         /* Otherwise, go to the next one.. */
3361         list = g_list_next(list);
3362     }
3363
3364     if(pi->payload_type == 2 || pi->payload_type == 1) {
3365
3366         if(pi->key_state == 1 || pi->hook_state == 1) {
3367
3368             /* If the user hits a button,
3369                Session will be SETUP */
3370
3371             /* If new add to list */
3372             if (callsinfo==NULL) {
3373
3374                 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
3375                 callsinfo->call_active_state = VOIP_ACTIVE;
3376                 callsinfo->call_state = VOIP_CALL_SETUP;
3377                 callsinfo->from_identity=g_strdup_printf("%x",pi->termid);
3378                 callsinfo->to_identity=g_strdup("UNKNOWN");
3379                 copy_address(&(callsinfo->initial_speaker),&(pinfo->src));
3380
3381                 /* Set this on init of struct so in case the call doesn't complete, we'll have a ref. */
3382                 /* Otherwise if the call is completed we'll have the open/close streams to ref actual call duration */
3383                 /* Store frame data which holds time and frame number */
3384                 callsinfo->start_fd=pinfo->fd;
3385                 callsinfo->start_rel_ts=pinfo->rel_ts;
3386
3387                 callsinfo->protocol=VOIP_UNISTIM;
3388                 callsinfo->prot_info=g_malloc(sizeof(unistim_info_t));
3389
3390                 tmp_unistim_info = (unistim_info_t *)callsinfo->prot_info;
3391
3392                 /* Clear tap struct */
3393                 tmp_unistim_info->rudp_type = 0;
3394                 tmp_unistim_info->payload_type = 0;
3395                 tmp_unistim_info->sequence = pi->sequence;
3396                 tmp_unistim_info->termid = pi->termid;
3397                 tmp_unistim_info->key_val = -1;
3398                 tmp_unistim_info->key_state = -1;
3399                 tmp_unistim_info->hook_state = -1;
3400                 tmp_unistim_info->stream_connect = -1;
3401                 tmp_unistim_info->trans_connect = -1;
3402                 tmp_unistim_info->set_termid = -1;
3403                 tmp_unistim_info->string_data = NULL;
3404                 tmp_unistim_info->key_buffer = NULL;
3405
3406                 copy_address(&(tmp_unistim_info->it_ip),&(pi->it_ip));
3407                 copy_address(&(tmp_unistim_info->ni_ip),&(pi->ni_ip));
3408                 tmp_unistim_info->it_port = pi->it_port;
3409
3410                 callsinfo->free_prot_info = g_free;
3411                 callsinfo->npackets = 0;
3412                 callsinfo->call_num = tapinfo->ncalls++;
3413                 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
3414
3415             } else {
3416
3417                 /* Set up call wide info struct */
3418                 tmp_unistim_info = (unistim_info_t *)callsinfo->prot_info;
3419                 tmp_unistim_info->sequence = pi->sequence;
3420             }
3421
3422             /* Each packet COULD BE OUR LAST!!!! */
3423             /* Store frame data which holds time and frame number */
3424             callsinfo->stop_fd = pinfo->fd;
3425             callsinfo->stop_rel_ts = pinfo->rel_ts;
3426
3427             /* This is a valid packet so increment counter */
3428             ++(callsinfo->npackets);
3429
3430             /* increment the packets counter of all calls */
3431             ++(tapinfo->npackets);
3432
3433             /* Key was depressed.. update key buffer.. */
3434             if(pi->key_val >= 0 && pi->key_val <=&n