4432a60f73a448a38987363f33195584991745c3
[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->selected=FALSE;
938             callsinfo->start_fd = pinfo->fd;
939             callsinfo->start_rel_ts = pinfo->rel_ts;
940             callsinfo->protocol=MEDIA_T38;
941             callsinfo->prot_info=NULL;
942             callsinfo->free_prot_info = NULL;
943             callsinfo->npackets = 0;
944             callsinfo->call_num = tapinfo->ncalls++;
945             g_queue_push_tail(tapinfo->callsinfos, callsinfo);
946         }
947         callsinfo->stop_fd = pinfo->fd;
948         callsinfo->stop_rel_ts = pinfo->rel_ts;
949         ++(callsinfo->npackets);
950         /* increment the packets counter of all calls */
951         ++(tapinfo->npackets);
952
953         conv_num = (int) callsinfo->call_num;
954     }
955
956     /* at this point we should have found the call num for this t38 packets belong */
957     if (conv_num == -1) {
958         return FALSE;
959     }
960
961     /* add the item to the graph list */
962     if (t38_info->type_msg == 0) { /* 0=t30-indicator */
963         tmp_str1 = val_to_str_wmem(NULL, t38_info->t30ind_value, t38_T30_indicator_vals, "Ukn (0x%02X)");
964         frame_label = g_strdup(tmp_str1);
965         comment = g_strdup_printf("t38:t30 Ind:%s", tmp_str1);
966         wmem_free(NULL, tmp_str1);
967         line_style = 1;
968     } else if (t38_info->type_msg == 1) {  /* 1=data */
969         switch(t38_info->Data_Field_field_type_value) {
970             case 0: /* hdlc-data */
971                 break;
972             case 2: /* hdlc-fcs-OK */
973             case 4: /* hdlc-fcs-OK-sig-end */
974                 tmp_str1 = val_to_str_ext_wmem(NULL, t38_info->t30_Facsimile_Control & 0x7F,
975                             &t30_facsimile_control_field_vals_short_ext,
976                             "Ukn (0x%02X)");
977                 frame_label = g_strdup_printf("%s %s",
978                         tmp_str1,
979                         t38_info->desc);
980                 wmem_free(NULL, tmp_str1);
981
982                 tmp_str1 = val_to_str_ext_wmem(NULL, t38_info->t30_Facsimile_Control & 0x7F,
983                             &t30_facsimile_control_field_vals_ext,
984                             "Ukn (0x%02X)");
985                 tmp_str2 = val_to_str_wmem(NULL, t38_info->data_value,
986                             t38_T30_data_vals,
987                             "Ukn (0x%02X)");
988                 comment      = g_strdup_printf("t38:%s:HDLC:%s", tmp_str2, tmp_str1);
989                 wmem_free(NULL, tmp_str1);
990                 wmem_free(NULL, tmp_str2);
991                 break;
992             case 3: /* hdlc-fcs-BAD */
993             case 5: /* hdlc-fcs-BAD-sig-end */
994                 frame_label = g_strdup(t38_info->Data_Field_field_type_value == 3 ? "fcs-BAD" : "fcs-BAD-sig-end");
995                 tmp_str1    = val_to_str_wmem(NULL, t38_info->data_value, t38_T30_data_vals, "Ukn (0x%02X)");
996                 comment    = g_strdup_printf("WARNING: received t38:%s:HDLC:%s",
997                         tmp_str1,
998                         t38_info->Data_Field_field_type_value == 3 ? "fcs-BAD" : "fcs-BAD-sig-end");
999                 wmem_free(NULL, tmp_str1);
1000                 break;
1001             case 7: /* t4-non-ecm-sig-end */
1002                 duration = nstime_to_sec(&pinfo->rel_ts) - t38_info->time_first_t4_data;
1003                 tmp_str1    = val_to_str_wmem(NULL, t38_info->data_value, t38_T30_data_vals, "Ukn (0x%02X)");
1004                 frame_label = g_strdup_printf("t4-non-ecm-data:%s", tmp_str1);
1005                 comment     = g_strdup_printf("t38:t4-non-ecm-data:%s Duration: %.2fs %s",
1006                         tmp_str1, duration, t38_info->desc_comment );
1007                 insert_to_graph_t38(tapinfo, pinfo, edt, frame_label, comment,
1008                         (guint16)conv_num, &(pinfo->src), &(pinfo->dst),
1009                         line_style, t38_info->frame_num_first_t4_data);
1010                 wmem_free(NULL, tmp_str1);
1011                 break;
1012         }
1013     }
1014
1015     if (frame_label && !(t38_info->Data_Field_field_type_value == 7 && t38_info->type_msg == 1)) {
1016         add_to_graph(tapinfo, pinfo, edt, frame_label, comment, (guint16)conv_num, &(pinfo->src), &(pinfo->dst), line_style);
1017     }
1018
1019     g_free(comment);
1020     g_free(frame_label);
1021
1022     tapinfo->redraw |= REDRAW_T38;
1023
1024     return TRUE;  /* refresh output */
1025 }
1026
1027 /****************************************************************************/
1028 static void
1029 t38_draw(void *tap_offset_ptr)
1030 {
1031     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_t38_);
1032
1033     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_T38)) {
1034         tapinfo->tap_draw(tapinfo);
1035         tapinfo->redraw &= ~REDRAW_T38;
1036     }
1037 }
1038
1039 /****************************************************************************/
1040 void
1041 t38_init_tap(voip_calls_tapinfo_t *tap_id_base)
1042 {
1043     GString *error_string;
1044
1045     error_string = register_tap_listener("t38", tap_base_to_id(tap_id_base, tap_id_offset_t38_), NULL,
1046             0,
1047             NULL,
1048             t38_packet,
1049             t38_draw
1050             );
1051     if (error_string != NULL) {
1052         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1053                 "%s", error_string->str);
1054         g_string_free(error_string, TRUE);
1055     }
1056 }
1057
1058 /****************************************************************************/
1059 void
1060 remove_tap_listener_t38(voip_calls_tapinfo_t *tap_id_base)
1061 {
1062     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_t38_));
1063 }
1064
1065
1066 /****************************************************************************/
1067 /* ***************************TAP for SIP **********************************/
1068 /****************************************************************************/
1069
1070 static void
1071 free_sip_info(gpointer p) {
1072     sip_calls_info_t *si = (sip_calls_info_t *)p;
1073
1074     g_free(si->call_identifier);
1075     g_free(si);
1076 }
1077
1078 /****************************************************************************/
1079 /* whenever a SIP packet is seen by the tap listener */
1080 static gboolean
1081 sip_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt , const void *SIPinfo)
1082 {
1083     voip_calls_tapinfo_t *tapinfo     = tap_id_to_base(tap_offset_ptr, tap_id_offset_sip_);
1084     /* we just take note of the ISUP data here; when we receive the MTP3 part everything will
1085        be compared with existing calls */
1086
1087     voip_calls_info_t    *callsinfo   = NULL;
1088     sip_calls_info_t     *tmp_sipinfo = NULL;
1089     address               tmp_src, tmp_dst;
1090     gchar                *frame_label = NULL;
1091     gchar                *comment     = NULL;
1092     gchar                *old_comment = NULL;
1093     gchar                *key         = NULL;
1094
1095     const sip_info_value_t *pi = (const sip_info_value_t *)SIPinfo;
1096
1097     tapinfo->sip_frame_num = pinfo->num;
1098
1099     /* do not consider packets without call_id */
1100     if (pi->tap_call_id ==NULL) {
1101         return FALSE;
1102     }
1103     key=pi->tap_call_id;
1104     /* init the hash table */
1105     if(NULL==tapinfo->callsinfo_hashtable[SIP_HASH]) {
1106         /* TODO: check how efficient g_str_hash is for sip call ids */
1107         tapinfo->callsinfo_hashtable[SIP_HASH]=g_hash_table_new_full(g_str_hash,
1108                 g_str_equal,
1109                 NULL, /* key_destroy_func */
1110                 NULL);/* value_destroy_func */
1111     }
1112     /* search the call information in the SIP_HASH */
1113     callsinfo = (voip_calls_info_t *)g_hash_table_lookup(tapinfo->callsinfo_hashtable[SIP_HASH], key);
1114
1115     /* Create a new flow entry if the message is INVITE in case of FLOW_ONLY_INVITES,
1116        Create a new flow entry for all messages which have a method in case of FLOW_ALL.
1117        Flows for REGISTER, OPTIONS, MESSAGE and other SIP methods can be seen. */
1118
1119     if ((callsinfo==NULL) && (pi->request_method!=NULL)) {
1120
1121         /* check VoIPcalls_get_flow_show_option() == FLOW_ALL or FLOW_ONLY_INVITES */
1122
1123         if (tapinfo->fs_option == FLOW_ALL ||
1124                 (tapinfo->fs_option == FLOW_ONLY_INVITES &&
1125                  strcmp(pi->request_method,"INVITE")==0)) {
1126             callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
1127             callsinfo->call_active_state = VOIP_ACTIVE;
1128             callsinfo->call_state = VOIP_CALL_SETUP;
1129             callsinfo->from_identity=g_strdup(pi->tap_from_addr);
1130             callsinfo->to_identity=g_strdup(pi->tap_to_addr);
1131             copy_address(&(callsinfo->initial_speaker),&(pinfo->src));
1132             callsinfo->selected=FALSE;
1133             callsinfo->start_fd=pinfo->fd;
1134             callsinfo->start_rel_ts=pinfo->rel_ts;
1135             callsinfo->protocol=VOIP_SIP;
1136             callsinfo->prot_info=g_malloc(sizeof(sip_calls_info_t));
1137             callsinfo->free_prot_info = free_sip_info;
1138             callsinfo->call_id = g_strdup(pi->tap_call_id);
1139             tmp_sipinfo = (sip_calls_info_t *)callsinfo->prot_info;
1140             tmp_sipinfo->call_identifier = g_strdup(pi->tap_call_id);
1141             tmp_sipinfo->sip_state = SIP_INVITE_SENT;
1142             tmp_sipinfo->invite_cseq = pi->tap_cseq_number;
1143             callsinfo->npackets = 0;
1144             callsinfo->call_num = tapinfo->ncalls++;
1145
1146             /* show method in comment in conversation list dialog, user can discern different conversation types */
1147             callsinfo->call_comment=g_strdup(pi->request_method);
1148
1149             g_queue_push_tail(tapinfo->callsinfos, callsinfo);
1150             /* insert the call information in the SIP_HASH */
1151             g_hash_table_insert(tapinfo->callsinfo_hashtable[SIP_HASH],
1152                     tmp_sipinfo->call_identifier, callsinfo);
1153         }
1154     }
1155
1156     if (callsinfo != NULL) {
1157         tmp_sipinfo = (sip_calls_info_t *)callsinfo->prot_info;
1158
1159         /* let's analyze the call state */
1160
1161         copy_address(&(tmp_src), &(pinfo->src));
1162         copy_address(&(tmp_dst), &(pinfo->dst));
1163
1164         if (pi->request_method == NULL) {
1165             frame_label = g_strdup_printf("%u %s", pi->response_code, pi->reason_phrase );
1166             comment = g_strdup_printf("SIP Status %u %s", pi->response_code, pi->reason_phrase );
1167
1168             if ((tmp_sipinfo && pi->tap_cseq_number == tmp_sipinfo->invite_cseq)&&(addresses_equal(&tmp_dst,&(callsinfo->initial_speaker)))) {
1169                 if ((pi->response_code > 199) && (pi->response_code<300) && (tmp_sipinfo->sip_state == SIP_INVITE_SENT)) {
1170                     tmp_sipinfo->sip_state = SIP_200_REC;
1171                 }
1172                 else if ((pi->response_code>299)&&(tmp_sipinfo->sip_state == SIP_INVITE_SENT)) {
1173                     callsinfo->call_state = VOIP_REJECTED;
1174                     tapinfo->rejected_calls++;
1175                 }
1176
1177                 /* UPDATE comment in conversation list dialog with response code and reason.
1178                    Multiple code(+reason) may be appended, so skip over intermediate codes (100 trying, 183 ringing, e.t.c.)
1179 TODO: is useful but not perfect, what is appended is truncated when displayed in dialog window */
1180                 if (pi->response_code >= 200) {
1181                     old_comment = callsinfo->call_comment;
1182                     callsinfo->call_comment=g_strdup_printf("%s %u",
1183                             callsinfo->call_comment,
1184                             pi->response_code/*, pi->reason_phrase*/);
1185
1186                     g_free(old_comment);
1187                 }
1188
1189             }
1190
1191         }
1192         else {
1193             frame_label = g_strdup(pi->request_method);
1194
1195             if ((strcmp(pi->request_method,"INVITE")==0)&&(addresses_equal(&tmp_src,&(callsinfo->initial_speaker)))) {
1196                 tmp_sipinfo->invite_cseq = pi->tap_cseq_number;
1197                 callsinfo->call_state = VOIP_CALL_SETUP;
1198                 /* TODO: sometimes truncated when displayed in dialog window */
1199                 comment = g_strdup_printf("SIP INVITE From: %s To:%s Call-ID:%s CSeq:%d",
1200                         callsinfo->from_identity, callsinfo->to_identity,
1201                         callsinfo->call_id, pi->tap_cseq_number);
1202             }
1203             else if ((strcmp(pi->request_method,"ACK")==0)&&(pi->tap_cseq_number == tmp_sipinfo->invite_cseq)
1204                     &&(addresses_equal(&tmp_src,&(callsinfo->initial_speaker)))&&(tmp_sipinfo->sip_state==SIP_200_REC)
1205                     &&(callsinfo->call_state == VOIP_CALL_SETUP)) {
1206                 callsinfo->call_state = VOIP_IN_CALL;
1207                 comment = g_strdup_printf("SIP Request INVITE ACK 200 CSeq:%d", pi->tap_cseq_number);
1208             }
1209             else if (strcmp(pi->request_method,"BYE")==0) {
1210                 callsinfo->call_state = VOIP_COMPLETED;
1211                 tapinfo->completed_calls++;
1212                 comment = g_strdup_printf("SIP Request BYE CSeq:%d", pi->tap_cseq_number);
1213             }
1214             else if ((strcmp(pi->request_method,"CANCEL")==0)&&(pi->tap_cseq_number == tmp_sipinfo->invite_cseq)
1215                     &&(addresses_equal(&tmp_src,&(callsinfo->initial_speaker)))&&(callsinfo->call_state==VOIP_CALL_SETUP)) {
1216                 callsinfo->call_state = VOIP_CANCELLED;
1217                 tmp_sipinfo->sip_state = SIP_CANCEL_SENT;
1218                 comment = g_strdup_printf("SIP Request CANCEL CSeq:%d", pi->tap_cseq_number);
1219             } else {
1220                 /* comment = g_strdup_printf("SIP %s", pi->request_method); */
1221                 comment = g_strdup_printf("SIP %s From: %s To:%s CSeq:%d",
1222                         pi->request_method,
1223                         callsinfo->from_identity,
1224                         callsinfo->to_identity, pi->tap_cseq_number);
1225             }
1226         }
1227
1228         callsinfo->stop_fd = pinfo->fd;
1229         callsinfo->stop_rel_ts = pinfo->rel_ts;
1230         ++(callsinfo->npackets);
1231         /* increment the packets counter of all calls */
1232         ++(tapinfo->npackets);
1233
1234         /* add to the graph */
1235         add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
1236         g_free(comment);
1237         g_free(frame_label);
1238         free_address(&tmp_src);
1239         free_address(&tmp_dst);
1240
1241         /* add SDP info if apply */
1242         if ( (tapinfo->sdp_summary != NULL) && (tapinfo->sdp_frame_num == pinfo->num) ) {
1243             append_to_frame_graph(tapinfo, pinfo->num, tapinfo->sdp_summary, NULL);
1244             g_free(tapinfo->sdp_summary);
1245             tapinfo->sdp_summary = NULL;
1246         }
1247
1248     }
1249
1250     tapinfo->redraw |= REDRAW_SIP;
1251
1252     return TRUE;  /* refresh output */
1253 }
1254
1255 /****************************************************************************/
1256 static void
1257 sip_calls_draw(void *tap_offset_ptr)
1258 {
1259     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sip_);
1260
1261     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_SIP)) {
1262         tapinfo->tap_draw(tapinfo);
1263         tapinfo->redraw &= ~REDRAW_SIP;
1264     }
1265 }
1266
1267 /****************************************************************************/
1268 /* TAP INTERFACE */
1269 /****************************************************************************/
1270
1271 void
1272 sip_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
1273 {
1274     GString *error_string;
1275
1276     error_string = register_tap_listener("sip", tap_base_to_id(tap_id_base, tap_id_offset_sip_), NULL,
1277             0,
1278             NULL,
1279             sip_calls_packet,
1280             sip_calls_draw
1281             );
1282     if (error_string != NULL) {
1283         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1284                 "%s", error_string->str);
1285         g_string_free(error_string, TRUE);
1286     }
1287 }
1288
1289 /****************************************************************************/
1290 void
1291 remove_tap_listener_sip_calls(voip_calls_tapinfo_t *tap_id_base)
1292 {
1293     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_sip_));
1294 }
1295
1296 /****************************************************************************/
1297 /* ***************************TAP for ISUP **********************************/
1298 /****************************************************************************/
1299
1300 /****************************************************************************/
1301 /* whenever a isup_ packet is seen by the tap listener */
1302 static gboolean
1303 isup_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *isup_info)
1304 {
1305     voip_calls_tapinfo_t *tapinfo     = tap_id_to_base(tap_offset_ptr, tap_id_offset_isup_);
1306     voip_calls_info_t    *tmp_listinfo;
1307     voip_calls_info_t    *callsinfo   = NULL;
1308     isup_calls_info_t    *tmp_isupinfo;
1309     gboolean              found       = FALSE;
1310     gboolean              forward     = FALSE;
1311     gboolean              right_pair;
1312     GList                *list;
1313     gchar                *frame_label = NULL;
1314     gchar                *comment     = NULL;
1315
1316     const isup_tap_rec_t *pi = (const isup_tap_rec_t *)isup_info;
1317
1318     /* check if the lower layer is MTP matching the frame number */
1319     if (tapinfo->mtp3_frame_num != pinfo->num)
1320         return FALSE;
1321
1322     /* check whether we already have a call with these parameters in the list */
1323     list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1324     while (list)
1325     {
1326         right_pair = TRUE;
1327         tmp_listinfo=(voip_calls_info_t *)list->data;
1328         if ((tmp_listinfo->protocol == VOIP_ISUP)&&(tmp_listinfo->call_active_state==VOIP_ACTIVE)) {
1329             tmp_isupinfo = (isup_calls_info_t *)tmp_listinfo->prot_info;
1330             if ((tmp_isupinfo->cic == pi->circuit_id)&&(tmp_isupinfo->ni == tapinfo->mtp3_ni)) {
1331                 if ((tmp_isupinfo->opc == tapinfo->mtp3_opc)&&(tmp_isupinfo->dpc == tapinfo->mtp3_dpc)) {
1332                     forward = TRUE;
1333                 } else if ((tmp_isupinfo->dpc == tapinfo->mtp3_opc)&&(tmp_isupinfo->opc == tapinfo->mtp3_dpc)) {
1334                     forward = FALSE;
1335                 } else {
1336                     right_pair = FALSE;
1337                 }
1338
1339                 if (right_pair) {
1340                     /* if there is an IAM for a call that is not in setup state, that means the previous call in the same
1341                        cic is no longer active */
1342                     if (tmp_listinfo->call_state == VOIP_CALL_SETUP) {
1343                         found = TRUE;
1344                     } else if (pi->message_type != 1) {
1345                         found = TRUE;
1346                     } else {
1347                         tmp_listinfo->call_active_state=VOIP_INACTIVE;
1348                     }
1349                 }
1350
1351                 if (found) {
1352                     callsinfo = (voip_calls_info_t*)(list->data);
1353                     break;
1354                 }
1355             }
1356         }
1357         list = g_list_next (list);
1358     }
1359
1360     /* not in the list? then create a new entry if the message is IAM
1361        -i.e. if this session is a call*/
1362
1363     if ((callsinfo==NULL) &&(pi->message_type==1)) {
1364         callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
1365         callsinfo->call_active_state = VOIP_ACTIVE;
1366         callsinfo->call_state = VOIP_UNKNOWN;
1367         copy_address(&(callsinfo->initial_speaker),&(pinfo->src));
1368         callsinfo->selected       = FALSE;
1369         callsinfo->start_fd       = pinfo->fd;
1370         callsinfo->start_rel_ts   = pinfo->rel_ts;
1371         callsinfo->protocol       = VOIP_ISUP;
1372         callsinfo->from_identity  = g_strdup(pi->calling_number);
1373         callsinfo->to_identity    = g_strdup(pi->called_number);
1374         callsinfo->prot_info      = g_malloc(sizeof(isup_calls_info_t));
1375         callsinfo->free_prot_info = g_free;
1376         tmp_isupinfo              = (isup_calls_info_t *)callsinfo->prot_info;
1377         tmp_isupinfo->opc         = tapinfo->mtp3_opc;
1378         tmp_isupinfo->dpc         = tapinfo->mtp3_dpc;
1379         tmp_isupinfo->ni          = tapinfo->mtp3_ni;
1380         tmp_isupinfo->cic         = pi->circuit_id;
1381         callsinfo->npackets       = 0;
1382         callsinfo->call_num       = tapinfo->ncalls++;
1383         g_queue_push_tail(tapinfo->callsinfos, callsinfo);
1384     }
1385
1386
1387     if (callsinfo!=NULL) {
1388         callsinfo->stop_fd = pinfo->fd;
1389         callsinfo->stop_rel_ts = pinfo->rel_ts;
1390         ++(callsinfo->npackets);
1391
1392         /* Let's analyze the call state */
1393
1394         frame_label = g_strdup(val_to_str_ext_const(pi->message_type, &isup_message_type_value_acro_ext, "Unknown"));
1395
1396         if (callsinfo->npackets == 1) { /* this is the first packet, that must be an IAM */
1397
1398             if ((pi->calling_number!=NULL)&&(pi->called_number !=NULL)) {
1399                 comment = g_strdup_printf("Call from %s to %s",
1400                         pi->calling_number, pi->called_number);
1401             }
1402         } else if (callsinfo->npackets == 2) { /* in the second packet we show the SPs */
1403             if (forward) {
1404                 comment = g_strdup_printf("%i-%i -> %i-%i. Cic:%i",
1405                         tapinfo->mtp3_ni, tapinfo->mtp3_opc,
1406                         tapinfo->mtp3_ni, tapinfo->mtp3_dpc, pi->circuit_id);
1407             } else {
1408                 comment = g_strdup_printf("%i-%i -> %i-%i. Cic:%i",
1409                         tapinfo->mtp3_ni, tapinfo->mtp3_dpc,
1410                         tapinfo->mtp3_ni, tapinfo->mtp3_opc, pi->circuit_id);
1411             }
1412         }
1413
1414         switch(pi->message_type) {
1415             case 1: /* IAM */
1416                 callsinfo->call_state=VOIP_CALL_SETUP;
1417                 break;
1418             case 7: /* CONNECT */
1419             case 9: /* ANSWER */
1420                 callsinfo->call_state=VOIP_IN_CALL;
1421                 break;
1422             case 12: /* RELEASE */
1423                 if (callsinfo->call_state==VOIP_CALL_SETUP) {
1424                     if (forward) {
1425                         callsinfo->call_state=VOIP_CANCELLED;
1426                     }
1427                     else {
1428                         callsinfo->call_state=VOIP_REJECTED;
1429                         tapinfo->rejected_calls++;
1430                     }
1431                 }
1432                 else if (callsinfo->call_state == VOIP_IN_CALL) {
1433                     callsinfo->call_state = VOIP_COMPLETED;
1434                     tapinfo->completed_calls++;
1435                 }
1436                 comment = g_strdup_printf("Cause %i - %s",
1437                         pi->cause_value,
1438                         val_to_str_ext_const(pi->cause_value, &q931_cause_code_vals_ext, "(Unknown)"));
1439                 break;
1440         }
1441
1442         /* increment the packets counter of all calls */
1443         ++(tapinfo->npackets);
1444
1445         /* add to the graph */
1446         add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
1447         g_free(comment);
1448         g_free(frame_label);
1449     }
1450
1451     tapinfo->redraw |= REDRAW_ISUP;
1452
1453     return TRUE;  /* refresh output */
1454 }
1455
1456 /****************************************************************************/
1457 static void
1458 isup_calls_draw(void *tap_offset_ptr)
1459 {
1460     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_isup_);
1461
1462     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_ISUP)) {
1463         tapinfo->tap_draw(tapinfo);
1464         tapinfo->redraw &= ~REDRAW_ISUP;
1465     }
1466 }
1467
1468 /****************************************************************************/
1469
1470 void
1471 isup_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
1472 {
1473     GString *error_string;
1474
1475     error_string = register_tap_listener("isup", tap_base_to_id(tap_id_base, tap_id_offset_isup_),
1476             NULL,
1477             0,
1478             NULL,
1479             isup_calls_packet,
1480             isup_calls_draw
1481             );
1482
1483     if (error_string != NULL) {
1484         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1485                 "%s", error_string->str);
1486         g_string_free(error_string, TRUE);
1487     }
1488 }
1489
1490 /****************************************************************************/
1491
1492 void
1493 remove_tap_listener_isup_calls(voip_calls_tapinfo_t *tap_id_base)
1494 {
1495     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_isup_));
1496 }
1497
1498 /****************************************************************************/
1499 /* ***************************TAP for MTP3 **********************************/
1500 /****************************************************************************/
1501
1502
1503 /****************************************************************************/
1504 /* whenever a mtp3_ packet is seen by the tap listener */
1505 static gboolean
1506 mtp3_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt _U_, const void *mtp3_info)
1507 {
1508     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_mtp3_);
1509     const mtp3_tap_rec_t *pi      = (const mtp3_tap_rec_t *)mtp3_info;
1510
1511     /* keep the data in memory to use when the ISUP information arrives */
1512
1513     tapinfo->mtp3_opc = pi->addr_opc.pc;
1514     tapinfo->mtp3_dpc = pi->addr_dpc.pc;
1515     tapinfo->mtp3_ni = pi->addr_opc.ni;
1516     tapinfo->mtp3_frame_num = pinfo->num;
1517
1518     return FALSE;
1519 }
1520
1521 static gboolean
1522 m3ua_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt _U_, const void *mtp3_info)
1523 {
1524     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_m3ua_);
1525     const mtp3_tap_rec_t *pi = (const mtp3_tap_rec_t *)mtp3_info;
1526
1527     /* keep the data in memory to use when the ISUP information arrives */
1528
1529     tapinfo->mtp3_opc = pi->addr_opc.pc;
1530     tapinfo->mtp3_dpc = pi->addr_dpc.pc;
1531     tapinfo->mtp3_ni = pi->addr_opc.ni;
1532     tapinfo->mtp3_frame_num = pinfo->num;
1533
1534     return FALSE;
1535 }
1536
1537 /****************************************************************************/
1538
1539 void
1540 mtp3_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
1541 {
1542     GString *error_string;
1543
1544     error_string = register_tap_listener("mtp3", tap_base_to_id(tap_id_base, tap_id_offset_mtp3_),
1545             NULL,
1546             0,
1547             NULL,
1548             mtp3_calls_packet,
1549             NULL
1550             );
1551
1552     if (error_string != NULL) {
1553         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1554                 "%s", error_string->str);
1555         g_string_free(error_string, TRUE);
1556     }
1557
1558     error_string = register_tap_listener("m3ua", tap_base_to_id(tap_id_base, tap_id_offset_m3ua_),
1559             NULL,
1560             0,
1561             NULL,
1562             m3ua_calls_packet,
1563             NULL
1564             );
1565
1566     if (error_string != NULL) {
1567         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1568                 "%s", error_string->str);
1569         g_string_free(error_string, TRUE);
1570     }
1571
1572 }
1573
1574 /****************************************************************************/
1575
1576 void
1577 remove_tap_listener_mtp3_calls(voip_calls_tapinfo_t *tap_id_base)
1578 {
1579     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_mtp3_));
1580     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_m3ua_));
1581 }
1582
1583 /****************************************************************************/
1584 /* ***************************TAP for Q931 **********************************/
1585 /****************************************************************************/
1586 static void h245_add_to_graph(voip_calls_tapinfo_t *tapinfo, guint32 new_frame_num);
1587 static const e_guid_t guid_allzero = {0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };
1588 /* defines specific H323 data */
1589
1590 /****************************************************************************/
1591 /* whenever a q931_ packet is seen by the tap listener */
1592 static gboolean
1593 q931_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *q931_info)
1594 {
1595     GList                     *list,*list2;
1596     voip_calls_tapinfo_t      *tapinfo   = tap_id_to_base(tap_offset_ptr, tap_id_offset_q931_);
1597     h323_calls_info_t         *tmp_h323info,*tmp2_h323info;
1598     actrace_isdn_calls_info_t *tmp_actrace_isdn_info;
1599     voip_calls_info_t         *tmp_listinfo;
1600     voip_calls_info_t         *callsinfo = NULL;
1601     h245_address_t            *h245_add  = NULL;
1602     gchar                     *comment, *tmp_str;
1603
1604     const q931_packet_info *pi = (const q931_packet_info *)q931_info;
1605
1606     /* free previously allocated q931_calling/ed_number */
1607     g_free(tapinfo->q931_calling_number);
1608     g_free(tapinfo->q931_called_number);
1609
1610     if (pi->calling_number!=NULL)
1611         tapinfo->q931_calling_number = g_strdup(pi->calling_number);
1612     else
1613         tapinfo->q931_calling_number = g_strdup("");
1614
1615     if (pi->called_number!=NULL)
1616         tapinfo->q931_called_number = g_strdup(pi->called_number);
1617     else
1618         tapinfo->q931_called_number = g_strdup("");
1619     tapinfo->q931_cause_value = pi->cause_value;
1620     tapinfo->q931_frame_num = pinfo->num;
1621     tapinfo->q931_crv = pi->crv;
1622
1623
1624     /* add staff to H323 calls */
1625     if (tapinfo->h225_frame_num == tapinfo->q931_frame_num) {
1626         tmp_h323info = NULL;
1627         list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1628         while (list)
1629         {
1630             tmp_listinfo=(voip_calls_info_t *)list->data;
1631             if ( (tmp_listinfo->protocol == VOIP_H323) && (tmp_listinfo->call_num == tapinfo->h225_call_num) ) {
1632                 tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info;
1633                 callsinfo = (voip_calls_info_t*)(list->data);
1634
1635                 /* Add the CRV to the h323 call */
1636                 if (tmp_h323info->q931_crv == -1) {
1637                     tmp_h323info->q931_crv = tapinfo->q931_crv;
1638                 } else if (tmp_h323info->q931_crv != tapinfo->q931_crv) {
1639                     tmp_h323info->q931_crv2 = tapinfo->q931_crv;
1640                 }
1641                 break;
1642             }
1643             list = g_list_next (list);
1644         }
1645
1646         if (callsinfo != NULL) {
1647             comment = NULL;
1648             if (tapinfo->h225_cstype == H225_SETUP) {
1649                 /* set te calling and called number from the Q931 packet */
1650                 if (tapinfo->q931_calling_number != NULL) {
1651                     g_free(callsinfo->from_identity);
1652                     callsinfo->from_identity=g_strdup(tapinfo->q931_calling_number);
1653                 }
1654                 if (tapinfo->q931_called_number != NULL) {
1655                     g_free(callsinfo->to_identity);
1656                     callsinfo->to_identity=g_strdup(tapinfo->q931_called_number);
1657                 }
1658
1659                 /* check if there is an LRQ/LCF that match this Setup */
1660                 /* TODO: we are just checking the DialedNumer in LRQ/LCF against the Setup
1661                    we should also check if the h225 signaling IP and port match the destination
1662                    Setup ip and port */
1663                 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1664                 while (list)
1665                 {
1666                     tmp_listinfo=(voip_calls_info_t *)list->data;
1667                     if (tmp_listinfo->protocol == VOIP_H323) {
1668                         tmp2_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info;
1669
1670                         /* check if the called number match a LRQ/LCF */
1671                         if ( (strcmp(callsinfo->to_identity, tmp_listinfo->to_identity)==0)
1672                                 && (memcmp(tmp2_h323info->guid, &guid_allzero, GUID_LEN) == 0) ) {
1673                             /* change the call graph to the LRQ/LCF to belong to this call */
1674                             callsinfo->npackets += change_call_num_graph(tapinfo, tmp_listinfo->call_num, callsinfo->call_num);
1675
1676                             /* remove this LRQ/LCF call entry because we have found the Setup that match them */
1677                             g_free(tmp_listinfo->from_identity);
1678                             g_free(tmp_listinfo->to_identity);
1679                             DUMP_PTR2(tmp2_h323info->guid);
1680                             g_free(tmp2_h323info->guid);
1681
1682                             list2 = g_list_first(tmp2_h323info->h245_list);
1683                             while (list2)
1684                             {
1685                                 h245_add=(h245_address_t *)list2->data;
1686                                 free_address(&h245_add->h245_address);
1687                                 g_free(list2->data);
1688                                 list2 = g_list_next(list2);
1689                             }
1690                             g_list_free(tmp_h323info->h245_list);
1691                             tmp_h323info->h245_list = NULL;
1692                             g_free(tmp_listinfo->prot_info);
1693                             g_queue_unlink(tapinfo->callsinfos, list);
1694                             break;
1695                         }
1696                     }
1697                     list = g_list_next (list);
1698                 }
1699
1700                 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"),
1701                         (tapinfo->h225_is_faststart==TRUE?"on":"off"));
1702             } else if (tapinfo->h225_cstype == H225_RELEASE_COMPLET) {
1703                 /* get the Q931 Release cause code */
1704                 if (tapinfo->q931_cause_value != 0xFF) {
1705                     comment = g_strdup_printf("H225 Q931 Rel Cause (%i):%s", tapinfo->q931_cause_value,
1706                             val_to_str_ext_const(tapinfo->q931_cause_value, &q931_cause_code_vals_ext, "<unknown>"));
1707                 } else { /* Cause not set */
1708                     comment = g_strdup("H225 No Q931 Rel Cause");
1709                 }
1710             }
1711             /* change the graph comment for this new one */
1712             if (comment != NULL) {
1713                 change_frame_graph(tapinfo, tapinfo->h225_frame_num, NULL, comment);
1714                 g_free(comment);
1715             }
1716         }
1717         /* we reset the h225_frame_num to 0 because there could be empty h225 in the same frame
1718            as non empty h225 (e.g connect), so we don't have to be here twice */
1719         tapinfo->h225_frame_num = 0;
1720
1721         /* add staff to H245 */
1722     } else if (tapinfo->h245_labels->frame_num == tapinfo->q931_frame_num) {
1723         /* there are empty H225 frames that don't have guid (guaid=0) but they have h245 info,
1724            so the only way to match those frames is with the Q931 CRV number */
1725         list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1726         while (list)
1727         {
1728             tmp_listinfo=(voip_calls_info_t *)list->data;
1729             if (tmp_listinfo->protocol == VOIP_H323) {
1730                 tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info;
1731                 if ( ((tmp_h323info->q931_crv == tapinfo->q931_crv) || (tmp_h323info->q931_crv2 == tapinfo->q931_crv)) && (tapinfo->q931_crv!=-1)) {
1732                     /* if the frame number exists in graph, append to it*/
1733                     if (!append_to_frame_graph(tapinfo, tapinfo->q931_frame_num, NULL, NULL)) {
1734                         /* if not exist, add to the graph */
1735                         add_to_graph(tapinfo, pinfo, edt, NULL, NULL, tmp_listinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
1736                         ++(tmp_listinfo->npackets);
1737                         /* increment the packets counter of all calls */
1738                         ++(tapinfo->npackets);
1739                     }
1740
1741                     /* Add the H245 info if exists to the Graph */
1742                     h245_add_to_graph(tapinfo, pinfo->num);
1743                     break;
1744                 }
1745             }
1746             list = g_list_next (list);
1747         }
1748     /* SIP-Q */
1749     } else if (tapinfo->sip_frame_num == tapinfo->q931_frame_num) {
1750          /* Do nothing for now */
1751     /* add stuff to ACTRACE */
1752     } else {
1753         address pstn_add;
1754
1755         comment = NULL;
1756         callsinfo = NULL;
1757         list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1758         while (list)
1759         {
1760             tmp_listinfo=(voip_calls_info_t *)list->data;
1761             if ( tmp_listinfo->protocol == VOIP_AC_ISDN ) {
1762                 tmp_actrace_isdn_info = (actrace_isdn_calls_info_t *)tmp_listinfo->prot_info;
1763                 /* TODO: Also check the IP of the Blade, and if the call is complete (no active) */
1764                 if ( (tmp_actrace_isdn_info->crv == tapinfo->q931_crv) && (tmp_actrace_isdn_info->trunk == tapinfo->actrace_trunk) ) {
1765                     callsinfo = (voip_calls_info_t*)(list->data);
1766                     break;
1767                 }
1768             }
1769             list = g_list_next (list);
1770         }
1771
1772         set_address(&pstn_add, AT_STRINGZ, 5, g_strdup("PSTN"));
1773
1774         /* if it is a new call, add it to the list */
1775         if (!callsinfo) {
1776             callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
1777             callsinfo->call_active_state = VOIP_ACTIVE;
1778             callsinfo->call_state = VOIP_CALL_SETUP;
1779             callsinfo->from_identity=g_strdup(tapinfo->q931_calling_number);
1780             callsinfo->to_identity=g_strdup(tapinfo->q931_called_number);
1781             copy_address(&(callsinfo->initial_speaker),tapinfo->actrace_direction?&pstn_add:&(pinfo->src));
1782             callsinfo->selected=FALSE;
1783             callsinfo->start_fd=pinfo->fd;
1784             callsinfo->start_rel_ts=pinfo->rel_ts;
1785             callsinfo->protocol=VOIP_AC_ISDN;
1786             callsinfo->prot_info=g_malloc(sizeof(actrace_isdn_calls_info_t));
1787             callsinfo->free_prot_info = g_free;
1788             tmp_actrace_isdn_info=(actrace_isdn_calls_info_t *)callsinfo->prot_info;
1789             tmp_actrace_isdn_info->crv=tapinfo->q931_crv;
1790             tmp_actrace_isdn_info->trunk=tapinfo->actrace_trunk;
1791             callsinfo->npackets = 0;
1792             callsinfo->call_num = tapinfo->ncalls++;
1793             g_queue_push_tail(tapinfo->callsinfos, callsinfo);
1794         }
1795
1796         callsinfo->stop_fd = pinfo->fd;
1797         callsinfo->stop_rel_ts = pinfo->rel_ts;
1798         ++(callsinfo->npackets);
1799         /* increment the packets counter of all calls */
1800         ++(tapinfo->npackets);
1801
1802         switch(pi->message_type) {
1803             case Q931_SETUP:
1804                 comment = g_strdup_printf("AC_ISDN trunk:%u Calling: %s  Called:%s", tapinfo->actrace_trunk, tapinfo->q931_calling_number, tapinfo->q931_called_number);
1805                 callsinfo->call_state=VOIP_CALL_SETUP;
1806                 break;
1807             case Q931_CONNECT:
1808                 callsinfo->call_state=VOIP_IN_CALL;
1809                 break;
1810             case Q931_RELEASE_COMPLETE:
1811             case Q931_RELEASE:
1812             case Q931_DISCONNECT:
1813                 if (callsinfo->call_state==VOIP_CALL_SETUP) {
1814                     if (addresses_equal(&(callsinfo->initial_speaker), tapinfo->actrace_direction?&pstn_add:&(pinfo->src) )) {  /* forward direction */
1815                         callsinfo->call_state=VOIP_CANCELLED;
1816                     }
1817                     else { /* reverse */
1818                         callsinfo->call_state=VOIP_REJECTED;
1819                         tapinfo->rejected_calls++;
1820                     }
1821                 } else if ( (callsinfo->call_state!=VOIP_CANCELLED) && (callsinfo->call_state!=VOIP_REJECTED) ) {
1822                     callsinfo->call_state=VOIP_COMPLETED;
1823                     tapinfo->completed_calls++;
1824                 }
1825                 if (tapinfo->q931_cause_value != 0xFF) {
1826                     comment = g_strdup_printf("AC_ISDN trunk:%u Q931 Rel Cause (%i):%s", tapinfo->actrace_trunk, tapinfo->q931_cause_value,
1827                             val_to_str_ext_const(tapinfo->q931_cause_value, &q931_cause_code_vals_ext, "<unknown>"));
1828                 } else { /* Cause not set */
1829                     comment = g_strdup("AC_ISDN No Q931 Rel Cause");
1830                 }
1831                 break;
1832         }
1833
1834         if (!comment)
1835             comment = g_strdup_printf("AC_ISDN  trunk:%u", tapinfo->actrace_trunk );
1836
1837         tmp_str = val_to_str_wmem(NULL, pi->message_type, q931_message_type_vals, "<unknown (%d)>");
1838         add_to_graph(tapinfo, pinfo, edt, tmp_str, comment, callsinfo->call_num,
1839                 tapinfo->actrace_direction?&pstn_add:&(pinfo->src),
1840                 tapinfo->actrace_direction?&(pinfo->src):&pstn_add,
1841                 1 );
1842         wmem_free(NULL, tmp_str);
1843
1844         g_free(comment);
1845         free_address(&pstn_add);
1846     }
1847
1848     tapinfo->redraw |= REDRAW_Q931;
1849
1850     return TRUE;  /* refresh output */
1851 }
1852
1853 /****************************************************************************/
1854 static void
1855 q931_calls_draw(void *tap_offset_ptr)
1856 {
1857     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_q931_);
1858
1859     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_Q931)) {
1860         tapinfo->tap_draw(tapinfo);
1861         tapinfo->redraw &= ~REDRAW_Q931;
1862     }
1863 }
1864
1865 /****************************************************************************/
1866
1867 void
1868 q931_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
1869 {
1870     GString *error_string;
1871
1872     error_string = register_tap_listener("q931", tap_base_to_id(tap_id_base, tap_id_offset_q931_),
1873             NULL,
1874             0,
1875             NULL,
1876             q931_calls_packet,
1877             q931_calls_draw
1878             );
1879
1880     if (error_string != NULL) {
1881         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1882                 "%s", error_string->str);
1883         g_string_free(error_string, TRUE);
1884     }
1885 }
1886
1887 /****************************************************************************/
1888
1889 void
1890 remove_tap_listener_q931_calls(voip_calls_tapinfo_t *tap_id_base)
1891 {
1892     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_q931_));
1893 }
1894
1895 /****************************************************************************/
1896 /****************************TAP for H323 ***********************************/
1897 /****************************************************************************/
1898
1899 static void
1900 add_h245_Address(h323_calls_info_t *h323info,  h245_address_t *h245_address)
1901 {
1902     h323info->h245_list = g_list_prepend(h323info->h245_list, h245_address);
1903 }
1904
1905
1906 static void
1907 free_h225_info(gpointer p) {
1908     h323_calls_info_t *tmp_h323info = (h323_calls_info_t *)p;
1909
1910     DUMP_PTR2(tmp_h323info->guid);
1911     g_free(tmp_h323info->guid);
1912
1913     if (tmp_h323info->h245_list) {
1914         GList *list2 = g_list_first(tmp_h323info->h245_list);
1915         while (list2)
1916         {
1917             h245_address_t *h245_add=(h245_address_t *)list2->data;
1918             free_address(&h245_add->h245_address);
1919             g_free(list2->data);
1920             list2 = g_list_next(list2);
1921         }
1922
1923         g_list_free(tmp_h323info->h245_list);
1924
1925     }
1926
1927     g_free(p);
1928 }
1929 /****************************************************************************/
1930 /* whenever a H225 packet is seen by the tap listener */
1931 static gboolean
1932 h225_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *H225info)
1933 {
1934     voip_calls_tapinfo_t *tapinfo      = tap_id_to_base(tap_offset_ptr, tap_id_offset_h225_);
1935     voip_calls_info_t    *tmp_listinfo;
1936     voip_calls_info_t    *callsinfo    = NULL;
1937     h323_calls_info_t    *tmp_h323info = NULL;
1938     gchar                *frame_label;
1939     gchar                *comment;
1940     GList                *list;
1941     h245_address_t       *h245_add     = NULL;
1942
1943     const h225_packet_info *pi = (const h225_packet_info *)H225info;
1944
1945     /* if not guid and RAS and not LRQ, LCF or LRJ return because did not belong to a call */
1946     /* OR, if not guid and is H225 return because doesn't belong to a call */
1947     if ((memcmp(&pi->guid, &guid_allzero, GUID_LEN) == 0))
1948         if ( ((pi->msg_type == H225_RAS) && ((pi->msg_tag < 18) || (pi->msg_tag > 20))) || (pi->msg_type != H225_RAS) )
1949             return FALSE;
1950
1951     /* if it is RAS LCF or LRJ*/
1952     if ( (pi->msg_type == H225_RAS) && ((pi->msg_tag == 19) || (pi->msg_tag == 20))) {
1953         /* if the LCF/LRJ doesn't match to a LRQ, just return */
1954         if (!pi->request_available) return FALSE;
1955
1956         /* check whether we already have a call with this request SeqNum */
1957         list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1958         while (list)
1959         {
1960             tmp_listinfo=(voip_calls_info_t *)list->data;
1961             g_assert(tmp_listinfo != NULL);
1962             if (tmp_listinfo->protocol == VOIP_H323) {
1963                 tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info;
1964                 if (tmp_h323info->requestSeqNum == pi->requestSeqNum) {
1965                     callsinfo = (voip_calls_info_t*)(list->data);
1966                     break;
1967                 }
1968             }
1969             list = g_list_next (list);
1970         }
1971     } else {
1972         /* check whether we already have a call with this guid in the list */
1973         list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
1974         while (list)
1975         {
1976             tmp_listinfo=(voip_calls_info_t *)list->data;
1977             if (tmp_listinfo->protocol == VOIP_H323) {
1978                 tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info;
1979                 g_assert(tmp_h323info != NULL);
1980                 if ( (memcmp(tmp_h323info->guid, &guid_allzero, GUID_LEN) != 0) && (memcmp(tmp_h323info->guid, &pi->guid,GUID_LEN)==0) ) {
1981                     callsinfo = (voip_calls_info_t*)(list->data);
1982                     break;
1983                 }
1984             }
1985             list = g_list_next (list);
1986         }
1987     }
1988
1989     tapinfo->h225_cstype = pi->cs_type;
1990     tapinfo->h225_is_faststart = pi->is_faststart;
1991
1992     /* not in the list? then create a new entry */
1993     if (callsinfo==NULL) {
1994         callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
1995         callsinfo->call_active_state = VOIP_ACTIVE;
1996         callsinfo->call_state = VOIP_UNKNOWN;
1997         callsinfo->from_identity=g_strdup("");
1998         callsinfo->to_identity=g_strdup("");
1999         copy_address(&(callsinfo->initial_speaker),&(pinfo->src));
2000         callsinfo->selected=FALSE;
2001         callsinfo->start_fd=pinfo->fd;
2002         callsinfo->start_rel_ts=pinfo->rel_ts;
2003         callsinfo->protocol=VOIP_H323;
2004         callsinfo->prot_info=g_malloc(sizeof(h323_calls_info_t));
2005         callsinfo->free_prot_info = free_h225_info;
2006
2007         tmp_h323info = (h323_calls_info_t *)callsinfo->prot_info;
2008         g_assert(tmp_h323info != NULL);
2009         tmp_h323info->guid = (e_guid_t *)g_memdup(&pi->guid, sizeof pi->guid);
2010         DUMP_PTR1(tmp_h323info->guid);
2011
2012         clear_address(&tmp_h323info->h225SetupAddr);
2013         tmp_h323info->h245_list = NULL;
2014         tmp_h323info->is_faststart_Setup = FALSE;
2015         tmp_h323info->is_faststart_Proc = FALSE;
2016         tmp_h323info->is_h245Tunneling = FALSE;
2017         tmp_h323info->is_h245 = FALSE;
2018         tmp_h323info->q931_crv = -1;
2019         tmp_h323info->q931_crv2 = -1;
2020         tmp_h323info->requestSeqNum = 0;
2021         callsinfo->call_num = tapinfo->ncalls++;
2022         callsinfo->npackets = 0;
2023
2024         g_queue_push_tail(tapinfo->callsinfos, callsinfo);
2025     }
2026
2027     tapinfo->h225_frame_num = pinfo->num;
2028     tapinfo->h225_call_num = callsinfo->call_num;
2029
2030     /* let's analyze the call state */
2031
2032     callsinfo->stop_fd = pinfo->fd;
2033     callsinfo->stop_rel_ts = pinfo->rel_ts;
2034     ++(callsinfo->npackets);
2035     /* increment the packets counter of all calls */
2036     ++(tapinfo->npackets);
2037
2038
2039     /* XXX: it is supposed to be initialized isn't it? */
2040     g_assert(tmp_h323info != NULL);
2041
2042     /* change the status */
2043     if (pi->msg_type == H225_CS) {
2044
2045         /* this is still IPv4 only, because the dissector is */
2046         if (pi->is_h245 == TRUE) {
2047             h245_add = (h245_address_t *)g_malloc(sizeof (h245_address_t));
2048             alloc_address_wmem(NULL, &h245_add->h245_address, AT_IPv4, 4, &pi->h245_address);
2049             h245_add->h245_port = pi->h245_port;
2050             add_h245_Address(tmp_h323info, h245_add);
2051         }
2052
2053         if (pi->cs_type != H225_RELEASE_COMPLET) tmp_h323info->is_h245Tunneling = pi->is_h245Tunneling;
2054
2055         frame_label = g_strdup(pi->frame_label);
2056
2057         switch(pi->cs_type) {
2058             case H225_SETUP:
2059                 tmp_h323info->is_faststart_Setup = pi->is_faststart;
2060
2061                 /* Set the Setup address if it was not set */
2062                 if (tmp_h323info->h225SetupAddr.type == AT_NONE)
2063                     copy_address(&(tmp_h323info->h225SetupAddr), &(pinfo->src));
2064                 callsinfo->call_state=VOIP_CALL_SETUP;
2065                 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
2066                         (pi->is_faststart==TRUE?"on":"off"));
2067                 break;
2068             case H225_CONNECT:
2069                 callsinfo->call_state=VOIP_IN_CALL;
2070                 if (pi->is_faststart == TRUE) tmp_h323info->is_faststart_Proc = TRUE;
2071                 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
2072                         (pi->is_faststart==TRUE?"on":"off"));
2073                 break;
2074             case H225_RELEASE_COMPLET:
2075                 if (callsinfo->call_state==VOIP_CALL_SETUP) {
2076                     if (addresses_equal(&(tmp_h323info->h225SetupAddr),&(pinfo->src))) {  /* forward direction */
2077                         callsinfo->call_state=VOIP_CANCELLED;
2078                     }
2079                     else { /* reverse */
2080                         callsinfo->call_state=VOIP_REJECTED;
2081                         tapinfo->rejected_calls++;
2082                     }
2083                 } else {
2084                     callsinfo->call_state=VOIP_COMPLETED;
2085                     tapinfo->completed_calls++;
2086                 }
2087                 comment = g_strdup("H225 No Q931 Rel Cause");
2088                 break;
2089             case H225_PROGRESS:
2090             case H225_ALERTING:
2091             case H225_CALL_PROCEDING:
2092                 if (pi->is_faststart == TRUE) tmp_h323info->is_faststart_Proc = TRUE;
2093                 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
2094                         (pi->is_faststart==TRUE?"on":"off"));
2095                 break;
2096             default:
2097                 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
2098                         (pi->is_faststart==TRUE?"on":"off"));
2099
2100         }
2101     }
2102     else if (pi->msg_type == H225_RAS) {
2103         switch(pi->msg_tag) {
2104             case 18:  /* LRQ */
2105                 if (!pi->is_duplicate) {
2106                     g_free(callsinfo->to_identity);
2107                     callsinfo->to_identity=g_strdup(pi->dialedDigits);
2108                     tmp_h323info->requestSeqNum = pi->requestSeqNum;
2109                 }
2110                 /* Fall Through */
2111             case 19: /* LCF */
2112                 if (strlen(pi->dialedDigits))
2113                     comment = g_strdup_printf("H225 RAS dialedDigits: %s", pi->dialedDigits);
2114                 else
2115                     comment = g_strdup("H225 RAS");
2116                 break;
2117             default:
2118                 comment = g_strdup("H225 RAS");
2119         }
2120         frame_label = g_strdup(val_to_str_const(pi->msg_tag, h225_RasMessage_vals, "<unknown>"));
2121     } else {
2122         frame_label = g_strdup("H225: Unknown");
2123         comment = NULL;
2124     }
2125
2126     /* add to graph analysis */
2127
2128     /* if the frame number exists in graph, append to it*/
2129     if (!append_to_frame_graph(tapinfo, pinfo->num, pi->frame_label, comment)) {
2130         /* if not exist, add to the graph */
2131         add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
2132     }
2133
2134     /* Add the H245 info if exists to the Graph */
2135     h245_add_to_graph(tapinfo, pinfo->num);
2136
2137     g_free(frame_label);
2138     g_free(comment);
2139
2140     tapinfo->redraw |= REDRAW_H225;
2141
2142     return TRUE;  /* refresh output */
2143 }
2144
2145 /****************************************************************************/
2146 static void
2147 h225_calls_draw(void *tap_offset_ptr)
2148 {
2149     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_h225_);
2150
2151     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_H225)) {
2152         tapinfo->tap_draw(tapinfo);
2153         tapinfo->redraw &= ~REDRAW_H225;
2154     }
2155 }
2156
2157 /****************************************************************************/
2158 /* TAP INTERFACE */
2159 /****************************************************************************/
2160 void
2161 h225_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
2162 {
2163     GString *error_string;
2164
2165     error_string = register_tap_listener("h225", tap_base_to_id(tap_id_base, tap_id_offset_h225_), NULL,
2166             0,
2167             NULL,
2168             h225_calls_packet,
2169             h225_calls_draw
2170             );
2171
2172     if (error_string != NULL) {
2173         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2174                 "%s", error_string->str);
2175         g_string_free(error_string, TRUE);
2176     }
2177 }
2178
2179 /****************************************************************************/
2180 void
2181 remove_tap_listener_h225_calls(voip_calls_tapinfo_t *tap_id_base)
2182 {
2183     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_h225_));
2184 }
2185
2186 /* Add the h245 label info to the graph */
2187 void
2188 h245_add_to_graph(voip_calls_tapinfo_t *tapinfo, guint32 new_frame_num)
2189 {
2190     gint8 n;
2191
2192     if (new_frame_num != tapinfo->h245_labels->frame_num) return;
2193
2194     for (n=0; n<tapinfo->h245_labels->labels_count; n++) {
2195         append_to_frame_graph(tapinfo, new_frame_num, tapinfo->h245_labels->labels[n].frame_label, tapinfo->h245_labels->labels[n].comment);
2196         g_free(tapinfo->h245_labels->labels[n].frame_label);
2197         tapinfo->h245_labels->labels[n].frame_label = NULL;
2198         g_free(tapinfo->h245_labels->labels[n].comment);
2199         tapinfo->h245_labels->labels[n].comment = NULL;
2200     }
2201     tapinfo->h245_labels->frame_num = 0;
2202     tapinfo->h245_labels->labels_count = 0;
2203 }
2204
2205 /* free the h245_labels if the frame number is different */
2206 static void
2207 h245_free_labels(voip_calls_tapinfo_t *tapinfo, guint32 new_frame_num)
2208 {
2209     gint8 n;
2210
2211     if (new_frame_num == tapinfo->h245_labels->frame_num) return;
2212
2213     for (n=0; n<tapinfo->h245_labels->labels_count; n++) {
2214         g_free(tapinfo->h245_labels->labels[n].frame_label);
2215         tapinfo->h245_labels->labels[n].frame_label = NULL;
2216         g_free(tapinfo->h245_labels->labels[n].comment);
2217         tapinfo->h245_labels->labels[n].comment = NULL;
2218     }
2219     tapinfo->h245_labels->frame_num = 0;
2220     tapinfo->h245_labels->labels_count = 0;
2221 }
2222
2223 /* add the frame_label and comment to h245_labels and free the actual one if it is different frame num */
2224 static void
2225 h245_add_label(voip_calls_tapinfo_t *tapinfo, guint32 new_frame_num, const gchar *frame_label, const gchar *comment)
2226 {
2227     h245_free_labels(tapinfo, new_frame_num);
2228
2229     tapinfo->h245_labels->frame_num = new_frame_num;
2230     tapinfo->h245_labels->labels[tapinfo->h245_labels->labels_count].frame_label = g_strdup(frame_label);
2231     tapinfo->h245_labels->labels[tapinfo->h245_labels->labels_count].comment = g_strdup(comment);
2232
2233     if (tapinfo->h245_labels->labels_count < (H245_MAX-1))
2234         tapinfo->h245_labels->labels_count++;
2235
2236 }
2237
2238 /****************************************************************************/
2239 /* whenever a H245dg packet is seen by the tap listener (when H245 tunneling is ON) */
2240 static gboolean
2241 h245dg_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *H245info)
2242 {
2243     voip_calls_tapinfo_t *tapinfo   = tap_id_to_base(tap_offset_ptr, tap_id_offset_h245dg_);
2244     voip_calls_info_t    *tmp_listinfo;
2245     voip_calls_info_t    *callsinfo = NULL;
2246     h323_calls_info_t    *tmp_h323info;
2247     GList                *list;
2248     GList                *list2;
2249     h245_address_t       *h245_add  = NULL;
2250
2251     const h245_packet_info *pi = (const h245_packet_info *)H245info;
2252
2253     /* check if Tunneling is OFF and we have a call with this H245 add */
2254     list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
2255     while (list)
2256     {
2257         tmp_listinfo=(voip_calls_info_t *)list->data;
2258         if (tmp_listinfo->protocol == VOIP_H323) {
2259             tmp_h323info = (h323_calls_info_t *)tmp_listinfo->prot_info;
2260
2261             list2 = g_list_first(tmp_h323info->h245_list);
2262             while (list2)
2263             {
2264                 h245_add=(h245_address_t *)list2->data;
2265                 if ( (addresses_equal(&(h245_add->h245_address),&(pinfo->src)) && (h245_add->h245_port == pinfo->srcport))
2266                         || (addresses_equal(&(h245_add->h245_address),&(pinfo->dst)) && (h245_add->h245_port == pinfo->destport)) ) {
2267                     callsinfo = (voip_calls_info_t*)(list->data);
2268
2269                     ++(callsinfo->npackets);
2270                     /* increment the packets counter of all calls */
2271                     ++(tapinfo->npackets);
2272
2273                     break;
2274                 }
2275                 list2 = g_list_next(list2);
2276             }
2277             if (callsinfo!=NULL) break;
2278         }
2279         list = g_list_next(list);
2280     }
2281
2282     /* Tunnel is OFF, and we matched the h245 add so we add it to graph */
2283     if (callsinfo!=NULL) {
2284         ++(callsinfo->npackets);
2285         /* increment the packets counter of all calls */
2286         ++(tapinfo->npackets);
2287         /* if the frame number exists in graph, append to it*/
2288         if (!append_to_frame_graph(tapinfo, pinfo->num, pi->frame_label, pi->comment)) {
2289             /* if not exist, add to the graph */
2290             add_to_graph(tapinfo, pinfo, edt, pi->frame_label, pi->comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
2291         }
2292     } else {
2293         /* Tunnel is ON, so we save the label info to use it into h225 or q931 tap. OR may be
2294            tunnel OFF but we did not matched the h245 add, in this case nobady will set this label
2295            since the frame_num will not match */
2296
2297         h245_add_label(tapinfo, pinfo->num, pi->frame_label, pi->comment);
2298     }
2299
2300     tapinfo->redraw |= REDRAW_H245DG;
2301
2302     return TRUE;  /* refresh output */
2303 }
2304
2305 /****************************************************************************/
2306 static void
2307 h245dg_calls_draw(void *tap_offset_ptr)
2308 {
2309     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_h245dg_);
2310
2311     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_H245DG)) {
2312         tapinfo->tap_draw(tapinfo);
2313         tapinfo->redraw &= ~REDRAW_H245DG;
2314     }
2315 }
2316
2317 /****************************************************************************/
2318 /* TAP INTERFACE */
2319 /****************************************************************************/
2320 void
2321 h245dg_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
2322 {
2323     GString *error_string;
2324
2325     if (!tap_id_base->h245_labels) {
2326         tap_id_base->h245_labels = g_new0(h245_labels_t, 1);
2327     }
2328
2329     error_string = register_tap_listener("h245dg", tap_base_to_id(tap_id_base, tap_id_offset_h245dg_), NULL,
2330             0,
2331             NULL,
2332             h245dg_calls_packet,
2333             h245dg_calls_draw
2334             );
2335
2336     if (error_string != NULL) {
2337         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2338                 "%s", error_string->str);
2339         g_string_free(error_string, TRUE);
2340     }
2341 }
2342
2343 /****************************************************************************/
2344 void
2345 remove_tap_listener_h245dg_calls(voip_calls_tapinfo_t *tap_id_base)
2346 {
2347     if (tap_id_base->h245_labels) {
2348         g_free(tap_id_base->h245_labels);
2349         tap_id_base->h245_labels = NULL;
2350     }
2351     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_h245dg_));
2352 }
2353
2354 /****************************************************************************/
2355 /****************************TAP for SDP PROTOCOL ***************************/
2356 /****************************************************************************/
2357 /* whenever a SDP packet is seen by the tap listener */
2358 static gboolean
2359 sdp_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt _U_, const void *SDPinfo)
2360 {
2361     voip_calls_tapinfo_t  *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sdp_);
2362     const sdp_packet_info *pi      = (const sdp_packet_info *)SDPinfo;
2363
2364     /* There are protocols like MGCP/SIP where the SDP is called before the tap for the
2365        MGCP/SIP packet, in those cases we assign the SPD summary to global lastSDPsummary
2366        to use it later
2367      */
2368     g_free(tapinfo->sdp_summary);
2369     tapinfo->sdp_frame_num = pinfo->num;
2370     /* Append to graph the SDP summary if the packet exists */
2371     tapinfo->sdp_summary = g_strdup_printf("SDP (%s)", pi->summary_str);
2372     append_to_frame_graph(tapinfo, pinfo->num, tapinfo->sdp_summary, NULL);
2373
2374     tapinfo->redraw |= REDRAW_SDP;
2375
2376     return TRUE;  /* refresh output */
2377 }
2378
2379 /****************************************************************************/
2380 static void
2381 sdp_calls_draw(void *tap_offset_ptr)
2382 {
2383     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sdp_);
2384
2385     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_SDP)) {
2386         tapinfo->tap_draw(tapinfo);
2387         tapinfo->redraw &= ~REDRAW_SDP;
2388     }
2389 }
2390
2391 /****************************************************************************/
2392 /* TAP INTERFACE */
2393 /****************************************************************************/
2394 void
2395 sdp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
2396 {
2397     GString *error_string;
2398
2399     error_string = register_tap_listener("sdp", tap_base_to_id(tap_id_base, tap_id_offset_sdp_), NULL,
2400             0,
2401             NULL,
2402             sdp_calls_packet,
2403             sdp_calls_draw
2404             );
2405
2406     if (error_string != NULL) {
2407         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2408                 "%s", error_string->str);
2409         g_string_free(error_string, TRUE);
2410     }
2411 }
2412
2413 /****************************************************************************/
2414 void
2415 remove_tap_listener_sdp_calls(voip_calls_tapinfo_t *tap_id_base)
2416 {
2417     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_sdp_));
2418 }
2419
2420 /****************************************************************************/
2421 /* ***************************TAP for MGCP **********************************/
2422 /****************************************************************************/
2423
2424 /*
2425    This function will look for a signal/event in the SignalReq/ObsEvent string
2426    and return true if it is found
2427 */
2428 static gboolean
2429 is_mgcp_signal(const gchar *signal_str_p, const gchar *signalStr)
2430 {
2431     gint    i;
2432     gchar **resultArray;
2433
2434     /* if there is no signalStr, just return false */
2435     if (signalStr == NULL) return FALSE;
2436
2437     /* if are both "blank" return true */
2438     if ( (*signal_str_p == '\0') &&  (*signalStr == '\0') ) return TRUE;
2439
2440     /* look for signal in signalStr */
2441     resultArray = g_strsplit(signalStr, ",", 10);
2442
2443     for (i = 0; resultArray[i]; i++) {
2444         g_strstrip(resultArray[i]);
2445         if (strcmp(resultArray[i], signal_str_p) == 0) return TRUE;
2446     }
2447
2448     g_strfreev(resultArray);
2449
2450     return FALSE;
2451 }
2452
2453 /*
2454    This function will get the Caller ID info and replace the current string
2455    This is how it looks the caller Id: rg, ci(02/16/08/29, "3035550002","Ale Sipura 2")
2456 */
2457 static void
2458 mgcp_caller_id(gchar *signalStr, gchar **callerId)
2459 {
2460     gchar **arrayStr;
2461
2462     /* if there is no signalStr, just return false */
2463     if (signalStr == NULL) return;
2464
2465     arrayStr = g_strsplit(signalStr, "\"", 3);
2466
2467     /* look for the ci signal */
2468     if (g_strv_length(arrayStr) == 3 && strstr(arrayStr[0], "ci(")) {
2469         /* free the previous "From" field of the call, and assign the new */
2470         g_free(*callerId);
2471         *callerId = g_strdup(arrayStr[1]);
2472     }
2473     g_strfreev(arrayStr);
2474 }
2475
2476 /*
2477    This function will get the Dialed Digits and replace the current string
2478    This is how it looks the dialed digits 5,5,5,0,0,0,2,#,*
2479 */
2480 static void
2481 mgcp_dialed_digits(gchar *signalStr, gchar **dialedDigits)
2482 {
2483     gchar *tmpStr;
2484     gchar *resultStr;
2485     gint   i,j;
2486
2487     /* start with 1 for the null-terminator */
2488     guint resultStrLen = 1;
2489
2490     /* if there is no signalStr, just return false */
2491     if (signalStr == NULL) return;
2492
2493     tmpStr = g_strdup(signalStr);
2494
2495     for ( i = 0 ; tmpStr[i] ; i++) {
2496         switch (tmpStr[i]) {
2497             case '0' : case '1' : case '2' : case '3' : case '4' :
2498             case '5' : case '6' : case '7' : case '8' : case '9' :
2499             case '#' : case '*' :
2500                 resultStrLen++;
2501                 break;
2502             default:
2503                 tmpStr[i] = '?';
2504                 break;
2505         }
2506     }
2507
2508     if (resultStrLen == 1) {
2509         g_free(tmpStr);
2510         return;
2511     }
2512
2513     resultStr = (gchar *)g_malloc(resultStrLen);
2514
2515     for (i = 0, j = 0; tmpStr[i]; i++) {
2516         if (tmpStr[i] != '?')
2517             resultStr[j++] = tmpStr[i];
2518     }
2519     resultStr[j] = '\0';
2520
2521     g_free(*dialedDigits);
2522     g_free(tmpStr);
2523
2524     *dialedDigits = resultStr;
2525
2526     return;
2527 }
2528
2529
2530
2531 /****************************************************************************/
2532 /* whenever a MGCP packet is seen by the tap listener */
2533 static gboolean
2534 mgcp_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *MGCPinfo)
2535 {
2536     voip_calls_tapinfo_t *tapinfo      = tap_id_to_base(tap_offset_ptr, tap_id_offset_mgcp_);
2537     voip_calls_info_t    *tmp_listinfo;
2538     voip_calls_info_t    *callsinfo    = NULL;
2539     mgcp_calls_info_t    *tmp_mgcpinfo = NULL;
2540     GList                *list;
2541     GList                *listGraph    = NULL;
2542     gchar                *frame_label  = NULL;
2543     gchar                *comment      = NULL;
2544     seq_analysis_item_t  *gai          = NULL;
2545     gboolean              newcall      = FALSE;
2546     gboolean              fromEndpoint = FALSE; /* true for calls originated in Endpoints, false for calls from MGC */
2547     gdouble               diff_time;
2548
2549     const mgcp_info_t *pi = (const mgcp_info_t *)MGCPinfo;
2550
2551
2552     if ((pi->mgcp_type == MGCP_REQUEST) && !pi->is_duplicate ) {
2553         /* check whether we already have a call with this Endpoint and it is active*/
2554         list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
2555         while (list)
2556         {
2557             tmp_listinfo=(voip_calls_info_t *)list->data;
2558             if ((tmp_listinfo->protocol == VOIP_MGCP) && (tmp_listinfo->call_active_state == VOIP_ACTIVE)) {
2559                 tmp_mgcpinfo = (mgcp_calls_info_t *)tmp_listinfo->prot_info;
2560                 if (pi->endpointId != NULL) {
2561                     if (g_ascii_strcasecmp(tmp_mgcpinfo->endpointId,pi->endpointId) == 0) {
2562                         /*
2563                            check first if it is an ended call. We can still match packets to this Endpoint 2 seconds
2564                            after the call has been released
2565                          */
2566                         diff_time = nstime_to_sec(&pinfo->rel_ts) - nstime_to_sec(&tmp_listinfo->stop_rel_ts);
2567                         if ( ((tmp_listinfo->call_state == VOIP_CANCELLED) ||
2568                                     (tmp_listinfo->call_state == VOIP_COMPLETED)  ||
2569                                     (tmp_listinfo->call_state == VOIP_REJECTED)) &&
2570                                 (diff_time > 2) )
2571                         {
2572                             tmp_listinfo->call_active_state = VOIP_INACTIVE;
2573                         } else {
2574                             callsinfo = (voip_calls_info_t*)(list->data);
2575                             break;
2576                         }
2577                     }
2578                 }
2579             }
2580             list = g_list_next (list);
2581         }
2582
2583         /* there is no call with this Endpoint, lets see if this a new call or not */
2584         if (callsinfo == NULL) {
2585             if ( (strcmp(pi->code, "NTFY") == 0) && is_mgcp_signal("hd", pi->observedEvents) ) { /* off hook transition */
2586                 /* this is a new call from the Endpoint */
2587                 fromEndpoint = TRUE;
2588                 newcall = TRUE;
2589             } else if (strcmp(pi->code, "CRCX") == 0) {
2590                 /* this is a new call from the MGC */
2591                 fromEndpoint = FALSE;
2592                 newcall = TRUE;
2593             }
2594             if (!newcall) return FALSE;
2595         }
2596     } else if ( ((pi->mgcp_type == MGCP_RESPONSE) && pi->request_available) ||
2597             ((pi->mgcp_type == MGCP_REQUEST) && pi->is_duplicate) ) {
2598         /* if it is a response OR if it is a duplicated Request, lets look in the Graph to see
2599            if there is a request that matches */
2600         if(tapinfo->graph_analysis){
2601             listGraph = g_queue_peek_nth_link(tapinfo->graph_analysis->items, 0);
2602         }
2603         while (listGraph)
2604         {
2605             gai = (seq_analysis_item_t *)listGraph->data;
2606             if (gai->frame_number == pi->req_num) {
2607                 /* there is a request that match, so look the associated call with this call_num */
2608                 list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
2609                 while (list)
2610                 {
2611                     tmp_listinfo=(voip_calls_info_t *)list->data;
2612                     if (tmp_listinfo->protocol == VOIP_MGCP) {
2613                         if (tmp_listinfo->call_num == gai->conv_num) {
2614                             tmp_mgcpinfo = (mgcp_calls_info_t *)tmp_listinfo->prot_info;
2615                             callsinfo = (voip_calls_info_t*)(list->data);
2616                             break;
2617                         }
2618                     }
2619                     list = g_list_next (list);
2620                 }
2621                 if (callsinfo != NULL) break;
2622             }
2623             listGraph = g_list_next(listGraph);
2624         }
2625         /* if there is not a matching request, just return */
2626         if (callsinfo == NULL) return FALSE;
2627     } else return FALSE;
2628
2629     /* not in the list? then create a new entry */
2630     if (callsinfo==NULL) {
2631         callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
2632         callsinfo->call_active_state = VOIP_ACTIVE;
2633         callsinfo->call_state = VOIP_CALL_SETUP;
2634         if (fromEndpoint) {
2635             callsinfo->from_identity=g_strdup(pi->endpointId);
2636             callsinfo->to_identity=g_strdup("");
2637         } else {
2638             callsinfo->from_identity=g_strdup("");
2639             callsinfo->to_identity=g_strdup(pi->endpointId);
2640         }
2641         copy_address(&(callsinfo->initial_speaker),&(pinfo->src));
2642         callsinfo->selected=FALSE;
2643         callsinfo->start_fd=pinfo->fd;
2644         callsinfo->start_rel_ts=pinfo->rel_ts;
2645         callsinfo->protocol=VOIP_MGCP;
2646         callsinfo->prot_info=g_malloc(sizeof(mgcp_calls_info_t));
2647         callsinfo->free_prot_info = g_free;
2648         tmp_mgcpinfo=(mgcp_calls_info_t *)callsinfo->prot_info;
2649         tmp_mgcpinfo->endpointId = g_strdup(pi->endpointId);
2650         tmp_mgcpinfo->fromEndpoint = fromEndpoint;
2651         callsinfo->npackets = 0;
2652         callsinfo->call_num = tapinfo->ncalls++;
2653         g_queue_push_tail(tapinfo->callsinfos, callsinfo);
2654     }
2655
2656     g_assert(tmp_mgcpinfo != NULL);
2657
2658     /* change call state and add to graph */
2659     switch (pi->mgcp_type)
2660     {
2661         case MGCP_REQUEST:
2662             if ( (strcmp(pi->code, "NTFY") == 0) && (pi->observedEvents != NULL) ) {
2663                 frame_label = g_strdup_printf("%s ObsEvt:%s",pi->code, pi->observedEvents);
2664
2665                 if (tmp_mgcpinfo->fromEndpoint) {
2666                     /* use the Dialed digits to fill the "To" for the call, but use the first NTFY */
2667                     if (callsinfo->to_identity[0] == '\0') mgcp_dialed_digits(pi->observedEvents, &(callsinfo->to_identity));
2668
2669                     /* from MGC and the user picked up, the call is connected */
2670                 } else if (is_mgcp_signal("hd", pi->observedEvents))
2671                     callsinfo->call_state=VOIP_IN_CALL;
2672
2673                 /* hung up signal */
2674                 if (is_mgcp_signal("hu", pi->observedEvents)) {
2675                     if ((callsinfo->call_state == VOIP_CALL_SETUP) || (callsinfo->call_state == VOIP_RINGING)) {
2676                         callsinfo->call_state = VOIP_CANCELLED;
2677                     } else {
2678                         callsinfo->call_state = VOIP_COMPLETED;
2679                     }
2680                 }
2681
2682             } else if (strcmp(pi->code, "RQNT") == 0) {
2683                 /* for calls from Endpoint: if there is a "no signal" RQNT and the call was RINGING, we assume this is the CONNECT */
2684                 if ( tmp_mgcpinfo->fromEndpoint && is_mgcp_signal("", pi->signalReq) && (callsinfo->call_state == VOIP_RINGING) ) {
2685                     callsinfo->call_state = VOIP_IN_CALL;
2686                 }
2687
2688                 /* if there is ringback or ring tone, change state to ringing */
2689                 if ( is_mgcp_signal("rg", pi->signalReq) || is_mgcp_signal("rt", pi->signalReq) ) {
2690                     callsinfo->call_state = VOIP_RINGING;
2691                 }
2692
2693                 /* if there is a Busy or ReorderTone, and the call was Ringing or Setup the call is Rejected */
2694                 if ( (is_mgcp_signal("ro", pi->signalReq) || is_mgcp_signal("bz", pi->signalReq)) && ((callsinfo->call_state == VOIP_CALL_SETUP) || (callsinfo->call_state == VOIP_RINGING)) ) {
2695                     callsinfo->call_state = VOIP_REJECTED;
2696                 }
2697
2698                 if (pi->signalReq != NULL)
2699                     frame_label = g_strdup_printf("%s%sSigReq:%s",pi->code, (pi->hasDigitMap == TRUE)?" DigitMap ":"", pi->signalReq);
2700                 else
2701                     frame_label = g_strdup_printf("%s%s",pi->code, (pi->hasDigitMap == TRUE)?" DigitMap ":"");
2702
2703                 /* use the CallerID info to fill the "From" for the call */
2704                 if (!tmp_mgcpinfo->fromEndpoint) mgcp_caller_id(pi->signalReq, &(callsinfo->from_identity));
2705
2706             } else if (strcmp(pi->code, "DLCX") == 0) {
2707                 /*
2708                    if there is a DLCX in a call To an Endpoint and the call was not connected, we use
2709                    the DLCX as the end of the call
2710                  */
2711                 if (!tmp_mgcpinfo->fromEndpoint) {
2712                     if ((callsinfo->call_state == VOIP_CALL_SETUP) || (callsinfo->call_state == VOIP_RINGING)) {
2713                         callsinfo->call_state = VOIP_CANCELLED;
2714                     }
2715                 }
2716             }
2717
2718             if (frame_label == NULL) frame_label = g_strdup(pi->code);
2719             break;
2720         case MGCP_RESPONSE:
2721             frame_label = g_strdup_printf("%u (%s)",pi->rspcode, pi->code);
2722             break;
2723         case MGCP_OTHERS:
2724             /* XXX what to do? */
2725             break;
2726     }
2727
2728     comment = g_strdup_printf("MGCP %s %s%s", tmp_mgcpinfo->endpointId, (pi->mgcp_type == MGCP_REQUEST)?"Request":"Response", pi->is_duplicate?" Duplicate":"");
2729
2730     callsinfo->stop_fd = pinfo->fd;
2731     callsinfo->stop_rel_ts = pinfo->rel_ts;
2732     ++(callsinfo->npackets);
2733     /* increment the packets counter of all calls */
2734     ++(tapinfo->npackets);
2735
2736     /* add to the graph */
2737     add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
2738     g_free(comment);
2739     g_free(frame_label);
2740
2741     /* add SDP info if apply */
2742     if ( (tapinfo->sdp_summary != NULL) && (tapinfo->sdp_frame_num == pinfo->num) ) {
2743         append_to_frame_graph(tapinfo, pinfo->num, tapinfo->sdp_summary, NULL);
2744         g_free(tapinfo->sdp_summary);
2745         tapinfo->sdp_summary = NULL;
2746     }
2747
2748     tapinfo->redraw |= REDRAW_MGCP;
2749
2750     return TRUE;  /* refresh output */
2751 }
2752
2753 /****************************************************************************/
2754 static void
2755 mgcp_calls_draw(void *tap_offset_ptr)
2756 {
2757     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_mgcp_);
2758
2759     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_MGCP)) {
2760         tapinfo->tap_draw(tapinfo);
2761         tapinfo->redraw &= ~REDRAW_MGCP;
2762     }
2763 }
2764
2765 /****************************************************************************/
2766 /* TAP INTERFACE */
2767 /****************************************************************************/
2768 void
2769 mgcp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
2770 {
2771     GString *error_string;
2772
2773     /*
2774      * We set TL_REQUIRES_PROTO_TREE to force a non-null "tree"
2775      * in the MGCP dissector; otherwise, the dissector
2776      * doesn't fill in the info passed to the tap's packet
2777      * routine.
2778      */
2779     error_string = register_tap_listener("mgcp",
2780             tap_base_to_id(tap_id_base, tap_id_offset_mgcp_),
2781             NULL,
2782             TL_REQUIRES_PROTO_TREE,
2783             NULL,
2784             mgcp_calls_packet,
2785             mgcp_calls_draw
2786             );
2787     if (error_string != NULL) {
2788         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2789                 "%s", error_string->str);
2790         g_string_free(error_string, TRUE);
2791     }
2792 }
2793
2794 /****************************************************************************/
2795 void
2796 remove_tap_listener_mgcp_calls(voip_calls_tapinfo_t *tap_id_base)
2797 {
2798     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_mgcp_));
2799 }
2800
2801 /****************************************************************************/
2802 /****************************TAP for ACTRACE (AudioCodes trace)**************/
2803 /****************************************************************************/
2804
2805 /* whenever a ACTRACE packet is seen by the tap listener */
2806 static gboolean
2807 actrace_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *ACTRACEinfo)
2808 {
2809     voip_calls_tapinfo_t     *tapinfo   = tap_id_to_base(tap_offset_ptr, tap_id_offset_actrace_);
2810     const actrace_info_t     *pi        = (const actrace_info_t *)ACTRACEinfo;
2811     GList                    *list;
2812     actrace_cas_calls_info_t *tmp_actrace_cas_info;
2813     voip_calls_info_t        *tmp_listinfo;
2814     voip_calls_info_t        *callsinfo = NULL;
2815
2816     tapinfo->actrace_frame_num = pinfo->num;
2817     tapinfo->actrace_trunk = pi->trunk;
2818     tapinfo->actrace_direction = pi->direction;
2819
2820     if (pi->type == 1) { /* is CAS protocol */
2821         address pstn_add;
2822         gchar *comment = NULL;
2823
2824         callsinfo = NULL;
2825         list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
2826         while (list)
2827         {
2828             tmp_listinfo=(voip_calls_info_t *)list->data;
2829             if ( tmp_listinfo->protocol == VOIP_AC_CAS ) {
2830                 tmp_actrace_cas_info = (actrace_cas_calls_info_t *)tmp_listinfo->prot_info;
2831                 /* TODO: Also check the IP of the Blade, and if the call is complete (no active) */
2832                 if ( (tmp_actrace_cas_info->bchannel == pi->cas_bchannel) && (tmp_actrace_cas_info->trunk == tapinfo->actrace_trunk) ) {
2833                     callsinfo = (voip_calls_info_t*)(list->data);
2834                     break;
2835                 }
2836             }
2837             list = g_list_next (list);
2838         }
2839
2840         set_address(&pstn_add, AT_STRINGZ, 5, "PSTN");
2841
2842         /* if it is a new call, add it to the list */
2843         if (!callsinfo) {
2844             callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
2845             callsinfo->call_active_state = VOIP_ACTIVE;
2846             callsinfo->call_state = VOIP_CALL_SETUP;
2847             callsinfo->from_identity=g_strdup("N/A");
2848             callsinfo->to_identity=g_strdup("N/A");
2849             copy_address(&(callsinfo->initial_speaker),tapinfo->actrace_direction?&pstn_add:&(pinfo->src));
2850             callsinfo->selected=FALSE;
2851             callsinfo->start_fd=pinfo->fd;
2852             callsinfo->start_rel_ts=pinfo->rel_ts;
2853             callsinfo->protocol=VOIP_AC_CAS;
2854             callsinfo->prot_info=g_malloc(sizeof(actrace_cas_calls_info_t));
2855             callsinfo->free_prot_info = g_free;
2856
2857             tmp_actrace_cas_info=(actrace_cas_calls_info_t *)callsinfo->prot_info;
2858             tmp_actrace_cas_info->bchannel=pi->cas_bchannel;
2859             tmp_actrace_cas_info->trunk=tapinfo->actrace_trunk;
2860             callsinfo->npackets = 0;
2861             callsinfo->call_num = tapinfo->ncalls++;
2862             g_queue_push_tail(tapinfo->callsinfos, callsinfo);
2863         }
2864
2865         callsinfo->stop_fd = pinfo->fd;
2866         callsinfo->stop_rel_ts = pinfo->rel_ts;
2867         ++(callsinfo->npackets);
2868         /* increment the packets counter of all calls */
2869         ++(tapinfo->npackets);
2870
2871         comment = g_strdup_printf("AC_CAS  trunk:%u", tapinfo->actrace_trunk);
2872
2873         add_to_graph(tapinfo, pinfo, edt, pi->cas_frame_label, comment, callsinfo->call_num,
2874                 tapinfo->actrace_direction?&pstn_add:&(pinfo->src),
2875                 tapinfo->actrace_direction?&(pinfo->src):&pstn_add,
2876                 1 );
2877
2878         g_free(comment);
2879     }
2880
2881     tapinfo->redraw |= REDRAW_ACTRACE;
2882
2883     return TRUE;  /* refresh output */
2884 }
2885
2886 /****************************************************************************/
2887 static void
2888 actrace_calls_draw(void *tap_offset_ptr)
2889 {
2890     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_actrace_);
2891
2892     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_ACTRACE)) {
2893         tapinfo->tap_draw(tapinfo);
2894         tapinfo->redraw &= ~REDRAW_ACTRACE;
2895     }
2896 }
2897
2898 /****************************************************************************/
2899 /* TAP INTERFACE */
2900 /****************************************************************************/
2901 void
2902 actrace_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
2903 {
2904     GString *error_string;
2905
2906     error_string = register_tap_listener("actrace", tap_base_to_id(tap_id_base, tap_id_offset_actrace_), NULL,
2907             0,
2908             NULL,
2909             actrace_calls_packet,
2910             actrace_calls_draw
2911             );
2912
2913     if (error_string != NULL) {
2914         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2915                 "%s", error_string->str);
2916         g_string_free(error_string, TRUE);
2917     }
2918 }
2919
2920 /****************************************************************************/
2921 void
2922 remove_tap_listener_actrace_calls(voip_calls_tapinfo_t *tap_id_base)
2923 {
2924     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_actrace_));
2925 }
2926
2927
2928 /****************************************************************************/
2929 /**************************** TAP for H248/MEGACO **********************************/
2930 /****************************************************************************/
2931
2932 #define gcp_is_req(type) ( type == GCP_CMD_ADD_REQ || type == GCP_CMD_MOVE_REQ || type == GCP_CMD_MOD_REQ || \
2933                            type == GCP_CMD_SUB_REQ || type == GCP_CMD_AUDITCAP_REQ || type == GCP_CMD_AUDITVAL_REQ || \
2934                            type == GCP_CMD_NOTIFY_REQ || type == GCP_CMD_SVCCHG_REQ || type == GCP_CMD_TOPOLOGY_REQ || \
2935                            type == GCP_CMD_CTX_ATTR_AUDIT_REQ )
2936
2937
2938 static gboolean
2939 h248_calls_packet_common(voip_calls_tapinfo_t *tapinfo, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info, guint32 redraw_bit) {
2940     const gcp_cmd_t      *cmd       = (const gcp_cmd_t *)prot_info;
2941     GList                *list;
2942     voip_calls_info_t    *callsinfo = NULL;
2943     address              *mgw;
2944     address              *mgc;
2945     gchar                 mgw_addr[128];
2946
2947     if (cmd->ctx->id == NULL_CONTEXT || cmd->ctx->id == ALL_CONTEXTS ) {
2948         return FALSE;
2949     }
2950
2951     if ( gcp_is_req(cmd->type) ) {
2952         mgw = &(pinfo->dst);
2953         mgc = &(pinfo->src);
2954     } else {
2955         mgc = &(pinfo->dst);
2956         mgw = &(pinfo->src);
2957     }
2958
2959     address_to_str_buf(mgw, mgw_addr, 128);
2960
2961     /* check whether we already have this context in the list */
2962     list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
2963     while (list)
2964     {
2965         voip_calls_info_t* tmp_listinfo = (voip_calls_info_t *)list->data;
2966
2967         if (tmp_listinfo->protocol == TEL_H248) {
2968             if (tmp_listinfo->prot_info == cmd->ctx) {
2969                 callsinfo = (voip_calls_info_t*)(list->data);
2970                 break;
2971             }
2972         }
2973         list = g_list_next (list);
2974     }
2975
2976     if (callsinfo==NULL) {
2977
2978         callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
2979         callsinfo->call_state = VOIP_NO_STATE;
2980         callsinfo->call_active_state = VOIP_ACTIVE;
2981         callsinfo->from_identity = g_strdup_printf("%s : %.8x", mgw_addr, cmd->ctx->id);
2982         callsinfo->to_identity = g_strdup("");
2983         callsinfo->prot_info = cmd->ctx;
2984         callsinfo->free_prot_info = NULL;
2985
2986         callsinfo->npackets = 1;
2987
2988         copy_address(&(callsinfo->initial_speaker), mgc);
2989
2990         callsinfo->protocol = TEL_H248;
2991         callsinfo->call_num = tapinfo->ncalls++;
2992         callsinfo->start_fd = pinfo->fd;
2993         callsinfo->start_rel_ts = pinfo->rel_ts;
2994         callsinfo->stop_fd = pinfo->fd;
2995         callsinfo->stop_rel_ts = pinfo->rel_ts;
2996
2997         callsinfo->selected = FALSE;
2998
2999         g_queue_push_tail(tapinfo->callsinfos, callsinfo);
3000
3001     } else {
3002         GString *s = g_string_new("");
3003         gcp_terms_t *ctx_term;
3004
3005         g_free(callsinfo->from_identity);
3006         callsinfo->from_identity = g_strdup_printf("%s : %.8x", mgw_addr, ((gcp_ctx_t*)callsinfo->prot_info)->id);
3007
3008         g_free(callsinfo->to_identity);
3009
3010         for (ctx_term = ((gcp_ctx_t*)callsinfo->prot_info)->terms.next;
3011                 ctx_term;
3012                 ctx_term = ctx_term->next ) {
3013             if ( ctx_term->term && ctx_term->term->str) {
3014                 g_string_append_printf(s," %s",ctx_term->term->str);
3015             }
3016         }
3017
3018         callsinfo->to_identity = g_string_free(s,FALSE);
3019
3020         callsinfo->stop_fd = pinfo->fd;
3021         callsinfo->stop_rel_ts = pinfo->rel_ts;
3022         ++(callsinfo->npackets);
3023     }
3024
3025     add_to_graph(tapinfo, pinfo, edt, cmd->str ? cmd->str : "unknown Msg",
3026             wmem_strdup_printf(wmem_packet_scope(), "TrxId = %u, CtxId = %.8x",cmd->trx->id,cmd->ctx->id),
3027             callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3028
3029     ++(tapinfo->npackets);
3030
3031     tapinfo->redraw |= redraw_bit;
3032
3033     return TRUE;
3034 }
3035
3036 static gboolean
3037 h248_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info) {
3038     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_h248_);
3039
3040     return h248_calls_packet_common(tapinfo, pinfo, edt, prot_info, REDRAW_H248);
3041 }
3042
3043 static void
3044 h248_calls_draw(void *tap_offset_ptr)
3045 {
3046     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_h248_);
3047
3048     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_H248)) {
3049         tapinfo->tap_draw(tapinfo);
3050         tapinfo->redraw &= ~REDRAW_H248;
3051     }
3052 }
3053
3054 static gboolean
3055 megaco_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info) {
3056     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_megaco_);
3057
3058     return h248_calls_packet_common(tapinfo, pinfo, edt, prot_info, REDRAW_MEGACO);
3059 }
3060
3061 static void
3062 megaco_calls_draw(void *tap_offset_ptr)
3063 {
3064     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_megaco_);
3065
3066     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_MEGACO)) {
3067         tapinfo->tap_draw(tapinfo);
3068         tapinfo->redraw &= ~REDRAW_MEGACO;
3069     }
3070 }
3071
3072 void
3073 h248_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
3074 {
3075     GString *error_string;
3076
3077     error_string = register_tap_listener("megaco", tap_base_to_id(tap_id_base, tap_id_offset_megaco_),
3078             NULL,
3079             0,
3080             NULL,
3081             megaco_calls_packet,
3082             megaco_calls_draw);
3083
3084     if (error_string != NULL) {
3085         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3086                 "%s", error_string->str);
3087         g_string_free(error_string, TRUE);
3088     }
3089
3090     error_string = register_tap_listener("h248", tap_base_to_id(tap_id_base, tap_id_offset_h248_),
3091             NULL,
3092             0,
3093             NULL,
3094             h248_calls_packet,
3095             h248_calls_draw);
3096
3097     if (error_string != NULL) {
3098         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3099                 "%s", error_string->str);
3100         g_string_free(error_string, TRUE);
3101     }
3102 }
3103
3104 void
3105 remove_tap_listener_h248_calls(voip_calls_tapinfo_t *tap_id_base)
3106 {
3107     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_h248_));
3108     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_megaco_));
3109 }
3110
3111 /****************************************************************************/
3112 /**************************** TAP for SCCP and SUA **********************************/
3113 /**************************** ( RANAP and BSSAP ) **********************************/
3114 /****************************************************************************/
3115
3116 static const voip_protocol sccp_proto_map[] = {
3117     TEL_SCCP,
3118     TEL_BSSMAP,
3119     TEL_RANAP
3120 };
3121 #define SP2VP(ap) ((ap) < SCCP_PLOAD_NUM_PLOADS ? sccp_proto_map[(ap)] : TEL_SCCP)
3122 const value_string* sccp_payload_values;
3123
3124 static gboolean
3125 sccp_calls(voip_calls_tapinfo_t *tapinfo, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info, guint32 redraw_bit) {
3126     const sccp_msg_info_t*  msg       = (const sccp_msg_info_t *)prot_info;
3127     sccp_assoc_info_t*      assoc     = msg->data.co.assoc;
3128     GList                  *list;
3129     voip_calls_info_t      *callsinfo = NULL;
3130     gchar                  *label     = NULL;
3131     const gchar            *comment   = NULL;
3132     /* check whether we already have this assoc in the list */
3133
3134     for(list = g_queue_peek_nth_link(tapinfo->callsinfos, 0) ; list ; list = g_list_next (list) ) {
3135         if ( ((voip_calls_info_t*)(list->data))->prot_info == assoc ) {
3136             callsinfo = (voip_calls_info_t*)(list->data);
3137             break;
3138         }
3139     }
3140
3141     if (callsinfo==NULL) {
3142         callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
3143         callsinfo->call_state = VOIP_CALL_SETUP;
3144         callsinfo->call_active_state = VOIP_ACTIVE;
3145         if ( assoc->calling_party ) {
3146             callsinfo->from_identity =  g_strdup(assoc->calling_party);
3147         } else {
3148             callsinfo->from_identity =  g_strdup("Unknown");
3149         }
3150
3151         if ( assoc->called_party ) {
3152             callsinfo->to_identity =  g_strdup(assoc->called_party);
3153         } else {
3154             callsinfo->to_identity =  g_strdup("Unknown");
3155         }
3156
3157         callsinfo->prot_info = (void*)assoc;
3158         callsinfo->free_prot_info = NULL;
3159
3160         callsinfo->npackets = 1;
3161
3162         copy_address(&(callsinfo->initial_speaker), &(pinfo->src));
3163
3164         callsinfo->protocol =   SP2VP(assoc->payload);
3165         /* Store frame data which holds time and frame number */
3166         callsinfo->start_fd = pinfo->fd;
3167         callsinfo->start_rel_ts = pinfo->rel_ts;
3168         callsinfo->stop_fd = pinfo->fd;
3169         callsinfo->stop_rel_ts = pinfo->rel_ts;
3170
3171         callsinfo->selected = FALSE;
3172         callsinfo->call_num = tapinfo->ncalls++;
3173
3174         g_queue_push_tail(tapinfo->callsinfos, callsinfo);
3175     } else {
3176
3177         if ( assoc->calling_party ) {
3178             g_free(callsinfo->from_identity);
3179             callsinfo->from_identity =  g_strdup(assoc->calling_party);
3180         }
3181
3182         if ( assoc->called_party ) {
3183             g_free(callsinfo->to_identity);
3184             callsinfo->to_identity =  g_strdup(assoc->called_party);
3185         }
3186
3187         callsinfo->protocol =  SP2VP(assoc->payload);
3188         /* Store frame data which holds stop time and frame number */
3189         callsinfo->stop_fd = pinfo->fd;
3190         callsinfo->stop_rel_ts = pinfo->rel_ts;
3191         ++(callsinfo->npackets);
3192
3193         switch (msg->type) {
3194             case SCCP_MSG_TYPE_CC:
3195                 callsinfo->call_state = VOIP_IN_CALL;
3196                 break;
3197             case SCCP_MSG_TYPE_RLC:
3198                 callsinfo->call_state = VOIP_COMPLETED;
3199                 callsinfo->call_active_state = VOIP_INACTIVE;
3200                 break;
3201             default:
3202                 break;
3203         }
3204     }
3205
3206     if (msg->data.co.label) {
3207         label = wmem_strdup(NULL, msg->data.co.label);
3208     } else {
3209         label = val_to_str_wmem(NULL, msg->type, sccp_payload_values, "Unknown(%d)");
3210     }
3211
3212     if (msg->data.co.comment) {
3213         comment = msg->data.co.comment;
3214     } else {
3215         comment = NULL;
3216     }
3217
3218     add_to_graph(tapinfo, pinfo, edt, label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3219     wmem_free(NULL, label);
3220
3221     ++(tapinfo->npackets);
3222
3223     tapinfo->redraw |= redraw_bit;
3224
3225     return TRUE;
3226 }
3227
3228 static gboolean
3229 sccp_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info) {
3230     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sccp_);
3231
3232     sccp_payload_values = sccp_message_type_acro_values;
3233     return sccp_calls(tapinfo, pinfo, edt, prot_info, REDRAW_SCCP);
3234 }
3235
3236 static void
3237 sccp_calls_draw(void *tap_offset_ptr)
3238 {
3239     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sccp_);
3240
3241     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_SCCP)) {
3242         tapinfo->tap_draw(tapinfo);
3243         tapinfo->redraw &= ~REDRAW_SCCP;
3244     }
3245 }
3246
3247 static gboolean
3248 sua_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *prot_info) {
3249     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sua_);
3250
3251     sccp_payload_values = sua_co_class_type_acro_values;
3252     return sccp_calls(tapinfo, pinfo, edt, prot_info, REDRAW_SUA);
3253 }
3254
3255 static void
3256 sua_calls_draw(void *tap_offset_ptr)
3257 {
3258     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_sua_);
3259
3260     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_SUA)) {
3261         tapinfo->tap_draw(tapinfo);
3262         tapinfo->redraw &= ~REDRAW_SUA;
3263     }
3264 }
3265
3266 void sccp_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
3267 {
3268     GString *error_string;
3269
3270     error_string = register_tap_listener("sccp", tap_base_to_id(tap_id_base, tap_id_offset_sccp_),
3271             NULL,
3272             0,
3273             NULL,
3274             sccp_calls_packet,
3275             sccp_calls_draw);
3276
3277     if (error_string != NULL) {
3278         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3279                 "%s", error_string->str);
3280         g_string_free(error_string, TRUE);
3281     }
3282
3283     error_string = register_tap_listener("sua", tap_base_to_id(tap_id_base, tap_id_offset_sua_),
3284             NULL,
3285             0,
3286             NULL,
3287             sua_calls_packet,
3288             sua_calls_draw);
3289
3290     if (error_string != NULL) {
3291         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3292                 "%s", error_string->str);
3293         g_string_free(error_string, TRUE);
3294     }
3295 }
3296
3297 void
3298 remove_tap_listener_sccp_calls(voip_calls_tapinfo_t *tap_id_base)
3299 {
3300     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_sccp_));
3301     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_sua_));
3302 }
3303
3304
3305 /****************************************************************************/
3306 /****************************TAP for UNISTIM ********************************/
3307 /****************************************************************************/
3308
3309 static gboolean
3310 unistim_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *unistim_info)
3311 {
3312     voip_calls_tapinfo_t *tapinfo          = tap_id_to_base(tap_offset_ptr, tap_id_offset_unistim_);
3313     voip_calls_info_t    *tmp_listinfo;
3314     voip_calls_info_t    *callsinfo        = NULL;
3315     unistim_info_t       *tmp_unistim_info = NULL;
3316     GList                *list             = NULL;
3317     GString              *g_tmp            = NULL;
3318     const gchar          *frame_label      = NULL;
3319     gchar                *comment          = NULL;
3320
3321     /* Fetch specific packet infos */
3322     const unistim_info_t *pi = (const unistim_info_t *)unistim_info;
3323
3324     /* Init gstring */
3325     g_tmp = g_string_new(NULL);
3326
3327     /* Check to see if this is a dup */
3328     list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
3329
3330     while(list)
3331     {
3332         tmp_listinfo = (voip_calls_info_t *)list->data;
3333
3334         if(tmp_listinfo->protocol == VOIP_UNISTIM) {
3335
3336             tmp_unistim_info = (unistim_info_t *)tmp_listinfo->prot_info;
3337
3338             /* Search by termid if possible, otherwise use ni/it ip + port.. */
3339             if(pi->termid != 0) {
3340                 if(tmp_unistim_info->termid == pi->termid) {
3341                     /* If the call has ended, then we can reuse it.. */
3342                     if(tmp_listinfo->call_state == VOIP_COMPLETED || tmp_listinfo->call_state == VOIP_UNKNOWN) {
3343                         /* Do nothing */
3344                     } else {
3345                         callsinfo = (voip_calls_info_t*)(list->data);
3346                         break;
3347                     }
3348                 }
3349             } else {
3350                 /* If no term id use ips / port to find entry */
3351                 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)) {
3352                     if(tmp_listinfo->call_state == VOIP_COMPLETED || tmp_listinfo->call_state == VOIP_UNKNOWN) {
3353                         /* Do nothing previous call */
3354                     } else {
3355                         callsinfo = (voip_calls_info_t*)(list->data);
3356                         break;
3357                     }
3358                 }
3359                 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)) {
3360                     if(tmp_listinfo->call_state == VOIP_COMPLETED || tmp_listinfo->call_state == VOIP_UNKNOWN) {
3361                         /* Do nothing, it ain't our call.. */
3362                     } else {
3363                         callsinfo = (voip_calls_info_t*)(list->data);
3364                         break;
3365                     }
3366                 }
3367             }
3368         }
3369
3370         /* Otherwise, go to the next one.. */
3371         list = g_list_next(list);
3372     }
3373
3374     if(pi->payload_type == 2 || pi->payload_type == 1) {
3375
3376         if(pi->key_state == 1 || pi->hook_state == 1) {
3377
3378             /* If the user hits a button,
3379                Session will be SETUP */
3380
3381             /* If new add to list */
3382             if (callsinfo==NULL) {
3383
3384                 callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
3385                 callsinfo->call_active_state = VOIP_ACTIVE;
3386                 callsinfo->call_state = VOIP_CALL_SETUP;
3387                 callsinfo->from_identity=g_strdup_printf("%x",pi->termid);
3388                 callsinfo->to_identity=g_strdup("UNKNOWN");
3389                 copy_address(&(callsinfo->initial_speaker),&(pinfo->src));
3390                 callsinfo->selected=FALSE;
3391
3392                 /* Set this on init of struct so in case the call doesn't complete, we'll have a ref. */
3393                 /* Otherwise if the call is completed we'll have the open/close streams to ref actual call duration */
3394                 /* Store frame data which holds time and frame number */
3395                 callsinfo->start_fd=pinfo->fd;
3396                 callsinfo->start_rel_ts=pinfo->rel_ts;
3397
3398                 callsinfo->protocol=VOIP_UNISTIM;
3399                 callsinfo->prot_info=g_malloc(sizeof(unistim_info_t));
3400
3401                 tmp_unistim_info = (unistim_info_t *)callsinfo->prot_info;
3402
3403                 /* Clear tap struct */
3404                 tmp_unistim_info->rudp_type = 0;
3405                 tmp_unistim_info->payload_type = 0;
3406                 tmp_unistim_info->sequence = pi->sequence;
3407                 tmp_unistim_info->termid = pi->termid;
3408                 tmp_unistim_info->key_val = -1;
3409                 tmp_unistim_info->key_state = -1;
3410                 tmp_unistim_info->hook_state = -1;
3411                 tmp_unistim_info->stream_connect = -1;
3412                 tmp_unistim_info->trans_connect = -1;
3413                 tmp_unistim_info->set_termid = -1;
3414                 tmp_unistim_info->string_data = NULL;
3415                 tmp_unistim_info->key_buffer = NULL;
3416
3417                 copy_address(&(tmp_unistim_info->it_ip),&(pi->it_ip));
3418                 copy_address(&(tmp_unistim_info->ni_ip),&(pi->ni_ip));
3419                 tmp_unistim_info->it_port = pi->it_port;
3420
3421                 callsinfo->free_prot_info = g_free;
3422                 callsinfo->npackets = 0;
3423                 callsinfo->call_num = tapinfo->ncalls++;
3424                 g_queue_push_tail(tapinfo->callsinfos, callsinfo);
3425
3426             } else {
3427
3428                 /* Set up call wide info struct */
3429                 tmp_unistim_info = (unistim_info_t *)callsinfo->prot_info;
3430                 tmp_unistim_info->sequence = pi->sequence;
3431             }
3432
3433             /* Each packet COULD BE OUR LAST!!!! */
3434             /* Store frame data which holds time and frame number */
3435             callsinfo->stop_fd = pinfo->fd;
3436             callsinfo->stop_rel_ts = pinfo->rel_ts;
3437
3438             /* This is a valid packet so increment counter */
3439             ++(callsinfo->npackets);
3440
3441             /* increment the packets counter of all calls */
3442             ++(tapinfo->npackets);
3443
3444             /* Key was depressed.. update key buffer.. */
3445             if(pi->key_val >= 0 && pi->key_val <= 11) {
3446
3447                 if(tmp_unistim_info->key_buffer != NULL) {
3448
3449                     /* assign to temp variable */
3450                     g_string_assign(g_tmp,tmp_unistim_info->key_buffer);
3451
3452                     /* Manipulate the data */
3453                     if(pi->key_val == 10) {
3454                         tmp_unistim_info->key_buffer = g_strdup_printf("%s*",g_tmp->str);
3455                     } else if(pi->key_val == 11) {
3456                         tmp_unistim_info->key_buffer = g_strdup_printf("%s#",g_tmp->str);
3457                     } else {
3458                         tmp_unistim_info->key_buffer = g_strdup_printf("%s%d",g_tmp->str,pi->key_val);
3459                     }
3460
3461                 } else {
3462
3463                     /* Create new string */
3464                     if(pi->key_val == 10) {
3465                         tmp_unistim_info->key_buffer = g_strdup("*");
3466                     } else if(pi->key_val == 11) {
3467                         tmp_unistim_info->key_buffer = g_strdup("#");
3468                     } else {
3469                         tmp_unistim_info->key_buffer = g_strdup_printf("%d",pi->key_val);
3470                     }
3471
3472                 }
3473
3474                 /* Select for non-digit characters */
3475                 if(pi->key_val == 10) {
3476                     comment = g_strdup_printf("Key Input Sent: * (%d)", pi->sequence);
3477                 } else if(pi->key_val == 11) {
3478                     comment = g_strdup_printf("Key Input Sent: # (%d)", pi->sequence);
3479                 } else {
3480                     comment = g_strdup_printf("Key Input Sent: %d (%d)",pi->key_val, pi->sequence);
3481                 }
3482             } else if(pi->key_val == 12) {
3483                 /* Set label and comment for graph */
3484                 comment = g_strdup_printf("Key Input Sent: UP (%d)", pi->sequence);
3485             } else if(pi->key_val == 13) {
3486                 /* Set label and comment for graph */
3487                 comment = g_strdup_printf("Key Input Sent: DOWN (%d)", pi->sequence);
3488             } else if(pi->key_val == 14) {
3489                 /* Set label and comment for graph */
3490                 comment = g_strdup_printf("Key Input Sent: RIGHT (%d)", pi->sequence);
3491             } else if(pi->key_val == 15) {
3492                 if(pi->key_buffer != NULL) {
3493                     /* Get data */
3494                     g_string_assign(g_tmp,pi->key_buffer);
3495
3496                     /* Manipulate the data */
3497                     g_string_truncate(g_tmp,g_tmp->len-1);
3498
3499                     /* Insert new data */
3500                     tmp_unistim_info->key_buffer = g_strdup(g_tmp->str);
3501                 }
3502
3503                 /* Set label and comment for graph */
3504                 comment = g_strdup_printf("Key Input Sent: LEFT (%d)", pi->sequence);
3505             } else if(pi->key_val == 20) {
3506                 /* User pressed the soft key 0 probably dial */
3507                 comment = g_strdup_printf("Key Input Sent: S0 (%d)", pi->sequence);
3508             } else if(pi->key_val == 21) {
3509                 /* User pressed the soft key 1 */
3510                 comment = g_strdup_printf("Key Input Sent: S1 (%d)", pi->sequence);
3511             } else if(pi->key_val == 22) {
3512                 /* User pressed the soft key 2 */
3513                 /* On cs2k phones, soft key 2 is backspace. */
3514                 if(pi->key_buffer != NULL) {
3515
3516                     /* Get data */
3517                     g_string_assign(g_tmp,pi->key_buffer);
3518
3519                     /* Manipulate the data */
3520                     g_string_truncate(g_tmp,g_tmp->len-1);
3521
3522                     /* Insert new data */
3523                     tmp_unistim_info->key_buffer = g_strdup(g_tmp->str);
3524                 }
3525
3526                 /* add label and comment */
3527                 comment = g_strdup_printf("Key Input Sent: S2 (%d)", pi->sequence);
3528             } else if(pi->key_val == 28) {
3529                 /* User pressed something */
3530                 comment = g_strdup_printf("Key Input Sent: Release (%d)", pi->sequence);
3531             } else if(pi->key_val == 23) {
3532                 /* User pressed the soft key 3 */
3533                 /* Cancel on cs2k so clear buffer */
3534                 /* On mcs it's config which will clear the buffer too */
3535                 tmp_unistim_info->key_buffer = g_strdup("\n");
3536
3537                 /* User pressed something, set labels*/
3538                 comment = g_strdup_printf("Key Input Sent: S3 (%d)", pi->sequence);
3539             } else if(pi->key_val == 27) {
3540                 /* User pressed something */
3541                 comment = g_strdup_printf("Key Input Sent: Hold (%d)", pi->sequence);
3542             } else if(pi->key_val == 29) {
3543                 /* User pressed something */
3544                 comment = g_strdup_printf("Key Input Sent: Mute (%d)", pi->sequence);
3545             } else if(pi->key_val == 30) {
3546                 /* User pressed something */
3547                 comment = g_strdup_printf("Key Input Sent: Headset (%d)", pi->sequence);
3548             } else if(pi->key_val == 31) {
3549                 /* Handsfree button */
3550                 comment = g_strdup_printf("Key Input Sent: Handsfree (%d)", pi->sequence);
3551             } else if(pi->key_val >= 32 && pi->key_val <= 56) {
3552                 /* Prog. Key X */
3553                 comment = g_strdup_printf("Key Input Sent: Prog%d (%d)", (pi->key_val & 31), pi->sequence);
3554             }
3555
3556             if(pi->key_val != -1) {
3557
3558                 frame_label = "KEY INPUT";
3559
3560                 if (comment == NULL)
3561                     /* Ouch! What do you do!? */
3562                     /* User pressed something */
3563                     comment = g_strdup_printf("Key Input Sent: UNKNOWN - %d (%d)", pi->key_val, pi->sequence);
3564
3565                 /* add to the graph */
3566                 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3567
3568                 g_free(comment);
3569             }
3570
3571             if(pi->hook_state == 1) {
3572
3573                 /* Phone is off hook */
3574                 frame_label = "OFF HOOK";
3575                 comment = g_strdup_printf("Off Hook (%d)", pi->sequence);
3576
3577                 /* add to the graph */
3578                 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3579
3580                 g_free(comment);
3581             } else if(pi->hook_state == 0) {
3582
3583                 /* Phone is on hook */
3584                 frame_label = "ON HOOK";
3585                 comment = g_strdup_printf("On Hook (%d)", pi->sequence);
3586
3587                 /* add to the graph */
3588                 add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3589
3590                 g_free(comment);
3591             }
3592         }
3593
3594         /* Open stream was sent from server */
3595         if(pi->stream_connect == 1 && callsinfo != NULL) {
3596
3597             /* Open stream */
3598             /* Signifies the start of the call so set start_sec & start_usec */
3599             /* Frame data holds the time info */
3600             callsinfo->start_fd=pinfo->fd;
3601             callsinfo->start_rel_ts=pinfo->rel_ts;
3602             /* Each packet COULD BE OUR LAST!!!! */
3603             /* Store frame data which holds time and frame number */
3604             callsinfo->stop_fd = pinfo->fd;
3605             callsinfo->stop_rel_ts = pinfo->rel_ts;
3606
3607             /* Local packets too */
3608             ++(callsinfo->npackets);
3609
3610             /* increment the packets counter of all calls */
3611             ++(tapinfo->npackets);
3612
3613             /* ?? means we're not quite sure if this is accurate. Since Unistim isn't a true
3614                Call control protocol, we can only guess at the destination by messing with
3615                key buffers. */
3616             if(tmp_unistim_info->key_buffer != NULL) {
3617                 callsinfo->to_identity = g_strdup_printf("?? %s",tmp_unistim_info->key_buffer);
3618             }
3619
3620             /* change sequence number for ACK detection */
3621             tmp_unistim_info->sequence = pi->sequence;
3622
3623             /* State changes too */
3624             callsinfo->call_active_state = VOIP_ACTIVE;
3625             callsinfo->call_state = VOIP_IN_CALL;
3626
3627             /* Add graph data */
3628             frame_label = "STREAM OPENED";
3629             comment = g_strdup_printf("Stream Opened (%d)",pi->sequence);
3630
3631             /* add to the graph */
3632             add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3633
3634         } else if(pi->stream_connect == 1 && callsinfo == NULL) {
3635
3636             /* Research indicates some nortel products initiate stream first
3637              * without keypresses. therefore creating this solely on a keypress is
3638              * ineffective.
3639              * Sometimes calls start immediately with open stream.
3640              */
3641             callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
3642             callsinfo->call_active_state = VOIP_ACTIVE;
3643             callsinfo->call_state = VOIP_CALL_SETUP;
3644             callsinfo->from_identity=g_strdup("UNKNOWN");
3645             callsinfo->to_identity=g_strdup("UNKNOWN");
3646             copy_address(&(callsinfo->initial_speaker),&(pinfo->src));
3647             callsinfo->selected=FALSE;
3648
3649             /* Set this on init of struct so in case the call doesn't complete, we'll have a ref. */
3650             /* Otherwise if the call is completed we'll have the open/close streams to ref actual call duration */
3651             callsinfo->start_fd=pinfo->fd;
3652             callsinfo->start_rel_ts=pinfo->rel_ts;
3653
3654             callsinfo->protocol=VOIP_UNISTIM;
3655             callsinfo->prot_info=g_malloc(sizeof(unistim_info_t));
3656
3657             tmp_unistim_info = (unistim_info_t *)callsinfo->prot_info;
3658
3659             /* Clear tap struct */
3660             tmp_unistim_info->rudp_type = 0;
3661             tmp_unistim_info->payload_type = 0;
3662             tmp_unistim_info->sequence = pi->sequence;
3663             tmp_unistim_info->termid = 0;
3664             tmp_unistim_info->key_val = -1;
3665             tmp_unistim_info->key_state = -1;
3666             tmp_unistim_info->hook_state = -1;
3667             tmp_unistim_info->stream_connect = -1;
3668             tmp_unistim_info->trans_connect = -1;
3669             tmp_unistim_info->set_termid = -1;
3670             tmp_unistim_info->string_data = NULL;
3671             tmp_unistim_info->key_buffer = NULL;
3672
3673             copy_address(&(tmp_unistim_info->it_ip),&(pi->it_ip));
3674             copy_address(&(tmp_unistim_info->ni_ip),&(pi->ni_ip));
3675             tmp_unistim_info->it_port = pi->it_port;
3676
3677             callsinfo->free_prot_info = g_free;
3678             callsinfo->npackets = 0;
3679             callsinfo->call_num = tapinfo->ncalls++;
3680             g_queue_push_tail(tapinfo->callsinfos, callsinfo);
3681
3682             /* Open stream */
3683             /* Each packet COULD BE OUR LAST!!!! */
3684             /* Store frame data which holds time and frame number */
3685             callsinfo->stop_fd = pinfo->fd;
3686             callsinfo->stop_rel_ts = pinfo->rel_ts;
3687             /* Local packets too */
3688             ++(callsinfo->npackets);
3689
3690             /* increment the packets counter of all calls */
3691             ++(tapinfo->npackets);
3692
3693             /* ?? means we're not quite sure if this is accurate. Since Unistim isn't a true
3694                Call control protocol, we can only guess at the destination by messing with
3695                key buffers. */
3696             if(tmp_unistim_info->key_buffer != NULL) {
3697                 callsinfo->to_identity = g_strdup_printf("?? %s",tmp_unistim_info->key_buffer);
3698             }
3699
3700             /* change sequence number for ACK detection */
3701             tmp_unistim_info->sequence = pi->sequence;
3702
3703             /* State changes too */
3704             callsinfo->call_active_state = VOIP_ACTIVE;
3705             callsinfo->call_state = VOIP_IN_CALL;
3706
3707             /* Add graph data */
3708             frame_label = "STREAM OPENED";
3709             comment = g_strdup_printf("Stream Opened (%d)",pi->sequence);
3710
3711             /* add to the graph */
3712             add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3713
3714         } else if(pi->stream_connect == 0 && callsinfo != NULL) {
3715             /* Close Stream */
3716
3717             /* Set stop seconds + usec */
3718             /* frame_data holds the time info */
3719             callsinfo->stop_fd = pinfo->fd;
3720             callsinfo->stop_rel_ts = pinfo->rel_ts;
3721
3722             tmp_unistim_info->sequence = pi->sequence;
3723
3724             if(callsinfo->call_state == VOIP_IN_CALL) {
3725                 callsinfo->call_active_state = VOIP_INACTIVE;
3726                 callsinfo->call_state = VOIP_COMPLETED;
3727             } else {
3728                 callsinfo->call_state = VOIP_UNKNOWN;
3729                 callsinfo->call_active_state = VOIP_INACTIVE;
3730             }
3731
3732             frame_label = "STREAM CLOSED";
3733             comment = g_strdup_printf("Stream Closed (%d)",pi->sequence);
3734
3735             /* add to the graph */
3736             add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3737
3738         } else
3739             comment = NULL;
3740
3741     } else if(pi->rudp_type == 1 && callsinfo != NULL) {
3742         /* ACK */
3743         /* Only show acks for processed seq #s */
3744         if(tmp_unistim_info->sequence == pi->sequence) {
3745
3746             frame_label = "ACK";
3747             comment = g_strdup_printf("ACK for sequence %d",pi->sequence);
3748
3749             /* add to the graph */
3750             add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3751
3752         }
3753
3754     } else if(pi->rudp_type == 0 && callsinfo != NULL) {
3755
3756         /* NAK */
3757         frame_label = "NAK";
3758         comment = g_strdup_printf("NAK for sequence %d",pi->sequence);
3759
3760         /* add to the graph */
3761         add_to_graph(tapinfo, pinfo, edt, frame_label, comment, callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3762
3763     }
3764
3765     /* free data */
3766     g_free(comment);
3767
3768     tapinfo->redraw |= REDRAW_UNISTIM;
3769
3770     return TRUE;
3771 }
3772
3773 /****************************************************************************/
3774 static void
3775 unistim_calls_draw(void *tap_offset_ptr)
3776 {
3777     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_unistim_);
3778
3779     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_UNISTIM)) {
3780         tapinfo->tap_draw(tapinfo);
3781         tapinfo->redraw &= ~REDRAW_UNISTIM;
3782     }
3783 }
3784
3785 /****************************************************************************/
3786 /* TAP INTERFACE */
3787 /****************************************************************************/
3788 void
3789 unistim_calls_init_tap(voip_calls_tapinfo_t *tap_id_base) {
3790
3791     GString *error_string;
3792
3793     error_string = register_tap_listener("unistim", tap_base_to_id(tap_id_base, tap_id_offset_unistim_),
3794             NULL,
3795             0,
3796             NULL,
3797             unistim_calls_packet,
3798             unistim_calls_draw
3799             );
3800
3801     if (error_string != NULL) {
3802         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3803                 "%s", error_string->str);
3804         g_string_free(error_string, TRUE);
3805     }
3806 }
3807
3808 /****************************************************************************/
3809 void
3810 remove_tap_listener_unistim_calls(voip_calls_tapinfo_t *tap_id_base)
3811 {
3812     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_unistim_));
3813 }
3814
3815 /****************************************************************************/
3816 /* ***************************TAP for SKINNY **********************************/
3817 /****************************************************************************/
3818
3819 /* Telecaster to tap-voip call state mapping */
3820 static const voip_call_state skinny_tap_voip_state[] = {
3821     VOIP_NO_STATE,
3822     VOIP_CALL_SETUP,
3823     VOIP_COMPLETED,
3824     VOIP_RINGING,
3825     VOIP_RINGING,
3826     VOIP_IN_CALL,
3827     VOIP_REJECTED,
3828     VOIP_REJECTED,
3829     VOIP_IN_CALL,
3830     VOIP_IN_CALL,
3831     VOIP_COMPLETED,
3832     VOIP_COMPLETED,
3833     VOIP_CALL_SETUP,
3834     VOIP_UNKNOWN,
3835     VOIP_REJECTED
3836 };
3837
3838 static gboolean
3839 skinny_calls_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *skinny_info)
3840 {
3841     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_skinny_);
3842     GList* list;
3843     voip_calls_info_t *callsinfo = NULL;
3844     address* phone;
3845     const skinny_info_t *si = (const skinny_info_t *)skinny_info;
3846     skinny_calls_info_t *tmp_skinnyinfo;
3847     gchar *comment;
3848
3849     if (si == NULL || (si->callId == 0 && si->passThroughPartyId == 0))
3850         return FALSE;
3851     /* check whether we already have this context in the list */
3852     list = g_queue_peek_nth_link(tapinfo->callsinfos, 0);
3853     while (list)
3854     {
3855         voip_calls_info_t* tmp_listinfo = (voip_calls_info_t *)list->data;
3856         if (tmp_listinfo->protocol == VOIP_SKINNY) {
3857             tmp_skinnyinfo = (skinny_calls_info_t *)tmp_listinfo->prot_info;
3858             if (tmp_skinnyinfo->callId == si->callId ||
3859                     tmp_skinnyinfo->callId == si->passThroughPartyId) {
3860                 callsinfo = (voip_calls_info_t*)(list->data);
3861                 break;
3862             }
3863         }
3864         list = g_list_next (list);
3865     }
3866
3867     if (si->messId >= 256)
3868         phone = &(pinfo->dst);
3869     else
3870         phone = &(pinfo->src);
3871
3872     if (callsinfo==NULL) {
3873         callsinfo = (voip_calls_info_t *)g_malloc0(sizeof(voip_calls_info_t));
3874         callsinfo->call_state = VOIP_NO_STATE;
3875         callsinfo->call_active_state = VOIP_ACTIVE;
3876         /* callsinfo->from_identity = g_strdup_printf("%s : %.8x", "Skinny", 1); */
3877         callsinfo->from_identity = g_strdup("");
3878         callsinfo->to_identity = g_strdup("");
3879         callsinfo->prot_info = g_malloc(sizeof(skinny_calls_info_t));
3880         callsinfo->free_prot_info = g_free;
3881         tmp_skinnyinfo = (skinny_calls_info_t *)callsinfo->prot_info;
3882         tmp_skinnyinfo->callId = si->callId ? si->callId : si->passThroughPartyId;
3883         callsinfo->npackets = 1;
3884
3885         copy_address(&(callsinfo->initial_speaker), phone);
3886
3887         callsinfo->protocol = VOIP_SKINNY;
3888         callsinfo->call_num = tapinfo->ncalls++;
3889         callsinfo->start_fd = pinfo->fd;
3890         callsinfo->start_rel_ts = pinfo->rel_ts;
3891         callsinfo->stop_fd = pinfo->fd;
3892         callsinfo->stop_rel_ts = pinfo->rel_ts;
3893
3894         callsinfo->selected = FALSE;
3895         g_queue_push_tail(tapinfo->callsinfos, callsinfo);
3896     } else {
3897         if (si->callingParty) {
3898             g_free(callsinfo->from_identity);
3899             callsinfo->from_identity = g_strdup(si->callingParty);
3900         }
3901         if (si->calledParty) {
3902             g_free(callsinfo->to_identity);
3903             callsinfo->to_identity =  g_strdup(si->calledParty);
3904         }
3905         if ((si->callState > 0) && (si->callState < (sizeof(skinny_tap_voip_state)/sizeof(skinny_tap_voip_state[0]))))
3906             callsinfo->call_state = skinny_tap_voip_state[si->callState];
3907
3908         callsinfo->stop_fd = pinfo->fd;
3909         callsinfo->stop_rel_ts = pinfo->rel_ts;
3910         ++(callsinfo->npackets);
3911     }
3912
3913     if (si->callId) {
3914         if (si->passThroughPartyId)
3915             comment = g_strdup_printf("CallId = %u, PTId = %u", si->callId, si->passThroughPartyId);
3916         else
3917             comment = g_strdup_printf("CallId = %u, LineId = %u", si->callId, si->lineId);
3918     } else {
3919         if (si->passThroughPartyId)
3920             comment = g_strdup_printf("PTId = %u", si->passThroughPartyId);
3921         else
3922             comment = NULL;
3923     }
3924
3925     add_to_graph(tapinfo, pinfo, edt, si->messageName, comment,
3926             callsinfo->call_num, &(pinfo->src), &(pinfo->dst), 1);
3927     g_free(comment);
3928
3929     tapinfo->redraw |= REDRAW_SKINNY;
3930
3931     return TRUE;
3932 }
3933
3934 /****************************************************************************/
3935 static void
3936 skinny_calls_draw(void *tap_offset_ptr)
3937 {
3938     voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_skinny_);
3939
3940     if (tapinfo->tap_draw && (tapinfo->redraw & REDRAW_SKINNY)) {
3941         tapinfo->tap_draw(tapinfo);
3942         tapinfo->redraw &= ~REDRAW_SKINNY;
3943     }
3944 }
3945
3946 /****************************************************************************/
3947 /* TAP INTERFACE */
3948 /****************************************************************************/
3949 void
3950 skinny_calls_init_tap(voip_calls_tapinfo_t *tap_id_base)
3951 {
3952     GString *error_string;
3953
3954     /*
3955      * We set TL_REQUIRES_PROTO_TREE to force a non-null "tree"
3956      * in the SKINNY dissector; otherwise, the dissector
3957      * doesn't fill in the info passed to the tap's packet
3958      * routine.
3959      */
3960     error_string = register_tap_listener("skinny",
3961             tap_base_to_id(tap_id_base, tap_id_offset_skinny_),
3962             NULL,
3963             TL_REQUIRES_PROTO_TREE,
3964             NULL,
3965             skinny_calls_packet,
3966             skinny_calls_draw
3967             );
3968     if (error_string != NULL) {
3969         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3970                 "%s", error_string->str);
3971         g_string_free(error_string, TRUE);
3972     }
3973 }
3974
3975 /****************************************************************************/
3976 void
3977 remove_tap_listener_skinny_calls(voip_calls_tapinfo_t *tap_id_base)
3978 {
3979     remove_tap_listener(tap_base_to_id(tap_id_base, tap_id_offset_skinny_));
3980 }
3981
3982 /****************************************************************************/
3983 /* ***************************TAP for IAX2 **********************************/
3984 /****************************************************************************/
3985
3986 static void free_iax2_info(gpointer p) {
3987     iax2_info_t *ii = (iax2_info_t *)p;
3988
3989     g_free(ii);
3990 }
3991
3992
3993 /****************************************************************************/
3994 /* whenever a IAX2 packet is seen by the tap listener */
3995 static gboolean
3996 iax2_calls_packet( void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *iax2_info)
3997 {
3998     voip_calls_tapinfo_t *tapinfo   = tap_id_to_base(tap_offset_ptr, tap_id_offset_iax2_);
3999     GList*                list;
4000     voip_calls_info_t    *callsinfo = NULL;
4001     address              *phone;
4002     const iax2_info_t    *ii        = (const iax2_info_t *)iax2_info;
4003     iax2_info_t          *tmp_iax2info;
4004
4005     if (ii == NULL || ii->ptype != IAX2_FULL_PACKET || (ii->scallno == 0 && ii->dcallno == 0))
4006        &nbs