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