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