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