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