2 * VoIP calls summary addition for Wireshark
4 * Copyright 2004, Ericsson, Spain
5 * By Francisco Alcoba <francisco.alcoba@ericsson.com>
7 * based on h323_calls.c
8 * Copyright 2004, Iskratel, Ltd, Kranj
9 * By Miha Jemec <m.jemec@iskratel.si>
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.
15 * Wireshark - Network traffic analyzer
16 * By Gerald Combs <gerald@wireshark.org>
17 * Copyright 1998 Gerald Combs
19 * SPDX-License-Identifier: GPL-2.0-or-later
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"
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"
57 #include "wsutil/glib-compat.h"
58 #include <wsutil/ws_assert.h>
60 #define DUMP_PTR1(p) printf("#=> %p\n",(void *)p)
61 #define DUMP_PTR2(p) printf("==> %p\n",(void *)p)
63 const char *voip_call_state_name
[8]={
74 /* defines whether we can consider the call active */
75 const char *voip_protocol_name
[]={
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
99 tap_id_offset_actrace_
,
101 tap_id_offset_h245dg_
,
106 tap_id_offset_megaco_
,
111 tap_id_offset_rtp_event_
,
115 tap_id_offset_skinny_
,
118 tap_id_offset_unistim_
,
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_)
145 tap_base_to_id(voip_calls_tapinfo_t
* tap_base
, int offset
) {
146 return GSIZE_TO_POINTER(GPOINTER_TO_SIZE(tap_base
) + offset
);
149 static inline voip_calls_tapinfo_t
*
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
);
161 typedef struct _h245_labels
{
164 graph_str labels
[H245_MAX
];
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
);
187 voip_calls_init_all_taps(voip_calls_tapinfo_t
*tap_id_base
)
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
);
209 if (find_tap_id("voip")) {
210 voip_calls_init_tap(tap_id_base
);
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
);
233 void voip_calls_remove_all_tap_listeners(voip_calls_tapinfo_t
*tap_id_base
)
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
);
255 if (find_tap_id("voip")) {
256 remove_tap_listener_voip_calls(tap_id_base
);
260 /****************************************************************************/
261 /* when there is a [re]reading of packet's */
263 voip_calls_reset_all_taps(voip_calls_tapinfo_t
*tapinfo
)
265 voip_calls_info_t
*callsinfo
;
266 rtpstream_info_t
*strinfo
;
269 /* VOIP_CALLS_DEBUG("reset packets: %d streams: %d", tapinfo->npackets, tapinfo->nrtpstreams); */
271 /* free the data items first */
272 list
= g_queue_peek_nth_link(tapinfo
->callsinfos
, 0);
275 callsinfo
= (voip_calls_info_t
*)list
->data
;
276 voip_calls_free_callsinfo(callsinfo
);
277 list
= g_list_next(list
);
279 g_queue_clear(tapinfo
->callsinfos
);
280 /* free the SIP_HASH */
281 if(NULL
!=tapinfo
->callsinfo_hashtable
[SIP_HASH
])
283 g_hash_table_destroy(tapinfo
->callsinfo_hashtable
[SIP_HASH
]);
284 tapinfo
->callsinfo_hashtable
[SIP_HASH
] = NULL
;
287 /* free the strinfo data items first */
288 list
= g_list_first(tapinfo
->rtpstream_list
);
291 strinfo
= (rtpstream_info_t
*)list
->data
;
292 rtpstream_info_free_all(strinfo
);
293 list
= g_list_next(list
);
295 g_list_free(tapinfo
->rtpstream_list
);
296 tapinfo
->rtpstream_list
= NULL
;
298 g_free(tapinfo
->sdp_summary
);
299 tapinfo
->sdp_summary
= NULL
;
301 if (tapinfo
->h245_labels
) {
302 memset(tapinfo
->h245_labels
, 0, sizeof(h245_labels_t
));
306 tapinfo
->start_packets
= 0;
307 tapinfo
->completed_calls
= 0;
308 tapinfo
->rejected_calls
= 0;
313 /****************************************************************************/
314 /* free one callsinfo */
316 voip_calls_free_callsinfo(voip_calls_info_t
*callsinfo
)
318 g_free(callsinfo
->call_id
);
319 g_free(callsinfo
->from_identity
);
320 g_free(callsinfo
->to_identity
);
321 free_address(&callsinfo
->initial_speaker
);
322 g_free(callsinfo
->protocol_name
);
323 g_free(callsinfo
->call_comment
);
325 if (callsinfo
->free_prot_info
&& callsinfo
->prot_info
)
326 callsinfo
->free_prot_info(callsinfo
->prot_info
);
331 /****************************************************************************/
332 /* Add a new item into the graph */
334 add_to_graph(voip_calls_tapinfo_t
*tapinfo
, packet_info
*pinfo
, epan_dissect_t
*edt
, const char *frame_label
, const char *comment
, uint16_t call_num
, address
*src_addr
, address
*dst_addr
, uint16_t line_style
)
336 seq_analysis_item_t
*gai
;
337 char time_str
[COL_MAX_LEN
];
339 if (!tapinfo
->graph_analysis
) {
343 gai
= g_new0(seq_analysis_item_t
, 1);
344 gai
->frame_number
= pinfo
->num
;
345 copy_address(&(gai
->src_addr
),src_addr
);
346 copy_address(&(gai
->dst_addr
),dst_addr
);
348 gai
->port_src
=pinfo
->srcport
;
349 gai
->port_dst
=pinfo
->destport
;
351 if (frame_label
!= NULL
)
352 gai
->frame_label
= g_strdup(frame_label
);
354 gai
->frame_label
= g_strdup("");
357 gai
->comment
= g_strdup(comment
);
359 gai
->comment
= g_strdup("");
361 gai
->conv_num
=call_num
;
362 gai
->line_style
=line_style
;
363 set_fd_time(edt
->session
, pinfo
->fd
, time_str
);
364 gai
->time_str
= g_strdup(time_str
);
367 g_queue_push_tail(tapinfo
->graph_analysis
->items
, gai
);
368 g_hash_table_insert(tapinfo
->graph_analysis
->ht
, GUINT_TO_POINTER(gai
->frame_number
), gai
);
371 /****************************************************************************/
372 /* Append str to frame_label and comment in a graph item */
373 /* return 0 if the frame_num is not in the graph list */
374 static int append_to_frame_graph(voip_calls_tapinfo_t
*tapinfo
, uint32_t frame_num
, const char *new_frame_label
, const char *new_comment
)
376 seq_analysis_item_t
*gai
=NULL
;
377 char *frame_label
= NULL
;
378 char *comment
= NULL
;
380 if(tapinfo
->graph_analysis
&& NULL
!=tapinfo
->graph_analysis
->ht
)
381 gai
=(seq_analysis_item_t
*)g_hash_table_lookup(tapinfo
->graph_analysis
->ht
, GUINT_TO_POINTER(frame_num
));
383 frame_label
= gai
->frame_label
;
384 comment
= gai
->comment
;
386 if (new_frame_label
!= NULL
) {
387 gai
->frame_label
= ws_strdup_printf("%s %s", frame_label
, new_frame_label
);
391 if (new_comment
!= NULL
) {
392 gai
->comment
= ws_strdup_printf("%s %s", comment
, new_comment
);
400 /****************************************************************************/
401 /* Change the frame_label and comment in a graph item if not NULL*/
402 /* return 0 if the frame_num is not in the graph list */
403 static int change_frame_graph(voip_calls_tapinfo_t
*tapinfo
, uint32_t frame_num
, const char *new_frame_label
, const char *new_comment
)
405 seq_analysis_item_t
*gai
=NULL
;
406 char *frame_label
= NULL
;
407 char *comment
= NULL
;
409 if(tapinfo
->graph_analysis
&& NULL
!=tapinfo
->graph_analysis
->ht
)
410 gai
=(seq_analysis_item_t
*)g_hash_table_lookup(tapinfo
->graph_analysis
->ht
, GUINT_TO_POINTER(frame_num
));
412 frame_label
= gai
->frame_label
;
413 comment
= gai
->comment
;
415 if (new_frame_label
!= NULL
) {
416 gai
->frame_label
= g_strdup(new_frame_label
);
420 if (new_comment
!= NULL
) {
421 gai
->comment
= g_strdup(new_comment
);
429 /****************************************************************************/
430 /* Change all the graph items with call_num to new_call_num */
431 static unsigned change_call_num_graph(voip_calls_tapinfo_t
*tapinfo
, uint16_t call_num
, uint16_t new_call_num
)
433 seq_analysis_item_t
*gai
;
435 unsigned items_changed
;
438 if(tapinfo
->graph_analysis
){
439 list
= g_queue_peek_nth_link(tapinfo
->graph_analysis
->items
, 0);
442 gai
= (seq_analysis_item_t
*)list
->data
;
443 if (gai
->conv_num
== call_num
) {
444 gai
->conv_num
= new_call_num
;
447 list
= g_list_next(list
);
450 return items_changed
;
453 /****************************************************************************/
454 /* Insert the item in the graph list */
455 static void insert_to_graph_t38(voip_calls_tapinfo_t
*tapinfo
, packet_info
*pinfo
, epan_dissect_t
*edt
, const char *frame_label
, const char *comment
, uint16_t call_num
, address
*src_addr
, address
*dst_addr
, uint16_t line_style
, uint32_t frame_num
)
457 seq_analysis_item_t
*gai
, *new_gai
;
460 char time_str
[COL_MAX_LEN
];
462 if (!tapinfo
->graph_analysis
){
467 new_gai
= g_new0(seq_analysis_item_t
, 1);
468 new_gai
->frame_number
= frame_num
;
469 copy_address(&(new_gai
->src_addr
),src_addr
);
470 copy_address(&(new_gai
->dst_addr
),dst_addr
);
472 new_gai
->port_src
=pinfo
->srcport
;
473 new_gai
->port_dst
=pinfo
->destport
;
474 if (frame_label
!= NULL
)
475 new_gai
->frame_label
= g_strdup(frame_label
);
477 new_gai
->frame_label
= g_strdup("");
480 new_gai
->comment
= g_strdup(comment
);
482 new_gai
->comment
= g_strdup("");
483 new_gai
->conv_num
=call_num
;
484 new_gai
->line_style
=line_style
;
485 set_fd_time(edt
->session
, pinfo
->fd
, time_str
);
486 new_gai
->time_str
= g_strdup(time_str
);
487 new_gai
->display
=false;
491 list
= g_queue_peek_nth_link(tapinfo
->graph_analysis
->items
, 0);
494 gai
= (seq_analysis_item_t
*)list
->data
;
495 if (gai
->frame_number
> frame_num
) {
496 g_queue_insert_before(tapinfo
->graph_analysis
->items
, list
, new_gai
);
497 g_hash_table_insert(tapinfo
->graph_analysis
->ht
, GUINT_TO_POINTER(new_gai
->frame_number
), new_gai
);
501 list
= g_list_next(list
);
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
);
511 /****************************************************************************/
512 /* ***************************TAP for RTP Events*****************************/
513 /****************************************************************************/
515 /*static uint32_t rtp_evt_setup_frame_num = 0;*/
517 /****************************************************************************/
518 /* whenever a rtp event packet is seen by the tap listener */
519 static tap_packet_status
520 rtp_event_packet(void *tap_offset_ptr
, packet_info
*pinfo
, epan_dissect_t
*edt _U_
, const void *rtp_event_info
, tap_flags_t flags _U_
)
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
;
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
;
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
;
534 tapinfo
->rtp_evt_frame_num
= pinfo
->num
;
535 tapinfo
->rtp_evt
= pi
->info_rtp_evt
;
536 tapinfo
->rtp_evt_end
= pi
->info_end
;
538 return TAP_PACKET_DONT_REDRAW
;
541 /****************************************************************************/
543 rtp_event_init_tap(voip_calls_tapinfo_t
*tap_id_base
)
545 GString
*error_string
;
547 error_string
= register_tap_listener("rtpevent", tap_base_to_id(tap_id_base
, tap_id_offset_rtp_event_
),
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
);
563 /****************************************************************************/
566 remove_tap_listener_rtp_event(voip_calls_tapinfo_t
*tap_id_base
)
568 remove_tap_listener(tap_base_to_id(tap_id_base
, tap_id_offset_rtp_event_
));
571 /****************************************************************************/
572 /* ***************************TAP for RTP **********************************/
573 /****************************************************************************/
575 /****************************************************************************/
576 /* when there is a [re]reading of RTP packets */
578 rtp_reset(void *tap_offset_ptr
)
580 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_rtp_
);
582 rtpstream_info_t
*stream_info
;
584 /* free the data items first */
585 list
= g_list_first(tapinfo
->rtpstream_list
);
588 stream_info
= (rtpstream_info_t
*)(list
->data
);
589 rtpstream_info_free_data(stream_info
);
591 list
= g_list_next(list
);
593 g_list_free(tapinfo
->rtpstream_list
);
594 tapinfo
->rtpstream_list
= NULL
;
595 tapinfo
->nrtpstreams
= 0;
597 // Do not touch graph_analysis, it is handled by caller
599 if (tapinfo
->tap_reset
) {
600 tapinfo
->tap_reset(tapinfo
);
606 /****************************************************************************/
607 /* whenever a RTP packet is seen by the tap listener */
608 static tap_packet_status
609 rtp_packet(void *tap_offset_ptr
, packet_info
*pinfo
, epan_dissect_t
*edt
, void const *rtp_info_ptr
, tap_flags_t flags
)
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
;
615 struct _rtp_packet_info
*p_packet_data
= NULL
;
617 const struct _rtp_info
*rtp_info
= (const struct _rtp_info
*)rtp_info_ptr
;
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
;
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
;
629 if (tapinfo
->tap_packet
) {
630 tapinfo
->tap_packet(tapinfo
, pinfo
, edt
, rtp_info_ptr
, flags
);
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
);
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
) )
650 /* if ed137_info has changed, create new stream */
651 tmp_listinfo
->end_stream
= true;
653 strinfo
= (rtpstream_info_t
*)(list
->data
);
657 list
= g_list_next(list
);
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
;
665 /* not in the list? then create a new entry */
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_packet_data
= (struct _rtp_packet_info
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_get_id_by_filter_name("rtp"), RTP_CONVERSATION_PROTO_DATA
);
676 if (p_packet_data
&& p_packet_data
->rtp_dyn_payload
) {
677 const char *encoding_name
= rtp_dyn_payload_get_name(p_packet_data
->rtp_dyn_payload
, strinfo
->first_payload_type
);
679 strinfo
->first_payload_type_name
= encoding_name
;
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");
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
;
695 strinfo
->ed137_info
= NULL
;
697 tapinfo
->rtpstream_list
= g_list_prepend(tapinfo
->rtpstream_list
, strinfo
);
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
;
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;
713 tapinfo
->redraw
|= REDRAW_RTP
;
715 return TAP_PACKET_DONT_REDRAW
;
718 /****************************************************************************/
719 /* whenever a redraw in the RTP tap listener */
721 rtp_draw(void *tap_offset_ptr
)
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
;
731 char time_str
[COL_MAX_LEN
];
733 /* add each rtp stream to the graph */
734 rtpstreams_list
= g_list_first(tapinfo
->rtpstream_list
);
735 while (rtpstreams_list
)
737 rtp_listinfo
= (rtpstream_info_t
*)rtpstreams_list
->data
;
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
));
745 const char *comment_fmt_src
= "%%s, %%u packets. Duration: %%.%dfs SSRC: 0x%%X";
746 char *comment_fmt
= ws_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
));
752 duration
= (double)(nstime_to_msec(&rtp_listinfo
->stop_rel_time
) - nstime_to_msec(&rtp_listinfo
->start_rel_time
));
753 g_free(gai
->comment
);
754 gai
->comment
= ws_strdup_printf(comment_fmt
,
755 (rtp_listinfo
->is_srtp
)?"SRTP":"RTP", rtp_listinfo
->packet_count
,
756 duration
/1000, rtp_listinfo
->id
.ssrc
);
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
= (double)(nstime_to_msec(&rtp_listinfo
->stop_rel_time
) - nstime_to_msec(&rtp_listinfo
->start_rel_time
));
765 new_gai
->frame_label
= ws_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
:"")
773 new_gai
->comment
= ws_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
);
797 rtpstreams_list
= g_list_next(rtpstreams_list
);
798 } /* while (rtpstreams_list) */
800 if (tapinfo
->tap_draw
&& (tapinfo
->redraw
& REDRAW_RTP
)) {
801 tapinfo
->tap_draw(tapinfo
);
802 tapinfo
->redraw
&= ~REDRAW_RTP
;
807 rtp_packet_draw(void *tap_offset_ptr
)
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
;
814 seq_analysis_item_t
*gai
;
815 seq_analysis_item_t
*new_gai
;
818 char time_str
[COL_MAX_LEN
];
820 /* add each rtp stream to the graph */
821 rtpstreams_list
= g_list_first(tapinfo
->stream_list
);
822 while (rtpstreams_list
)
824 rtp_listinfo
= rtpstreams_list
->data
;
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
)
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
);
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
= (uint32_t)(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
= ws_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
);
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
++;
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
= (uint32_t)(nstime_to_msec(&rtp_listinfo
->stop_fd
->rel_ts
) - nstime_to_msec(&rtp_listinfo
->start_fd
->rel_ts
));
863 new_gai
->frame_label
= ws_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
= ws_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
);
879 if (voip_calls_graph_list
) item
++;
883 voip_calls_graph_list
= g_list_next(voip_calls_graph_list
);
885 rtpstreams_list
= g_list_next(rtpstreams_list
);
890 /****************************************************************************/
892 rtp_init_tap(voip_calls_tapinfo_t
*tap_id_base
)
894 GString
*error_string
;
896 error_string
= register_tap_listener("rtp", tap_base_to_id(tap_id_base
, tap_id_offset_rtp_
), NULL
,
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
);
910 /****************************************************************************/
912 remove_tap_listener_rtp(voip_calls_tapinfo_t
*tap_id_base
)
914 remove_tap_listener(tap_base_to_id(tap_id_base
, tap_id_offset_rtp_
));
917 /****************************************************************************/
918 /******************************TAP for T38 **********************************/
919 /****************************************************************************/
921 /****************************************************************************/
922 /* whenever a T38 packet is seen by the tap listener */
923 static tap_packet_status
924 t38_packet(void *tap_offset_ptr
, packet_info
*pinfo
, epan_dissect_t
*edt
, const void *t38_info_ptr
, tap_flags_t flags _U_
)
926 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_t38_
);
928 voip_calls_info_t
*callsinfo
= NULL
;
929 voip_calls_info_t
*tmp_listinfo
;
930 GList
*voip_calls_graph_list
= NULL
;
932 char *frame_label
= NULL
;
933 char *comment
= NULL
;
934 seq_analysis_item_t
*tmp_gai
, *gai
= NULL
;
935 char *tmp_str1
, *tmp_str2
;
936 uint16_t line_style
= 2;
940 const t38_packet_info
*t38_info
= (const t38_packet_info
*)t38_info_ptr
;
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
;
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);
952 while (voip_calls_graph_list
)
954 tmp_gai
= (seq_analysis_item_t
*)voip_calls_graph_list
->data
;
955 if (t38_info
->setup_frame_number
== tmp_gai
->frame_number
) {
959 voip_calls_graph_list
= g_list_next(voip_calls_graph_list
);
961 if (gai
) conv_num
= (int) gai
->conv_num
;
964 /* if setup_frame_number in the t38 packet is 0, it means it was not set using an SDP or H245 session, which means we don't
965 * have the associated Voip calls. It probably means that 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.
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);
974 tmp_listinfo
=(voip_calls_info_t
*)list
->data
;
975 if (tmp_listinfo
->protocol
== MEDIA_T38
) {
976 callsinfo
= (voip_calls_info_t
*)(list
->data
);
979 list
= g_list_next (list
);
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
);
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
);
1005 conv_num
= (int) callsinfo
->call_num
;
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
;
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
= ws_strdup_printf("t38:t30 Ind:%s", tmp_str1
);
1018 wmem_free(NULL
, tmp_str1
);
1020 } else if (t38_info
->type_msg
== 1) { /* 1=data */
1021 switch(t38_info
->Data_Field_field_type_value
) {
1022 case 0: /* hdlc-data */
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
,
1029 frame_label
= ws_strdup_printf("%s %s",
1032 wmem_free(NULL
, tmp_str1
);
1034 tmp_str1
= val_to_str_ext_wmem(NULL
, t38_info
->t30_Facsimile_Control
& 0x7F,
1035 &t30_facsimile_control_field_vals_ext
,
1037 tmp_str2
= val_to_str_wmem(NULL
, t38_info
->data_value
,
1040 comment
= ws_strdup_printf("t38:%s:HDLC:%s", tmp_str2
, tmp_str1
);
1041 wmem_free(NULL
, tmp_str1
);
1042 wmem_free(NULL
, tmp_str2
);
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
= ws_strdup_printf("WARNING: received t38:%s:HDLC:%s",
1050 t38_info
->Data_Field_field_type_value
== 3 ? "fcs-BAD" : "fcs-BAD-sig-end");
1051 wmem_free(NULL
, tmp_str1
);
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
= ws_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
= ws_strdup_printf(comment_fmt_src
, prefs
.gui_decimal_places1
);
1059 comment
= ws_strdup_printf(comment_fmt
,
1060 tmp_str1
, duration
, t38_info
->desc_comment
);
1061 insert_to_graph_t38(tapinfo
, pinfo
, edt
, frame_label
, comment
,
1062 (uint16_t)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
);
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
, (uint16_t)conv_num
, &(pinfo
->src
), &(pinfo
->dst
), line_style
);
1075 g_free(frame_label
);
1077 tapinfo
->redraw
|= REDRAW_T38
;
1079 return TAP_PACKET_REDRAW
; /* refresh output */
1082 /****************************************************************************/
1084 t38_draw(void *tap_offset_ptr
)
1086 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_t38_
);
1088 if (tapinfo
->tap_draw
&& (tapinfo
->redraw
& REDRAW_T38
)) {
1089 tapinfo
->tap_draw(tapinfo
);
1090 tapinfo
->redraw
&= ~REDRAW_T38
;
1094 /****************************************************************************/
1096 t38_init_tap(voip_calls_tapinfo_t
*tap_id_base
)
1098 GString
*error_string
;
1100 error_string
= register_tap_listener("t38", tap_base_to_id(tap_id_base
, tap_id_offset_t38_
), NULL
,
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
);
1114 /****************************************************************************/
1116 remove_tap_listener_t38(voip_calls_tapinfo_t
*tap_id_base
)
1118 remove_tap_listener(tap_base_to_id(tap_id_base
, tap_id_offset_t38_
));
1122 /****************************************************************************/
1123 /* ***************************TAP for SIP **********************************/
1124 /****************************************************************************/
1127 free_sip_info(void *p
) {
1128 sip_calls_info_t
*si
= (sip_calls_info_t
*)p
;
1130 g_free(si
->call_identifier
);
1134 /****************************************************************************/
1135 /* whenever a SIP packet is seen by the tap listener */
1136 static tap_packet_status
1137 sip_calls_packet(void *tap_offset_ptr
, packet_info
*pinfo
, epan_dissect_t
*edt
, const void *SIPinfo
, tap_flags_t flags _U_
)
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 */
1143 voip_calls_info_t
*callsinfo
= NULL
;
1144 sip_calls_info_t
*tmp_sipinfo
= NULL
;
1145 address tmp_src
, tmp_dst
;
1146 char *frame_label
= NULL
;
1147 char *comment
= NULL
;
1148 char *old_comment
= NULL
;
1151 const sip_info_value_t
*pi
= (const sip_info_value_t
*)SIPinfo
;
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
;
1158 tapinfo
->sip_frame_num
= pinfo
->num
;
1160 /* do not consider packets without call_id */
1161 if (pi
->tap_call_id
==NULL
) {
1162 return TAP_PACKET_DONT_REDRAW
;
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
,
1170 NULL
, /* key_destroy_func */
1171 NULL
);/* value_destroy_func */
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
);
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. */
1180 if ((callsinfo
==NULL
) && (pi
->request_method
!=NULL
)) {
1182 /* check VoIPcalls_get_flow_show_option() == FLOW_ALL or FLOW_ONLY_INVITES */
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
++;
1206 /* show method in comment in conversation list dialog, user can discern different conversation types */
1207 callsinfo
->call_comment
=g_strdup(pi
->request_method
);
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
);
1216 if (callsinfo
!= NULL
) {
1217 tmp_sipinfo
= (sip_calls_info_t
*)callsinfo
->prot_info
;
1219 /* let's analyze the call state */
1221 copy_address(&(tmp_src
), &(pinfo
->src
));
1222 copy_address(&(tmp_dst
), &(pinfo
->dst
));
1224 if (pi
->request_method
== NULL
) {
1225 frame_label
= ws_strdup_printf("%u %s", pi
->response_code
, pi
->reason_phrase
);
1226 comment
= ws_strdup_printf("SIP Status %u %s", pi
->response_code
, pi
->reason_phrase
);
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
;
1232 else if ((pi
->response_code
>299)&&(tmp_sipinfo
->sip_state
== SIP_INVITE_SENT
)) {
1233 callsinfo
->call_state
= VOIP_REJECTED
;
1234 tapinfo
->rejected_calls
++;
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
=ws_strdup_printf("%s %u",
1243 callsinfo
->call_comment
,
1244 pi
->response_code
/*, pi->reason_phrase*/);
1246 g_free(old_comment
);
1253 frame_label
= g_strdup(pi
->request_method
);
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
= ws_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
);
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
= ws_strdup_printf("SIP Request INVITE ACK 200 CSeq:%d", pi
->tap_cseq_number
);
1269 else if (strcmp(pi
->request_method
,"BYE")==0) {
1270 callsinfo
->call_state
= VOIP_COMPLETED
;
1271 tapinfo
->completed_calls
++;
1272 comment
= ws_strdup_printf("SIP Request BYE CSeq:%d", pi
->tap_cseq_number
);
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
= ws_strdup_printf("SIP Request CANCEL CSeq:%d", pi
->tap_cseq_number
);
1280 /* comment = ws_strdup_printf("SIP %s", pi->request_method); */
1281 comment
= ws_strdup_printf("SIP %s From: %s To:%s CSeq:%d",
1283 callsinfo
->from_identity
,
1284 callsinfo
->to_identity
, pi
->tap_cseq_number
);
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
);
1294 /* add to the graph */
1295 add_to_graph(tapinfo
, pinfo
, edt
, frame_label
, comment
, callsinfo
->call_num
, &(pinfo
->src
), &(pinfo
->dst
), 1);
1297 g_free(frame_label
);
1298 free_address(&tmp_src
);
1299 free_address(&tmp_dst
);
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
;
1310 tapinfo
->redraw
|= REDRAW_SIP
;
1312 return TAP_PACKET_REDRAW
; /* refresh output */
1315 /****************************************************************************/
1317 sip_calls_draw(void *tap_offset_ptr
)
1319 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_sip_
);
1321 if (tapinfo
->tap_draw
&& (tapinfo
->redraw
& REDRAW_SIP
)) {
1322 tapinfo
->tap_draw(tapinfo
);
1323 tapinfo
->redraw
&= ~REDRAW_SIP
;
1327 /****************************************************************************/
1329 /****************************************************************************/
1332 sip_calls_init_tap(voip_calls_tapinfo_t
*tap_id_base
)
1334 GString
*error_string
;
1336 error_string
= register_tap_listener("sip", tap_base_to_id(tap_id_base
, tap_id_offset_sip_
), NULL
,
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
);
1350 /****************************************************************************/
1352 remove_tap_listener_sip_calls(voip_calls_tapinfo_t
*tap_id_base
)
1354 remove_tap_listener(tap_base_to_id(tap_id_base
, tap_id_offset_sip_
));
1357 /****************************************************************************/
1358 /* ***************************TAP for ISUP **********************************/
1359 /****************************************************************************/
1361 /****************************************************************************/
1362 /* whenever a isup_ packet is seen by the tap listener */
1363 static tap_packet_status
1364 isup_calls_packet(void *tap_offset_ptr
, packet_info
*pinfo
, epan_dissect_t
*edt
, const void *isup_info
, tap_flags_t flags _U_
)
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
;
1371 bool forward
= false;
1374 char *frame_label
= NULL
;
1375 char *comment
= NULL
;
1377 const isup_tap_rec_t
*pi
= (const isup_tap_rec_t
*)isup_info
;
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
;
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
;
1388 /* check whether we already have a call with these parameters in the list */
1389 list
= g_queue_peek_nth_link(tapinfo
->callsinfos
, 0);
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
)) {
1399 } else if ((tmp_isupinfo
->dpc
== tapinfo
->mtp3_opc
)&&(tmp_isupinfo
->opc
== tapinfo
->mtp3_dpc
)) {
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
) {
1410 } else if (pi
->message_type
!= 1) {
1413 tmp_listinfo
->call_active_state
=VOIP_INACTIVE
;
1418 callsinfo
= (voip_calls_info_t
*)(list
->data
);
1423 list
= g_list_next (list
);
1426 /* not in the list? then create a new entry if the message is IAM
1427 -i.e. if this session is a call*/
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
);
1452 if (callsinfo
!=NULL
) {
1453 callsinfo
->stop_fd
= pinfo
->fd
;
1454 callsinfo
->stop_rel_ts
= pinfo
->rel_ts
;
1455 ++(callsinfo
->npackets
);
1457 /* Let's analyze the call state */
1459 frame_label
= g_strdup(val_to_str_ext_const(pi
->message_type
, &isup_message_type_value_acro_ext
, "Unknown"));
1461 if (callsinfo
->npackets
== 1) { /* this is the first packet, that must be an IAM */
1463 if ((pi
->calling_number
!=NULL
)&&(pi
->called_number
!=NULL
)) {
1464 comment
= ws_strdup_printf("Call from %s to %s",
1465 pi
->calling_number
, pi
->called_number
);
1467 } else if (callsinfo
->npackets
== 2) { /* in the second packet we show the SPs */
1469 comment
= ws_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
);
1473 comment
= ws_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
);
1479 switch(pi
->message_type
) {
1481 callsinfo
->call_state
=VOIP_CALL_SETUP
;
1483 case 7: /* CONNECT */
1484 case 9: /* ANSWER */
1485 callsinfo
->call_state
=VOIP_IN_CALL
;
1487 case 12: /* RELEASE */
1488 if (callsinfo
->call_state
==VOIP_CALL_SETUP
) {
1490 callsinfo
->call_state
=VOIP_CANCELLED
;
1493 callsinfo
->call_state
=VOIP_REJECTED
;
1494 tapinfo
->rejected_calls
++;
1497 else if (callsinfo
->call_state
== VOIP_IN_CALL
) {
1498 callsinfo
->call_state
= VOIP_COMPLETED
;
1499 tapinfo
->completed_calls
++;
1501 /* Overwrite any comment set above */
1503 comment
= ws_strdup_printf("Cause %i - %s",
1505 val_to_str_ext_const(pi
->cause_value
, &q931_cause_code_vals_ext
, "(Unknown)"));
1509 /* increment the packets counter of all calls */
1510 ++(tapinfo
->npackets
);
1512 /* add to the graph */
1513 add_to_graph(tapinfo
, pinfo
, edt
, frame_label
, comment
, callsinfo
->call_num
, &(pinfo
->src
), &(pinfo
->dst
), 1);
1515 g_free(frame_label
);
1518 tapinfo
->redraw
|= REDRAW_ISUP
;
1520 return TAP_PACKET_REDRAW
; /* refresh output */
1523 /****************************************************************************/
1525 isup_calls_draw(void *tap_offset_ptr
)
1527 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_isup_
);
1529 if (tapinfo
->tap_draw
&& (tapinfo
->redraw
& REDRAW_ISUP
)) {
1530 tapinfo
->tap_draw(tapinfo
);
1531 tapinfo
->redraw
&= ~REDRAW_ISUP
;
1535 /****************************************************************************/
1538 isup_calls_init_tap(voip_calls_tapinfo_t
*tap_id_base
)
1540 GString
*error_string
;
1542 error_string
= register_tap_listener("isup", tap_base_to_id(tap_id_base
, tap_id_offset_isup_
),
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
);
1558 /****************************************************************************/
1561 remove_tap_listener_isup_calls(voip_calls_tapinfo_t
*tap_id_base
)
1563 remove_tap_listener(tap_base_to_id(tap_id_base
, tap_id_offset_isup_
));
1566 /****************************************************************************/
1567 /* ***************************TAP for MTP3 **********************************/
1568 /****************************************************************************/
1571 /****************************************************************************/
1572 /* whenever a mtp3_ packet is seen by the tap listener */
1573 static tap_packet_status
1574 mtp3_calls_packet(void *tap_offset_ptr
, packet_info
*pinfo
, epan_dissect_t
*edt _U_
, const void *mtp3_info
, tap_flags_t flags _U_
)
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
;
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
;
1584 /* keep the data in memory to use when the ISUP information arrives */
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
;
1591 return TAP_PACKET_DONT_REDRAW
;
1594 static tap_packet_status
1595 m3ua_calls_packet(void *tap_offset_ptr
, packet_info
*pinfo
, epan_dissect_t
*edt _U_
, const void *mtp3_info
, tap_flags_t flags _U_
)
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
;
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
;
1605 /* keep the data in memory to use when the ISUP information arrives */
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
;
1612 return TAP_PACKET_DONT_REDRAW
;
1615 /****************************************************************************/
1618 mtp3_calls_init_tap(voip_calls_tapinfo_t
*tap_id_base
)
1620 GString
*error_string
;
1622 error_string
= register_tap_listener("mtp3", tap_base_to_id(tap_id_base
, tap_id_offset_mtp3_
),
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
);
1637 error_string
= register_tap_listener("m3ua", tap_base_to_id(tap_id_base
, tap_id_offset_m3ua_
),
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
);
1654 /****************************************************************************/
1657 remove_tap_listener_mtp3_calls(voip_calls_tapinfo_t
*tap_id_base
)
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_
));
1663 /****************************************************************************/
1664 /* ***************************TAP for Q931 **********************************/
1665 /****************************************************************************/
1666 static void h245_add_to_graph(voip_calls_tapinfo_t
*tapinfo
, uint32_t 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 */
1670 /****************************************************************************/
1671 /* whenever a q931_ packet is seen by the tap listener */
1672 static tap_packet_status
1673 q931_calls_packet(void *tap_offset_ptr
, packet_info
*pinfo
, epan_dissect_t
*edt
, const void *q931_info
, tap_flags_t flags _U_
)
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 char *comment
, *tmp_str
;
1684 const q931_packet_info
*pi
= (const q931_packet_info
*)q931_info
;
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
;
1691 /* free previously allocated q931_calling/ed_number */
1692 g_free(tapinfo
->q931_calling_number
);
1693 g_free(tapinfo
->q931_called_number
);
1695 if (pi
->calling_number
!=NULL
)
1696 tapinfo
->q931_calling_number
= g_strdup(pi
->calling_number
);
1698 tapinfo
->q931_calling_number
= g_strdup("");
1700 if (pi
->called_number
!=NULL
)
1701 tapinfo
->q931_called_number
= g_strdup(pi
->called_number
);
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
;
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);
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
);
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
;
1728 list
= g_list_next (list
);
1731 if (callsinfo
!= NULL
) {
1733 if (tapinfo
->h225_cstype
== H225_SETUP
) {
1734 /* set the 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
);
1739 if (tapinfo
->q931_called_number
!= NULL
) {
1740 g_free(callsinfo
->to_identity
);
1741 callsinfo
->to_identity
=g_strdup(tapinfo
->q931_called_number
);
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);
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
;
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
);
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
);
1767 list2
= g_list_first(tmp2_h323info
->h245_list
);
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
);
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
);
1782 list
= g_list_next (list
);
1785 comment
= ws_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
= ws_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");
1796 /* change the graph comment for this new one */
1797 if (comment
!= NULL
) {
1798 change_frame_graph(tapinfo
, tapinfo
->h225_frame_num
, NULL
, comment
);
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;
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);
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
);
1826 /* Add the H245 info if exists to the Graph */
1827 h245_add_to_graph(tapinfo
, pinfo
->num
);
1831 list
= g_list_next (list
);
1834 } else if (tapinfo
->sip_frame_num
== tapinfo
->q931_frame_num
) {
1835 /* Do nothing for now */
1836 /* add stuff to ACTRACE */
1842 list
= g_queue_peek_nth_link(tapinfo
->callsinfos
, 0);
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
);
1854 list
= g_list_next (list
);
1857 set_address(&pstn_add
, AT_STRINGZ
, 5, g_strdup("PSTN"));
1859 /* if it is a new call, add it to the list */
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
);
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
);
1886 switch(pi
->message_type
) {
1888 comment
= ws_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
;
1892 callsinfo
->call_state
=VOIP_IN_CALL
;
1894 case Q931_RELEASE_COMPLETE
:
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
;
1901 else { /* reverse */
1902 callsinfo
->call_state
=VOIP_REJECTED
;
1903 tapinfo
->rejected_calls
++;
1905 } else if ( (callsinfo
->call_state
!=VOIP_CANCELLED
) && (callsinfo
->call_state
!=VOIP_REJECTED
) ) {
1906 callsinfo
->call_state
=VOIP_COMPLETED
;
1907 tapinfo
->completed_calls
++;
1909 if (tapinfo
->q931_cause_value
!= 0xFF) {
1910 comment
= ws_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");
1919 comment
= ws_strdup_printf("AC_ISDN trunk:%u", tapinfo
->actrace_trunk
);
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
,
1926 wmem_free(NULL
, tmp_str
);
1929 free_address(&pstn_add
);
1932 tapinfo
->redraw
|= REDRAW_Q931
;
1934 return TAP_PACKET_REDRAW
; /* refresh output */
1937 /****************************************************************************/
1939 q931_calls_draw(void *tap_offset_ptr
)
1941 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_q931_
);
1943 if (tapinfo
->tap_draw
&& (tapinfo
->redraw
& REDRAW_Q931
)) {
1944 tapinfo
->tap_draw(tapinfo
);
1945 tapinfo
->redraw
&= ~REDRAW_Q931
;
1949 /****************************************************************************/
1952 q931_calls_init_tap(voip_calls_tapinfo_t
*tap_id_base
)
1954 GString
*error_string
;
1956 error_string
= register_tap_listener("q931", tap_base_to_id(tap_id_base
, tap_id_offset_q931_
),
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
);
1972 /****************************************************************************/
1975 remove_tap_listener_q931_calls(voip_calls_tapinfo_t
*tap_id_base
)
1977 remove_tap_listener(tap_base_to_id(tap_id_base
, tap_id_offset_q931_
));
1980 /****************************************************************************/
1981 /****************************TAP for H323 ***********************************/
1982 /****************************************************************************/
1985 add_h245_Address(h323_calls_info_t
*h323info
, h245_address_t
*h245_address
)
1987 h323info
->h245_list
= g_list_prepend(h323info
->h245_list
, h245_address
);
1992 free_h225_info(void *p
) {
1993 h323_calls_info_t
*tmp_h323info
= (h323_calls_info_t
*)p
;
1995 /* DUMP_PTR2(tmp_h323info->guid); */
1996 g_free(tmp_h323info
->guid
);
1998 if (tmp_h323info
->h245_list
) {
1999 GList
*list2
= g_list_first(tmp_h323info
->h245_list
);
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
);
2008 g_list_free(tmp_h323info
->h245_list
);
2014 /****************************************************************************/
2015 /* whenever a H225 packet is seen by the tap listener */
2016 static tap_packet_status
2017 h225_calls_packet(void *tap_offset_ptr
, packet_info
*pinfo
, epan_dissect_t
*edt
, const void *H225info
, tap_flags_t flags _U_
)
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
;
2026 h245_address_t
*h245_add
= NULL
;
2028 const h225_packet_info
*pi
= (const h225_packet_info
*)H225info
;
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
;
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
;
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
;
2046 /* check whether we already have a call with this request SeqNum */
2047 list
= g_queue_peek_nth_link(tapinfo
->callsinfos
, 0);
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
);
2059 list
= g_list_next (list
);
2062 /* check whether we already have a call with this guid in the list */
2063 list
= g_queue_peek_nth_link(tapinfo
->callsinfos
, 0);
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
);
2075 list
= g_list_next (list
);
2079 tapinfo
->h225_cstype
= pi
->cs_type
;
2080 tapinfo
->h225_is_faststart
= pi
->is_faststart
;
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
;
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); */
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;
2113 g_queue_push_tail(tapinfo
->callsinfos
, callsinfo
);
2116 tapinfo
->h225_frame_num
= pinfo
->num
;
2117 tapinfo
->h225_call_num
= callsinfo
->call_num
;
2119 /* let's analyze the call state */
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
);
2128 /* XXX: it is supposed to be initialized isn't it? */
2129 ws_assert(tmp_h323info
!= NULL
);
2131 /* change the status */
2132 if (pi
->msg_type
== H225_CS
) {
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
);
2142 if (pi
->cs_type
!= H225_RELEASE_COMPLET
) tmp_h323info
->is_h245Tunneling
= pi
->is_h245Tunneling
;
2144 frame_label
= g_strdup(pi
->frame_label
);
2146 switch(pi
->cs_type
) {
2148 tmp_h323info
->is_faststart_Setup
= pi
->is_faststart
;
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
= ws_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info
->is_h245Tunneling
==true?"on":"off"),
2155 (pi
->is_faststart
==true?"on":"off"));
2158 callsinfo
->call_state
=VOIP_IN_CALL
;
2159 if (pi
->is_faststart
== true) tmp_h323info
->is_faststart_Proc
= true;
2160 comment
= ws_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info
->is_h245Tunneling
==true?"on":"off"),
2161 (pi
->is_faststart
==true?"on":"off"));
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
;
2168 else { /* reverse */
2169 callsinfo
->call_state
=VOIP_REJECTED
;
2170 tapinfo
->rejected_calls
++;
2173 callsinfo
->call_state
=VOIP_COMPLETED
;
2174 tapinfo
->completed_calls
++;
2176 comment
= g_strdup("H225 No Q931 Rel Cause");
2180 case H225_CALL_PROCEDING
:
2181 if (pi
->is_faststart
== true) tmp_h323info
->is_faststart_Proc
= true;
2182 comment
= ws_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info
->is_h245Tunneling
==true?"on":"off"),
2183 (pi
->is_faststart
==true?"on":"off"));
2186 comment
= ws_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info
->is_h245Tunneling
==true?"on":"off"),
2187 (pi
->is_faststart
==true?"on":"off"));
2191 else if (pi
->msg_type
== H225_RAS
) {
2192 switch(pi
->msg_tag
) {
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
;
2201 if (strlen(pi
->dialedDigits
))
2202 comment
= ws_strdup_printf("H225 RAS dialedDigits: %s", pi
->dialedDigits
);
2204 comment
= g_strdup("H225 RAS");
2207 comment
= g_strdup("H225 RAS");
2209 frame_label
= g_strdup(val_to_str_const(pi
->msg_tag
, h225_RasMessage_vals
, "<unknown>"));
2211 frame_label
= g_strdup("H225: Unknown");
2215 /* add to graph analysis */
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);
2223 /* Add the H245 info if exists to the Graph */
2224 h245_add_to_graph(tapinfo
, pinfo
->num
);
2226 g_free(frame_label
);
2229 tapinfo
->redraw
|= REDRAW_H225
;
2231 return TAP_PACKET_REDRAW
; /* refresh output */
2234 /****************************************************************************/
2236 h225_calls_draw(void *tap_offset_ptr
)
2238 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_h225_
);
2240 if (tapinfo
->tap_draw
&& (tapinfo
->redraw
& REDRAW_H225
)) {
2241 tapinfo
->tap_draw(tapinfo
);
2242 tapinfo
->redraw
&= ~REDRAW_H225
;
2246 /****************************************************************************/
2248 /****************************************************************************/
2250 h225_calls_init_tap(voip_calls_tapinfo_t
*tap_id_base
)
2252 GString
*error_string
;
2254 error_string
= register_tap_listener("h225", tap_base_to_id(tap_id_base
, tap_id_offset_h225_
), NULL
,
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
);
2269 /****************************************************************************/
2271 remove_tap_listener_h225_calls(voip_calls_tapinfo_t
*tap_id_base
)
2273 remove_tap_listener(tap_base_to_id(tap_id_base
, tap_id_offset_h225_
));
2276 /* Add the h245 label info to the graph */
2278 h245_add_to_graph(voip_calls_tapinfo_t
*tapinfo
, uint32_t new_frame_num
)
2282 if (new_frame_num
!= tapinfo
->h245_labels
->frame_num
) return;
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
;
2291 tapinfo
->h245_labels
->frame_num
= 0;
2292 tapinfo
->h245_labels
->labels_count
= 0;
2295 /* free the h245_labels if the frame number is different */
2297 h245_free_labels(voip_calls_tapinfo_t
*tapinfo
, uint32_t new_frame_num
)
2301 if (new_frame_num
== tapinfo
->h245_labels
->frame_num
) return;
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
;
2309 tapinfo
->h245_labels
->frame_num
= 0;
2310 tapinfo
->h245_labels
->labels_count
= 0;
2313 /* add the frame_label and comment to h245_labels and free the actual one if it is different frame num */
2315 h245_add_label(voip_calls_tapinfo_t
*tapinfo
, uint32_t new_frame_num
, const char *frame_label
, const char *comment
)
2317 h245_free_labels(tapinfo
, new_frame_num
);
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
);
2323 if (tapinfo
->h245_labels
->labels_count
< (H245_MAX
-1))
2324 tapinfo
->h245_labels
->labels_count
++;
2328 /****************************************************************************/
2329 /* whenever a H245dg packet is seen by the tap listener (when H245 tunneling is ON) */
2330 static tap_packet_status
2331 h245dg_calls_packet(void *tap_offset_ptr
, packet_info
*pinfo
, epan_dissect_t
*edt
, const void *H245info
, tap_flags_t flags _U_
)
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
;
2339 h245_address_t
*h245_add
= NULL
;
2341 const h245_packet_info
*pi
= (const h245_packet_info
*)H245info
;
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
;
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);
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
;
2356 list2
= g_list_first(tmp_h323info
->h245_list
);
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
);
2364 ++(callsinfo
->npackets
);
2365 /* increment the packets counter of all calls */
2366 ++(tapinfo
->npackets
);
2370 list2
= g_list_next(list2
);
2372 if (callsinfo
!=NULL
) break;
2374 list
= g_list_next(list
);
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);
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 */
2392 h245_add_label(tapinfo
, pinfo
->num
, pi
->frame_label
, pi
->comment
);
2395 tapinfo
->redraw
|= REDRAW_H245DG
;
2397 return TAP_PACKET_REDRAW
; /* refresh output */
2400 /****************************************************************************/
2402 h245dg_calls_draw(void *tap_offset_ptr
)
2404 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_h245dg_
);
2406 if (tapinfo
->tap_draw
&& (tapinfo
->redraw
& REDRAW_H245DG
)) {
2407 tapinfo
->tap_draw(tapinfo
);
2408 tapinfo
->redraw
&= ~REDRAW_H245DG
;
2412 /****************************************************************************/
2414 /****************************************************************************/
2416 h245dg_calls_init_tap(voip_calls_tapinfo_t
*tap_id_base
)
2418 GString
*error_string
;
2420 if (!tap_id_base
->h245_labels
) {
2421 tap_id_base
->h245_labels
= g_new0(h245_labels_t
, 1);
2424 error_string
= register_tap_listener("h245dg", tap_base_to_id(tap_id_base
, tap_id_offset_h245dg_
), NULL
,
2427 h245dg_calls_packet
,
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
);
2439 /****************************************************************************/
2441 remove_tap_listener_h245dg_calls(voip_calls_tapinfo_t
*tap_id_base
)
2443 if (tap_id_base
->h245_labels
) {
2444 g_free(tap_id_base
->h245_labels
);
2445 tap_id_base
->h245_labels
= NULL
;
2447 remove_tap_listener(tap_base_to_id(tap_id_base
, tap_id_offset_h245dg_
));
2450 /****************************************************************************/
2451 /****************************TAP for SDP PROTOCOL ***************************/
2452 /****************************************************************************/
2453 /* whenever a SDP packet is seen by the tap listener */
2454 static tap_packet_status
2455 sdp_calls_packet(void *tap_offset_ptr
, packet_info
*pinfo
, epan_dissect_t
*edt _U_
, const void *SDPinfo
, tap_flags_t flags _U_
)
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
;
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
;
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
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
= ws_strdup_printf("SDP (%s)", pi
->summary_str
);
2473 append_to_frame_graph(tapinfo
, pinfo
->num
, tapinfo
->sdp_summary
, NULL
);
2475 tapinfo
->redraw
|= REDRAW_SDP
;
2477 return TAP_PACKET_REDRAW
; /* refresh output */
2480 /****************************************************************************/
2482 sdp_calls_draw(void *tap_offset_ptr
)
2484 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_sdp_
);
2486 if (tapinfo
->tap_draw
&& (tapinfo
->redraw
& REDRAW_SDP
)) {
2487 tapinfo
->tap_draw(tapinfo
);
2488 tapinfo
->redraw
&= ~REDRAW_SDP
;
2492 /****************************************************************************/
2494 /****************************************************************************/
2496 sdp_calls_init_tap(voip_calls_tapinfo_t
*tap_id_base
)
2498 GString
*error_string
;
2500 error_string
= register_tap_listener("sdp", tap_base_to_id(tap_id_base
, tap_id_offset_sdp_
), NULL
,
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
);
2515 /****************************************************************************/
2517 remove_tap_listener_sdp_calls(voip_calls_tapinfo_t
*tap_id_base
)
2519 remove_tap_listener(tap_base_to_id(tap_id_base
, tap_id_offset_sdp_
));
2522 /****************************************************************************/
2523 /* ***************************TAP for MGCP **********************************/
2524 /****************************************************************************/
2527 This function will look for a signal/event in the SignalReq/ObsEvent string
2528 and return true if it is found
2531 is_mgcp_signal(const char *signal_str_p
, const char *signalStr
)
2537 /* if there is no signalStr, just return false */
2538 if (signalStr
== NULL
) return false;
2540 /* if are both "blank" return true */
2541 if ( (*signal_str_p
== '\0') && (*signalStr
== '\0') ) return true;
2543 /* look for signal in signalStr */
2544 resultArray
= g_strsplit(signalStr
, ",", 10);
2546 for (i
= 0; resultArray
[i
]; i
++) {
2547 g_strstrip(resultArray
[i
]);
2548 if (strcmp(resultArray
[i
], signal_str_p
) == 0) {
2554 g_strfreev(resultArray
);
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")
2564 mgcp_caller_id(char *signalStr
, char **callerId
)
2568 /* if there is no signalStr, just return false */
2569 if (signalStr
== NULL
) return;
2571 arrayStr
= g_strsplit(signalStr
, "\"", 3);
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 */
2577 *callerId
= g_strdup(arrayStr
[1]);
2579 g_strfreev(arrayStr
);
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,#,*
2587 mgcp_dialed_digits(char *signalStr
, char **dialedDigits
)
2593 /* start with 1 for the null-terminator */
2594 unsigned resultStrLen
= 1;
2596 /* if there is no signalStr, just return false */
2597 if (signalStr
== NULL
) return;
2599 tmpStr
= g_strdup(signalStr
);
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 '*' :
2614 if (resultStrLen
== 1) {
2619 resultStr
= (char *)g_malloc(resultStrLen
);
2621 for (i
= 0, j
= 0; tmpStr
[i
]; i
++) {
2622 if (tmpStr
[i
] != '?')
2623 resultStr
[j
++] = tmpStr
[i
];
2625 resultStr
[j
] = '\0';
2627 g_free(*dialedDigits
);
2630 *dialedDigits
= resultStr
;
2637 /****************************************************************************/
2638 /* whenever a MGCP packet is seen by the tap listener */
2639 static tap_packet_status
2640 mgcp_calls_packet(void *tap_offset_ptr
, packet_info
*pinfo
, epan_dissect_t
*edt
, const void *MGCPinfo
, tap_flags_t flags _U_
)
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
;
2647 GList
*listGraph
= NULL
;
2648 char *frame_label
= NULL
;
2649 char *comment
= NULL
;
2650 seq_analysis_item_t
*gai
= NULL
;
2651 bool newcall
= false;
2652 bool fromEndpoint
= false; /* true for calls originated in Endpoints, false for calls from MGC */
2655 const mgcp_info_t
*pi
= (const mgcp_info_t
*)MGCPinfo
;
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
;
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);
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) {
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
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
)) &&
2682 tmp_listinfo
->call_active_state
= VOIP_INACTIVE
;
2684 callsinfo
= (voip_calls_info_t
*)(list
->data
);
2690 list
= g_list_next (list
);
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;
2699 } else if (strcmp(pi
->code
, "CRCX") == 0) {
2700 /* this is a new call from the MGC */
2701 fromEndpoint
= false;
2704 if (!newcall
) return TAP_PACKET_DONT_REDRAW
;
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);
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);
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
);
2729 list
= g_list_next (list
);
2731 if (callsinfo
!= NULL
) break;
2733 listGraph
= g_list_next(listGraph
);
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
;
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
;
2745 callsinfo
->from_identity
=g_strdup(pi
->endpointId
);
2746 callsinfo
->to_identity
=g_strdup("");
2748 callsinfo
->from_identity
=g_strdup("");
2749 callsinfo
->to_identity
=g_strdup(pi
->endpointId
);
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
);
2765 ws_assert(tmp_mgcpinfo
!= NULL
);
2767 /* change call state and add to graph */
2768 switch (pi
->mgcp_type
)
2771 if ( (strcmp(pi
->code
, "NTFY") == 0) && (pi
->observedEvents
!= NULL
) ) {
2772 frame_label
= ws_strdup_printf("%s ObsEvt:%s",pi
->code
, pi
->observedEvents
);
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
));
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
;
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
;
2787 callsinfo
->call_state
= VOIP_COMPLETED
;
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
;
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
;
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
;
2807 if (pi
->signalReq
!= NULL
)
2808 frame_label
= ws_strdup_printf("%s%sSigReq:%s",pi
->code
, (pi
->hasDigitMap
== true)?" DigitMap ":"", pi
->signalReq
);
2810 frame_label
= ws_strdup_printf("%s%s",pi
->code
, (pi
->hasDigitMap
== true)?" DigitMap ":"");
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
));
2815 } else if (strcmp(pi
->code
, "DLCX") == 0) {
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
2820 if (!tmp_mgcpinfo
->fromEndpoint
) {
2821 if ((callsinfo
->call_state
== VOIP_CALL_SETUP
) || (callsinfo
->call_state
== VOIP_RINGING
)) {
2822 callsinfo
->call_state
= VOIP_CANCELLED
;
2827 if (frame_label
== NULL
) frame_label
= g_strdup(pi
->code
);
2830 frame_label
= ws_strdup_printf("%u (%s)",pi
->rspcode
, pi
->code
);
2833 /* XXX what to do? */
2837 comment
= ws_strdup_printf("MGCP %s %s%s", tmp_mgcpinfo
->endpointId
, (pi
->mgcp_type
== MGCP_REQUEST
)?"Request":"Response", pi
->is_duplicate
?" Duplicate":"");
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
);
2845 /* add to the graph */
2846 add_to_graph(tapinfo
, pinfo
, edt
, frame_label
, comment
, callsinfo
->call_num
, &(pinfo
->src
), &(pinfo
->dst
), 1);
2848 g_free(frame_label
);
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
;
2857 tapinfo
->redraw
|= REDRAW_MGCP
;
2859 return TAP_PACKET_REDRAW
; /* refresh output */
2862 /****************************************************************************/
2864 mgcp_calls_draw(void *tap_offset_ptr
)
2866 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_mgcp_
);
2868 if (tapinfo
->tap_draw
&& (tapinfo
->redraw
& REDRAW_MGCP
)) {
2869 tapinfo
->tap_draw(tapinfo
);
2870 tapinfo
->redraw
&= ~REDRAW_MGCP
;
2874 /****************************************************************************/
2876 /****************************************************************************/
2878 mgcp_calls_init_tap(voip_calls_tapinfo_t
*tap_id_base
)
2880 GString
*error_string
;
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
2888 error_string
= register_tap_listener("mgcp",
2889 tap_base_to_id(tap_id_base
, tap_id_offset_mgcp_
),
2891 TL_REQUIRES_PROTO_TREE
,
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
);
2904 /****************************************************************************/
2906 remove_tap_listener_mgcp_calls(voip_calls_tapinfo_t
*tap_id_base
)
2908 remove_tap_listener(tap_base_to_id(tap_id_base
, tap_id_offset_mgcp_
));
2911 /****************************************************************************/
2912 /****************************TAP for ACTRACE (AudioCodes trace)**************/
2913 /****************************************************************************/
2915 /* whenever a ACTRACE packet is seen by the tap listener */
2916 static tap_packet_status
2917 actrace_calls_packet(void *tap_offset_ptr
, packet_info
*pinfo
, epan_dissect_t
*edt
, const void *ACTRACEinfo
, tap_flags_t flags _U_
)
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
;
2922 actrace_cas_calls_info_t
*tmp_actrace_cas_info
;
2923 voip_calls_info_t
*tmp_listinfo
;
2924 voip_calls_info_t
*callsinfo
= NULL
;
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
;
2931 tapinfo
->actrace_frame_num
= pinfo
->num
;
2932 tapinfo
->actrace_trunk
= pi
->trunk
;
2933 tapinfo
->actrace_direction
= pi
->direction
;
2935 if (pi
->type
== 1) { /* is CAS protocol */
2937 char *comment
= NULL
;
2940 list
= g_queue_peek_nth_link(tapinfo
->callsinfos
, 0);
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
);
2952 list
= g_list_next (list
);
2955 set_address(&pstn_add
, AT_STRINGZ
, 5, "PSTN");
2957 /* if it is a new call, add it to the list */
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
;
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
);
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
);
2985 comment
= ws_strdup_printf("AC_CAS trunk:%u", tapinfo
->actrace_trunk
);
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
,
2995 tapinfo
->redraw
|= REDRAW_ACTRACE
;
2997 return TAP_PACKET_REDRAW
; /* refresh output */
3000 /****************************************************************************/
3002 actrace_calls_draw(void *tap_offset_ptr
)
3004 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_actrace_
);
3006 if (tapinfo
->tap_draw
&& (tapinfo
->redraw
& REDRAW_ACTRACE
)) {
3007 tapinfo
->tap_draw(tapinfo
);
3008 tapinfo
->redraw
&= ~REDRAW_ACTRACE
;
3012 /****************************************************************************/
3014 /****************************************************************************/
3016 actrace_calls_init_tap(voip_calls_tapinfo_t
*tap_id_base
)
3018 GString
*error_string
;
3020 error_string
= register_tap_listener("actrace", tap_base_to_id(tap_id_base
, tap_id_offset_actrace_
), NULL
,
3023 actrace_calls_packet
,
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
);
3035 /****************************************************************************/
3037 remove_tap_listener_actrace_calls(voip_calls_tapinfo_t
*tap_id_base
)
3039 remove_tap_listener(tap_base_to_id(tap_id_base
, tap_id_offset_actrace_
));
3043 /****************************************************************************/
3044 /**************************** TAP for H248/MEGACO **********************************/
3045 /****************************************************************************/
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 )
3053 static tap_packet_status
3054 h248_calls_packet_common(voip_calls_tapinfo_t
*tapinfo
, packet_info
*pinfo
, epan_dissect_t
*edt
, const void *prot_info
, uint32_t redraw_bit
) {
3055 const gcp_cmd_t
*cmd
= (const gcp_cmd_t
*)prot_info
;
3057 voip_calls_info_t
*callsinfo
= NULL
;
3062 if (cmd
->ctx
->id
== NULL_CONTEXT
|| cmd
->ctx
->id
== ALL_CONTEXTS
) {
3063 return TAP_PACKET_DONT_REDRAW
;
3066 if ( gcp_is_req(cmd
->type
) ) {
3067 mgw
= &(pinfo
->dst
);
3068 mgc
= &(pinfo
->src
);
3070 mgc
= &(pinfo
->dst
);
3071 mgw
= &(pinfo
->src
);
3074 address_to_str_buf(mgw
, mgw_addr
, 128);
3076 /* check whether we already have this context in the list */
3077 list
= g_queue_peek_nth_link(tapinfo
->callsinfos
, 0);
3080 voip_calls_info_t
* tmp_listinfo
= (voip_calls_info_t
*)list
->data
;
3082 if (tmp_listinfo
->protocol
== TEL_H248
) {
3083 if (tmp_listinfo
->prot_info
== cmd
->ctx
) {
3084 callsinfo
= (voip_calls_info_t
*)(list
->data
);
3088 list
= g_list_next (list
);
3091 if (callsinfo
==NULL
) {
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
= ws_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
;
3101 callsinfo
->npackets
= 1;
3103 copy_address(&(callsinfo
->initial_speaker
), mgc
);
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
;
3112 g_queue_push_tail(tapinfo
->callsinfos
, callsinfo
);
3115 GString
*s
= g_string_new("");
3116 gcp_terms_t
*ctx_term
;
3118 g_free(callsinfo
->from_identity
);
3119 callsinfo
->from_identity
= ws_strdup_printf("%s : %.8x", mgw_addr
, ((gcp_ctx_t
*)callsinfo
->prot_info
)->id
);
3121 g_free(callsinfo
->to_identity
);
3123 for (ctx_term
= ((gcp_ctx_t
*)callsinfo
->prot_info
)->terms
.next
;
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
);
3131 callsinfo
->to_identity
= g_string_free(s
,FALSE
);
3133 callsinfo
->stop_fd
= pinfo
->fd
;
3134 callsinfo
->stop_rel_ts
= pinfo
->rel_ts
;
3135 ++(callsinfo
->npackets
);
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);
3142 ++(tapinfo
->npackets
);
3144 tapinfo
->redraw
|= redraw_bit
;
3146 return TAP_PACKET_REDRAW
;
3149 static tap_packet_status
3150 h248_calls_packet(void *tap_offset_ptr
, packet_info
*pinfo
, epan_dissect_t
*edt
, const void *prot_info
, tap_flags_t flags _U_
) {
3151 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_h248_
);
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
;
3157 return h248_calls_packet_common(tapinfo
, pinfo
, edt
, prot_info
, REDRAW_H248
);
3161 h248_calls_draw(void *tap_offset_ptr
)
3163 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_h248_
);
3165 if (tapinfo
->tap_draw
&& (tapinfo
->redraw
& REDRAW_H248
)) {
3166 tapinfo
->tap_draw(tapinfo
);
3167 tapinfo
->redraw
&= ~REDRAW_H248
;
3171 static tap_packet_status
3172 megaco_calls_packet(void *tap_offset_ptr
, packet_info
*pinfo
, epan_dissect_t
*edt
, const void *prot_info
, tap_flags_t flags _U_
) {
3173 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_megaco_
);
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
;
3179 return h248_calls_packet_common(tapinfo
, pinfo
, edt
, prot_info
, REDRAW_MEGACO
);
3183 megaco_calls_draw(void *tap_offset_ptr
)
3185 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_megaco_
);
3187 if (tapinfo
->tap_draw
&& (tapinfo
->redraw
& REDRAW_MEGACO
)) {
3188 tapinfo
->tap_draw(tapinfo
);
3189 tapinfo
->redraw
&= ~REDRAW_MEGACO
;
3194 h248_calls_init_tap(voip_calls_tapinfo_t
*tap_id_base
)
3196 GString
*error_string
;
3198 error_string
= register_tap_listener("megaco", tap_base_to_id(tap_id_base
, tap_id_offset_megaco_
),
3202 megaco_calls_packet
,
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
);
3212 error_string
= register_tap_listener("h248", tap_base_to_id(tap_id_base
, tap_id_offset_h248_
),
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
);
3228 remove_tap_listener_h248_calls(voip_calls_tapinfo_t
*tap_id_base
)
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_
));
3234 /****************************************************************************/
3235 /**************************** TAP for SCCP and SUA **********************************/
3236 /**************************** ( RANAP and BSSAP ) **********************************/
3237 /****************************************************************************/
3239 static const voip_protocol sccp_proto_map
[] = {
3244 #define SP2VP(ap) ((ap) < SCCP_PLOAD_NUM_PLOADS ? sccp_proto_map[(ap)] : TEL_SCCP)
3245 const value_string
* sccp_payload_values
;
3247 static tap_packet_status
3248 sccp_calls(voip_calls_tapinfo_t
*tapinfo
, packet_info
*pinfo
, epan_dissect_t
*edt
, const void *prot_info
, uint32_t 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
;
3252 voip_calls_info_t
*callsinfo
= NULL
;
3254 const char *comment
= NULL
;
3255 /* check whether we already have this assoc in the list */
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
);
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
);
3271 callsinfo
->from_identity
= g_strdup("Unknown");
3274 if ( assoc
->called_party
) {
3275 callsinfo
->to_identity
= g_strdup(assoc
->called_party
);
3277 callsinfo
->to_identity
= g_strdup("Unknown");
3280 callsinfo
->prot_info
= (void*)assoc
;
3281 callsinfo
->free_prot_info
= NULL
;
3283 callsinfo
->npackets
= 1;
3285 copy_address(&(callsinfo
->initial_speaker
), &(pinfo
->src
));
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
;
3294 callsinfo
->call_num
= tapinfo
->ncalls
++;
3296 g_queue_push_tail(tapinfo
->callsinfos
, callsinfo
);
3299 if ( assoc
->calling_party
) {
3300 g_free(callsinfo
->from_identity
);
3301 callsinfo
->from_identity
= g_strdup(assoc
->calling_party
);
3304 if ( assoc
->called_party
) {
3305 g_free(callsinfo
->to_identity
);
3306 callsinfo
->to_identity
= g_strdup(assoc
->called_party
);
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
);
3315 switch (msg
->type
) {
3316 case SCCP_MSG_TYPE_CC
:
3317 callsinfo
->call_state
= VOIP_IN_CALL
;
3319 case SCCP_MSG_TYPE_RLC
:
3320 callsinfo
->call_state
= VOIP_COMPLETED
;
3321 callsinfo
->call_active_state
= VOIP_INACTIVE
;
3328 if (msg
->data
.co
.label
) {
3329 label
= wmem_strdup(NULL
, msg
->data
.co
.label
);
3331 label
= val_to_str_wmem(NULL
, msg
->type
, sccp_payload_values
, "Unknown(%d)");
3334 if (msg
->data
.co
.comment
) {
3335 comment
= msg
->data
.co
.comment
;
3340 add_to_graph(tapinfo
, pinfo
, edt
, label
, comment
, callsinfo
->call_num
, &(pinfo
->src
), &(pinfo
->dst
), 1);
3341 wmem_free(NULL
, label
);
3343 ++(tapinfo
->npackets
);
3345 tapinfo
->redraw
|= redraw_bit
;
3347 return TAP_PACKET_REDRAW
;
3350 static tap_packet_status
3351 sccp_calls_packet(void *tap_offset_ptr
, packet_info
*pinfo
, epan_dissect_t
*edt
, const void *prot_info
, tap_flags_t flags _U_
) {
3352 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_sccp_
);
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
;
3358 sccp_payload_values
= sccp_message_type_acro_values
;
3359 return sccp_calls(tapinfo
, pinfo
, edt
, prot_info
, REDRAW_SCCP
);
3363 sccp_calls_draw(void *tap_offset_ptr
)
3365 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_sccp_
);
3367 if (tapinfo
->tap_draw
&& (tapinfo
->redraw
& REDRAW_SCCP
)) {
3368 tapinfo
->tap_draw(tapinfo
);
3369 tapinfo
->redraw
&= ~REDRAW_SCCP
;
3373 static tap_packet_status
3374 sua_calls_packet(void *tap_offset_ptr
, packet_info
*pinfo
, epan_dissect_t
*edt
, const void *prot_info
, tap_flags_t flags _U_
) {
3375 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_sua_
);
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
;
3381 sccp_payload_values
= sua_co_class_type_acro_values
;
3382 return sccp_calls(tapinfo
, pinfo
, edt
, prot_info
, REDRAW_SUA
);
3386 sua_calls_draw(void *tap_offset_ptr
)
3388 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_sua_
);
3390 if (tapinfo
->tap_draw
&& (tapinfo
->redraw
& REDRAW_SUA
)) {
3391 tapinfo
->tap_draw(tapinfo
);
3392 tapinfo
->redraw
&= ~REDRAW_SUA
;
3396 void sccp_calls_init_tap(voip_calls_tapinfo_t
*tap_id_base
)
3398 GString
*error_string
;
3400 error_string
= register_tap_listener("sccp", tap_base_to_id(tap_id_base
, tap_id_offset_sccp_
),
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
);
3414 error_string
= register_tap_listener("sua", tap_base_to_id(tap_id_base
, tap_id_offset_sua_
),
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
);
3430 remove_tap_listener_sccp_calls(voip_calls_tapinfo_t
*tap_id_base
)
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_
));
3437 /****************************************************************************/
3438 /****************************TAP for UNISTIM ********************************/
3439 /****************************************************************************/
3441 static tap_packet_status
3442 unistim_calls_packet(void *tap_offset_ptr
, packet_info
*pinfo
, epan_dissect_t
*edt
, const void *unistim_info
, tap_flags_t flags _U_
)
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
;
3449 GString
*g_tmp
= NULL
;
3450 const char *frame_label
= NULL
;
3451 char *comment
= NULL
;
3453 /* Fetch specific packet infos */
3454 const unistim_info_t
*pi
= (const unistim_info_t
*)unistim_info
;
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
;
3462 g_tmp
= g_string_new(NULL
);
3464 /* Check to see if this is a dup */
3465 list
= g_queue_peek_nth_link(tapinfo
->callsinfos
, 0);
3469 tmp_listinfo
= (voip_calls_info_t
*)list
->data
;
3471 if(tmp_listinfo
->protocol
== VOIP_UNISTIM
) {
3473 tmp_unistim_info
= (unistim_info_t
*)tmp_listinfo
->prot_info
;
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
) {
3482 callsinfo
= (voip_calls_info_t
*)(list
->data
);
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 */
3492 callsinfo
= (voip_calls_info_t
*)(list
->data
);
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.. */
3500 callsinfo
= (voip_calls_info_t
*)(list
->data
);
3507 /* Otherwise, go to the next one.. */
3508 list
= g_list_next(list
);
3511 if(pi
->payload_type
== 2 || pi
->payload_type
== 1) {
3513 if(pi
->key_state
== 1 || pi
->hook_state
== 1) {
3515 /* If the user hits a button,
3516 Session will be SETUP */
3518 /* If new add to list */
3519 if (callsinfo
==NULL
) {
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
=ws_strdup_printf("%x",pi
->termid
);
3525 callsinfo
->to_identity
=g_strdup("UNKNOWN");
3526 copy_address(&(callsinfo
->initial_speaker
),&(pinfo
->src
));
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
;
3534 callsinfo
->protocol
=VOIP_UNISTIM
;
3535 callsinfo
->prot_info
=g_new(unistim_info_t
, 1);
3537 tmp_unistim_info
= (unistim_info_t
*)callsinfo
->prot_info
;
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
;
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
;
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
);
3564 /* Set up call wide info struct */
3565 tmp_unistim_info
= (unistim_info_t
*)callsinfo
->prot_info
;
3566 tmp_unistim_info
->sequence
= pi
->sequence
;
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
;
3574 /* This is a valid packet so increment counter */
3575 ++(callsinfo
->npackets
);
3577 /* increment the packets counter of all calls */
3578 ++(tapinfo
->npackets
);
3580 /* Key was depressed.. update key buffer.. */
3581 if(pi
->key_val
>= 0 && pi
->key_val
<= 11) {
3583 if(tmp_unistim_info
->key_buffer
!= NULL
) {
3585 /* assign to temp variable */
3586 g_string_assign(g_tmp
,tmp_unistim_info
->key_buffer
);
3588 /* Manipulate the data */
3589 if(pi
->key_val
== 10) {
3590 tmp_unistim_info
->key_buffer
= ws_strdup_printf("%s*",g_tmp
->str
);
3591 } else if(pi
->key_val
== 11) {
3592 tmp_unistim_info
->key_buffer
= ws_strdup_printf("%s#",g_tmp
->str
);
3594 tmp_unistim_info
->key_buffer
= ws_strdup_printf("%s%d",g_tmp
->str
,pi
->key_val
);
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("#");
3605 tmp_unistim_info
->key_buffer
= ws_strdup_printf("%d",pi
->key_val
);
3610 /* Select for non-digit characters */
3611 if(pi
->key_val
== 10) {
3612 comment
= ws_strdup_printf("Key Input Sent: * (%d)", pi
->sequence
);
3613 } else if(pi
->key_val
== 11) {
3614 comment
= ws_strdup_printf("Key Input Sent: # (%d)", pi
->sequence
);
3616 comment
= ws_strdup_printf("Key Input Sent: %d (%d)",pi
->key_val
, pi
->sequence
);
3618 } else if(pi
->key_val
== 12) {
3619 /* Set label and comment for graph */
3620 comment
= ws_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
= ws_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
= ws_strdup_printf("Key Input Sent: RIGHT (%d)", pi
->sequence
);
3627 } else if(pi
->key_val
== 15) {
3628 if(pi
->key_buffer
!= NULL
) {
3630 g_string_assign(g_tmp
,pi
->key_buffer
);
3632 /* Manipulate the data */
3633 g_string_truncate(g_tmp
,g_tmp
->len
-1);
3635 /* Insert new data */
3636 tmp_unistim_info
->key_buffer
= g_strdup(g_tmp
->str
);
3639 /* Set label and comment for graph */
3640 comment
= ws_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
= ws_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
= ws_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
) {
3653 g_string_assign(g_tmp
,pi
->key_buffer
);
3655 /* Manipulate the data */
3656 g_string_truncate(g_tmp
,g_tmp
->len
-1);
3658 /* Insert new data */
3659 tmp_unistim_info
->key_buffer
= g_strdup(g_tmp
->str
);
3662 /* add label and comment */
3663 comment
= ws_strdup_printf("Key Input Sent: S2 (%d)", pi
->sequence
);
3664 } else if(pi
->key_val
== 28) {
3665 /* User pressed something */
3666 comment
= ws_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");
3673 /* User pressed something, set labels*/
3674 comment
= ws_strdup_printf("Key Input Sent: S3 (%d)", pi
->sequence
);
3675 } else if(pi
->key_val
== 27) {
3676 /* User pressed something */
3677 comment
= ws_strdup_printf("Key Input Sent: Hold (%d)", pi
->sequence
);
3678 } else if(pi
->key_val
== 29) {
3679 /* User pressed something */
3680 comment
= ws_strdup_printf("Key Input Sent: Mute (%d)", pi
->sequence
);
3681 } else if(pi
->key_val
== 30) {
3682 /* User pressed something */
3683 comment
= ws_strdup_printf("Key Input Sent: Headset (%d)", pi
->sequence
);
3684 } else if(pi
->key_val
== 31) {
3685 /* Handsfree button */
3686 comment
= ws_strdup_printf("Key Input Sent: Handsfree (%d)", pi
->sequence
);
3687 } else if(pi
->key_val
>= 32 && pi
->key_val
<= 56) {
3689 comment
= ws_strdup_printf("Key Input Sent: Prog%d (%d)", (pi
->key_val
& 31), pi
->sequence
);
3692 if(pi
->key_val
!= -1) {
3694 frame_label
= "KEY INPUT";
3696 if (comment
== NULL
)
3697 /* Ouch! What do you do!? */
3698 /* User pressed something */
3699 comment
= ws_strdup_printf("Key Input Sent: UNKNOWN - %d (%d)", pi
->key_val
, pi
->sequence
);
3701 /* add to the graph */
3702 add_to_graph(tapinfo
, pinfo
, edt
, frame_label
, comment
, callsinfo
->call_num
, &(pinfo
->src
), &(pinfo
->dst
), 1);
3707 if(pi
->hook_state
== 1) {
3709 /* Phone is off hook */
3710 frame_label
= "OFF HOOK";
3711 comment
= ws_strdup_printf("Off Hook (%d)", pi
->sequence
);
3713 /* add to the graph */
3714 add_to_graph(tapinfo
, pinfo
, edt
, frame_label
, comment
, callsinfo
->call_num
, &(pinfo
->src
), &(pinfo
->dst
), 1);
3717 } else if(pi
->hook_state
== 0) {
3719 /* Phone is on hook */
3720 frame_label
= "ON HOOK";
3721 comment
= ws_strdup_printf("On Hook (%d)", pi
->sequence
);
3723 /* add to the graph */
3724 add_to_graph(tapinfo
, pinfo
, edt
, frame_label
, comment
, callsinfo
->call_num
, &(pinfo
->src
), &(pinfo
->dst
), 1);
3730 /* Open stream was sent from server */
3731 if(pi
->stream_connect
== 1 && callsinfo
!= NULL
) {
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
;
3743 /* Local packets too */
3744 ++(callsinfo
->npackets
);
3746 /* increment the packets counter of all calls */
3747 ++(tapinfo
->npackets
);
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
3752 if(tmp_unistim_info
->key_buffer
!= NULL
) {
3753 callsinfo
->to_identity
= ws_strdup_printf("?? %s",tmp_unistim_info
->key_buffer
);
3756 /* change sequence number for ACK detection */
3757 tmp_unistim_info
->sequence
= pi
->sequence
;
3759 /* State changes too */
3760 callsinfo
->call_active_state
= VOIP_ACTIVE
;
3761 callsinfo
->call_state
= VOIP_IN_CALL
;
3763 /* Add graph data */
3764 frame_label
= "STREAM OPENED";
3765 comment
= ws_strdup_printf("Stream Opened (%d)",pi
->sequence
);
3767 /* add to the graph */
3768 add_to_graph(tapinfo
, pinfo
, edt
, frame_label
, comment
, callsinfo
->call_num
, &(pinfo
->src
), &(pinfo
->dst
), 1);
3770 } else if(pi
->stream_connect
== 1 && callsinfo
== NULL
) {
3772 /* Research indicates some nortel products initiate stream first
3773 * without keypresses, therefore creating this solely on a keypress is
3775 * Sometimes calls start immediately with open stream.
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
));
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
;
3789 callsinfo
->protocol
=VOIP_UNISTIM
;
3790 callsinfo
->prot_info
=g_new(unistim_info_t
, 1);
3792 tmp_unistim_info
= (unistim_info_t
*)callsinfo
->prot_info
;
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
;
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
;
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
);
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
);
3825 /* increment the packets counter of all calls */
3826 ++(tapinfo
->npackets
);
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
3831 if(tmp_unistim_info
->key_buffer
!= NULL
) {
3832 callsinfo
->to_identity
= ws_strdup_printf("?? %s",tmp_unistim_info
->key_buffer
);
3835 /* change sequence number for ACK detection */
3836 tmp_unistim_info
->sequence
= pi
->sequence
;
3838 /* State changes too */
3839 callsinfo
->call_active_state
= VOIP_ACTIVE
;
3840 callsinfo
->call_state
= VOIP_IN_CALL
;
3842 /* Add graph data */
3843 frame_label
= "STREAM OPENED";
3844 comment
= ws_strdup_printf("Stream Opened (%d)",pi
->sequence
);
3846 /* add to the graph */
3847 add_to_graph(tapinfo
, pinfo
, edt
, frame_label
, comment
, callsinfo
->call_num
, &(pinfo
->src
), &(pinfo
->dst
), 1);
3849 } else if(pi
->stream_connect
== 0 && callsinfo
!= NULL
) {
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
;
3857 tmp_unistim_info
->sequence
= pi
->sequence
;
3859 if(callsinfo
->call_state
== VOIP_IN_CALL
) {
3860 callsinfo
->call_active_state
= VOIP_INACTIVE
;
3861 callsinfo
->call_state
= VOIP_COMPLETED
;
3863 callsinfo
->call_state
= VOIP_UNKNOWN
;
3864 callsinfo
->call_active_state
= VOIP_INACTIVE
;
3867 frame_label
= "STREAM CLOSED";
3868 comment
= ws_strdup_printf("Stream Closed (%d)",pi
->sequence
);
3870 /* add to the graph */
3871 add_to_graph(tapinfo
, pinfo
, edt
, frame_label
, comment
, callsinfo
->call_num
, &(pinfo
->src
), &(pinfo
->dst
), 1);
3876 } else if(pi
->rudp_type
== 1 && callsinfo
!= NULL
) {
3878 /* Only show acks for processed seq #s */
3879 if(tmp_unistim_info
->sequence
== pi
->sequence
) {
3881 frame_label
= "ACK";
3882 comment
= ws_strdup_printf("ACK for sequence %d",pi
->sequence
);
3884 /* add to the graph */
3885 add_to_graph(tapinfo
, pinfo
, edt
, frame_label
, comment
, callsinfo
->call_num
, &(pinfo
->src
), &(pinfo
->dst
), 1);
3889 } else if(pi
->rudp_type
== 0 && callsinfo
!= NULL
) {
3892 frame_label
= "NAK";
3893 comment
= ws_strdup_printf("NAK for sequence %d",pi
->sequence
);
3895 /* add to the graph */
3896 add_to_graph(tapinfo
, pinfo
, edt
, frame_label
, comment
, callsinfo
->call_num
, &(pinfo
->src
), &(pinfo
->dst
), 1);
3902 g_string_free(g_tmp
, TRUE
);
3904 tapinfo
->redraw
|= REDRAW_UNISTIM
;
3906 return TAP_PACKET_REDRAW
;
3909 /****************************************************************************/
3911 unistim_calls_draw(void *tap_offset_ptr
)
3913 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_unistim_
);
3915 if (tapinfo
->tap_draw
&& (tapinfo
->redraw
& REDRAW_UNISTIM
)) {
3916 tapinfo
->tap_draw(tapinfo
);
3917 tapinfo
->redraw
&= ~REDRAW_UNISTIM
;
3921 /****************************************************************************/
3923 /****************************************************************************/
3925 unistim_calls_init_tap(voip_calls_tapinfo_t
*tap_id_base
) {
3927 GString
*error_string
;
3929 error_string
= register_tap_listener("unistim", tap_base_to_id(tap_id_base
, tap_id_offset_unistim_
),
3933 unistim_calls_packet
,
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
);
3945 /****************************************************************************/
3947 remove_tap_listener_unistim_calls(voip_calls_tapinfo_t
*tap_id_base
)
3949 remove_tap_listener(tap_base_to_id(tap_id_base
, tap_id_offset_unistim_
));
3952 /****************************************************************************/
3953 /* ***************************TAP for SKINNY **********************************/
3954 /****************************************************************************/
3956 /* Telecaster to tap-voip call state mapping */
3957 static const voip_call_state skinny_tap_voip_state
[] = {
3975 static tap_packet_status
3976 skinny_calls_packet(void *tap_offset_ptr
, packet_info
*pinfo
, epan_dissect_t
*edt
, const void *skinny_info
, tap_flags_t flags _U_
)
3978 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_skinny_
);
3980 voip_calls_info_t
*callsinfo
= NULL
;
3982 const skinny_info_t
*si
= (const skinny_info_t
*)skinny_info
;
3983 skinny_calls_info_t
*tmp_skinnyinfo
;
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
;
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);
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
);
4006 list
= g_list_next (list
);
4009 if (si
->messId
>= 256)
4010 phone
= &(pinfo
->dst
);
4012 phone
= &(pinfo
->src
);
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 = ws_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;
4027 copy_address(&(callsinfo
->initial_speaker
), phone
);
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
;
4036 g_queue_push_tail(tapinfo
->callsinfos
, callsinfo
);
4038 if (si
->callingParty
) {
4039 g_free(callsinfo
->from_identity
);
4040 callsinfo
->from_identity
= g_strdup(si
->callingParty
);
4042 if (si
->calledParty
) {
4043 g_free(callsinfo
->to_identity
);
4044 callsinfo
->to_identity
= g_strdup(si
->calledParty
);
4046 if ((si
->callState
> 0) && (si
->callState
< array_length(skinny_tap_voip_state
)))
4047 callsinfo
->call_state
= skinny_tap_voip_state
[si
->callState
];
4049 callsinfo
->stop_fd
= pinfo
->fd
;
4050 callsinfo
->stop_rel_ts
= pinfo
->rel_ts
;
4051 ++(callsinfo
->npackets
);
4055 if (si
->passThroughPartyId
)
4056 comment
= ws_strdup_printf("CallId = %u, PTId = %u", si
->callId
, si
->passThroughPartyId
);
4058 comment
= ws_strdup_printf("CallId = %u, LineId = %u", si
->callId
, si
->lineId
);
4060 if (si
->passThroughPartyId
)
4061 comment
= ws_strdup_printf("PTId = %u", si
->passThroughPartyId
);
4066 add_to_graph(tapinfo
, pinfo
, edt
, si
->messageName
, comment
,
4067 callsinfo
->call_num
, &(pinfo
->src
), &(pinfo
->dst
), 1);
4069 append_to_frame_graph(tapinfo
, pinfo
->num
, si
->additionalInfo
, NULL
);
4071 tapinfo
->redraw
|= REDRAW_SKINNY
;
4073 return TAP_PACKET_REDRAW
;
4076 /****************************************************************************/
4078 skinny_calls_draw(void *tap_offset_ptr
)
4080 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_skinny_
);
4082 if (tapinfo
->tap_draw
&& (tapinfo
->redraw
& REDRAW_SKINNY
)) {
4083 tapinfo
->tap_draw(tapinfo
);
4084 tapinfo
->redraw
&= ~REDRAW_SKINNY
;
4088 /****************************************************************************/
4090 /****************************************************************************/
4092 skinny_calls_init_tap(voip_calls_tapinfo_t
*tap_id_base
)
4094 GString
*error_string
;
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
4102 error_string
= register_tap_listener("skinny",
4103 tap_base_to_id(tap_id_base
, tap_id_offset_skinny_
),
4105 TL_REQUIRES_PROTO_TREE
,
4107 skinny_calls_packet
,
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
);
4118 /****************************************************************************/
4120 remove_tap_listener_skinny_calls(voip_calls_tapinfo_t
*tap_id_base
)
4122 remove_tap_listener(tap_base_to_id(tap_id_base
, tap_id_offset_skinny_
));
4125 /****************************************************************************/
4126 /* ***************************TAP for IAX2 **********************************/
4127 /****************************************************************************/
4129 static void free_iax2_info(void *p
) {
4130 iax2_info_t
*ii
= (iax2_info_t
*)p
;
4136 /****************************************************************************/
4137 /* whenever a IAX2 packet is seen by the tap listener */
4138 static tap_packet_status
4139 iax2_calls_packet( void *tap_offset_ptr
, packet_info
*pinfo
, epan_dissect_t
*edt
, const void *iax2_info
, tap_flags_t flags _U_
)
4141 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_iax2_
);
4143 voip_calls_info_t
*callsinfo
= NULL
;
4145 const iax2_info_t
*ii
= (const iax2_info_t
*)iax2_info
;
4146 iax2_info_t
*tmp_iax2info
;
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
;
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);
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
);
4168 list
= g_list_next (list
);
4170 phone
= &(pinfo
->src
);
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
;
4184 tmp_iax2info
->scallno
= ii
->scallno
;
4185 if (tmp_iax2info
->scallno
== 0) tmp_iax2info
->scallno
= ii
->dcallno
;
4186 tmp_iax2info
->callState
= ii
->callState
;
4188 callsinfo
->npackets
= 1;
4190 copy_address(&(callsinfo
->initial_speaker
), phone
);
4191 callsinfo
->from_identity
= g_strdup(ii
->callingParty
);
4192 callsinfo
->to_identity
= g_strdup(ii
->calledParty
);
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
;
4201 g_queue_push_tail(tapinfo
->callsinfos
, callsinfo
);
4204 callsinfo
->call_state
= ii
->callState
;
4206 callsinfo
->stop_fd
= pinfo
->fd
;
4207 callsinfo
->stop_rel_ts
= pinfo
->rel_ts
;
4208 ++(callsinfo
->npackets
);
4211 add_to_graph(tapinfo
, pinfo
, edt
, ii
->messageName
, "",
4212 callsinfo
->call_num
, &(pinfo
->src
), &(pinfo
->dst
), 1);
4214 tapinfo
->redraw
|= REDRAW_IAX2
;
4216 return TAP_PACKET_REDRAW
;
4220 /****************************************************************************/
4222 iax2_calls_draw(void *tap_offset_ptr
)
4224 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_iax2_
);
4226 if (tapinfo
->tap_draw
&& (tapinfo
->redraw
& REDRAW_IAX2
)) {
4227 tapinfo
->tap_draw(tapinfo
);
4228 tapinfo
->redraw
&= ~REDRAW_IAX2
;
4232 /****************************************************************************/
4234 /****************************************************************************/
4236 iax2_calls_init_tap(voip_calls_tapinfo_t
*tap_id_base
)
4238 GString
*error_string
;
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
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.
4249 error_string
= register_tap_listener("IAX2",
4250 tap_base_to_id(tap_id_base
, tap_id_offset_iax2_
),
4252 TL_REQUIRES_PROTO_TREE
,
4258 if (error_string
!= NULL
) {
4259 simple_dialog(ESD_TYPE_ERROR
, ESD_BTN_OK
, "%s",
4261 g_string_free(error_string
, TRUE
);
4265 /****************************************************************************/
4267 remove_tap_listener_iax2_calls(voip_calls_tapinfo_t
*tap_id_base
)
4269 remove_tap_listener(tap_base_to_id(tap_id_base
, tap_id_offset_iax2_
));
4272 /****************************************************************************/
4273 /* ***************************TAP for OTHER PROTOCOL **********************************/
4274 /****************************************************************************/
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
4278 voip_calls_packet(void *tap_offset_ptr
, packet_info
*pinfo
, epan_dissect_t
*edt
, const void *VoIPinfo
, tap_flags_t flags _U_
)
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
;
4284 const voip_packet_info_t
*pi
= (const voip_packet_info_t
*)VoIPinfo
;
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
;
4291 /* VOIP_CALLS_DEBUG("num %u", pinfo->num); */
4293 list
= g_queue_peek_nth_link(tapinfo
->callsinfos
, 0);
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
);
4302 list
= g_list_next(list
);
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
;
4321 callsinfo
->call_num
= tapinfo
->ncalls
++;
4322 callsinfo
->npackets
= 0;
4324 g_queue_push_tail(tapinfo
->callsinfos
, callsinfo
);
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
);
4336 callsinfo
->stop_fd
= pinfo
->fd
;
4337 callsinfo
->stop_rel_ts
= pinfo
->rel_ts
;
4338 ++(callsinfo
->npackets
);
4339 ++(tapinfo
->npackets
);
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);
4344 tapinfo
->redraw
|= REDRAW_VOIP
;
4346 return TAP_PACKET_REDRAW
;
4349 /****************************************************************************/
4351 voip_calls_draw(void *tap_offset_ptr
)
4353 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_voip_
);
4355 if (tapinfo
->tap_draw
&& (tapinfo
->redraw
& REDRAW_VOIP
)) {
4356 tapinfo
->tap_draw(tapinfo
);
4357 tapinfo
->redraw
&= ~REDRAW_VOIP
;
4361 /****************************************************************************/
4364 voip_calls_init_tap(voip_calls_tapinfo_t
*tap_id_base
)
4366 GString
*error_string
;
4368 error_string
= register_tap_listener("voip", tap_base_to_id(tap_id_base
, tap_id_offset_voip_
),
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
);
4384 /****************************************************************************/
4386 remove_tap_listener_voip_calls(voip_calls_tapinfo_t
*tap_id_base
)
4388 remove_tap_listener(tap_base_to_id(tap_id_base
, tap_id_offset_voip_
));
4391 /****************************************************************************/
4392 /* ***************************TAP for OTHER PROTOCOL **********************************/
4393 /****************************************************************************/
4395 /****************************************************************************/
4396 /* whenever a prot_ packet is seen by the tap listener */
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_
, tap_flags_t flags _U_
)
4401 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_prot_
);
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
;
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
);
4416 tapinfo
->redraw
= REDRAW_PROT
;
4418 return TAP_PACKET_REDRAW
;
4421 /****************************************************************************/
4423 prot_calls_draw(void *tap_offset_ptr
)
4425 voip_calls_tapinfo_t
*tapinfo
= tap_id_to_base(tap_offset_ptr
, tap_id_offset_prot_
);
4427 if (tapinfo
->tap_draw
&& (tapinfo
->redraw
& REDRAW_PROT
)) {
4428 tapinfo
->tap_draw(tapinfo
);
4429 tapinfo
->redraw
&= ~REDRAW_PROT
;
4433 /****************************************************************************/
4435 prot_calls_init_tap(voip_calls_tapinfo_t
*tap_id_base
)
4437 GString
*error_string
;
4439 error_string
= register_tap_listener("prot_", tap_base_to_id(tap_id_base
, tap_id_offset_prot_
),
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
);
4455 /****************************************************************************/
4457 remove_tap_listener_prot__calls(voip_calls_tapinfo_t
*tap_id_base
)
4459 remove_tap_listener(tap_base_to_id(tap_id_base
, tap_id_offset_prot_
));