2 * VoIP calls summary addition for ethereal
6 * Copyright 2004, Ericsson, Spain
7 * By Francisco Alcoba <francisco.alcoba@ericsson.com>
9 * based on h323_calls.c
10 * Copyright 2004, Iskratel, Ltd, Kranj
11 * By Miha Jemec <m.jemec@iskratel.si>
13 * H323, RTP and Graph Support
14 * By Alejandro Vaquero, alejandro.vaquero@verso.com
15 * Copyright 2005, Verso Technologies Inc.
17 * Ethereal - Network traffic analyzer
18 * By Gerald Combs <gerald@ethereal.com>
19 * Copyright 1998 Gerald Combs
21 * This program is free software; you can redistribute it and/or
22 * modify it under the terms of the GNU General Public License
23 * as published by the Free Software Foundation; either version 2
24 * of the License, or (at your option) any later version.
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
40 #include "graph_analysis.h"
41 #include "voip_calls.h"
42 #include "voip_calls_dlg.h"
43 #include "rtp_stream.h"
48 #include <epan/dissectors/packet-sip.h>
49 #include <epan/dissectors/packet-mtp3.h>
50 #include <epan/dissectors/packet-isup.h>
51 #include <epan/dissectors/packet-h225.h>
52 #include <epan/dissectors/packet-h245.h>
53 #include <epan/dissectors/packet-q931.h>
54 #include <epan/dissectors/packet-sdp.h>
55 #include <epan/dissectors/packet-rtp.h>
58 #include "alert_box.h"
59 #include "simple_dialog.h"
65 #ifdef HAVE_SYS_TYPES_H
66 # include <sys/types.h>
72 char *voip_call_state_name[6]={
81 /* defines whether we can consider the call active */
82 char *voip_protocol_name[3]={
90 /****************************************************************************/
91 /* the one and only global voip_calls_tapinfo_t structure */
92 static voip_calls_tapinfo_t the_tapinfo_struct =
93 {0, NULL, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0};
95 /* the one and only global voip_rtp_tapinfo_t structure */
96 static voip_rtp_tapinfo_t the_tapinfo_rtp_struct =
99 /****************************************************************************/
100 /* when there is a [re]reading of packet's */
101 void voip_calls_reset(voip_calls_tapinfo_t *tapinfo)
103 voip_calls_info_t *strinfo;
104 sip_calls_info_t *tmp_sipinfo;
105 h323_calls_info_t *tmp_h323info;
107 graph_analysis_item_t *graph_item;
112 /* free the data items first */
113 list = g_list_first(tapinfo->strinfo_list);
116 strinfo = list->data;
117 g_free(strinfo->from_identity);
118 g_free(strinfo->to_identity);
119 if (strinfo->protocol == VOIP_SIP){
120 tmp_sipinfo = strinfo->prot_info;
121 g_free(tmp_sipinfo->call_identifier);
123 if (strinfo->protocol == VOIP_H323){
124 tmp_h323info = strinfo->prot_info;
125 g_free(tmp_h323info->guid);
126 /* free the H245 list address */
127 list2 = g_list_first(tmp_h323info->h245_list);
131 list2 = g_list_next(list2);
133 g_list_free(tmp_h323info->h245_list);
134 tmp_h323info->h245_list = NULL;
136 g_free(strinfo->prot_info);
139 list = g_list_next(list);
141 g_list_free(tapinfo->strinfo_list);
142 tapinfo->strinfo_list = NULL;
144 tapinfo->npackets = 0;
145 tapinfo->start_packets = 0;
146 tapinfo->completed_calls = 0;
147 tapinfo->rejected_calls = 0;
149 /* free the graph data items first */
150 list = g_list_first(tapinfo->graph_analysis->list);
153 graph_item = list->data;
154 g_free(graph_item->frame_label);
155 g_free(graph_item->comment);
157 list = g_list_next(list);
159 g_list_free(tapinfo->graph_analysis->list);
160 tapinfo->graph_analysis->nconv = 0;
161 tapinfo->graph_analysis->list = NULL;
163 ++(tapinfo->launch_count);
168 /****************************************************************************/
169 void graph_analysis_data_init(void){
170 the_tapinfo_struct.graph_analysis = g_malloc(sizeof(graph_analysis_info_t));
171 the_tapinfo_struct.graph_analysis->nconv = 0;
172 the_tapinfo_struct.graph_analysis->list = NULL;
176 /****************************************************************************/
177 /* Add the RTP streams into the graph data */
180 * - reimplement this function
181 * This function does not work with VoIP taps
182 * which keep the window up to date.
183 * Either make rtp_stream() work without redissection or
184 * add an additional tap listener for rtp to this file.
185 * The second solution is cleaner and probably easier to implement,
186 * leaving the current rtp analysis feature untouched.
188 void add_rtp_streams_graph(void)
190 rtp_stream_info_t *strinfo;
194 GList* voip_calls_graph_list;
195 graph_analysis_item_t *gai;
196 graph_analysis_item_t *new_gai;
200 /* Scan for rtpstream */
203 /* assigne the RTP streams to calls */
205 strinfo_list = g_list_first(rtpstream_get_info()->strinfo_list);
208 strinfo = (rtp_stream_info_t*)(strinfo_list->data);
210 /* look in the voip calls graph list if there is a match for this RTP stream */
211 voip_calls_graph_list = g_list_first(the_tapinfo_struct.graph_analysis->list);
213 while (voip_calls_graph_list)
215 gai = voip_calls_graph_list->data;
216 conv_num = gai->conv_num;
217 if (strinfo->setup_frame_number == gai->frame_num){
218 while(voip_calls_graph_list){
219 gai = voip_calls_graph_list->data;
220 /* add the RTP item to the graph */
221 if (strinfo->first_frame_num<gai->frame_num){
222 new_gai = g_malloc(sizeof(graph_analysis_item_t));
223 new_gai->frame_num = strinfo->first_frame_num;
224 new_gai->time = (double)strinfo->start_rel_sec + (double)strinfo->start_rel_usec/1000000;
225 g_memmove(&new_gai->ip_src, strinfo->src_addr.data, 4);
226 g_memmove(&new_gai->ip_dst, strinfo->dest_addr.data, 4);
227 new_gai->port_src = strinfo->src_port;
228 new_gai->port_dst = strinfo->dest_port;
229 duration = (strinfo->stop_rel_sec*1000000 + strinfo->stop_rel_usec) - (strinfo->start_rel_sec*1000000 + strinfo->start_rel_usec);
230 new_gai->frame_label = g_strdup_printf("RTP (%s)", val_to_str(strinfo->pt, rtp_payload_type_short_vals, "%u"));
231 new_gai->comment = g_strdup_printf("RTP Num packets:%d Duration:%d.%03ds ssrc:%d", strinfo->npackets, duration/1000000,(duration%1000000)/1000, strinfo->ssrc);
232 new_gai->conv_num = conv_num;
233 new_gai->display=FALSE;
234 new_gai->line_style = 2; /* the arrow line will be 2 pixels width */
235 the_tapinfo_struct.graph_analysis->list = g_list_insert(the_tapinfo_struct.graph_analysis->list, new_gai, item);
239 voip_calls_graph_list = g_list_next(voip_calls_graph_list);
244 voip_calls_graph_list = g_list_next(voip_calls_graph_list);
247 strinfo_list = g_list_next(strinfo_list);
251 /****************************************************************************/
252 /* Add a new item into the graph */
253 int add_to_graph(voip_calls_tapinfo_t *tapinfo _U_, packet_info *pinfo, gchar *frame_label, gchar *comment, guint16 call_num)
255 graph_analysis_item_t *gai;
257 gai = g_malloc(sizeof(graph_analysis_item_t));
258 gai->frame_num = pinfo->fd->num;
259 gai->time= (double)pinfo->fd->rel_secs + (double) pinfo->fd->rel_usecs/1000000;
260 g_memmove(&gai->ip_src, pinfo->src.data, 4);
261 g_memmove(&gai->ip_dst, pinfo->dst.data, 4);
262 gai->port_src=pinfo->srcport;
263 gai->port_dst=pinfo->destport;
264 if (frame_label != NULL)
265 gai->frame_label = g_strdup(frame_label);
267 gai->frame_label = g_strdup("");
270 gai->comment = g_strdup(comment);
272 gai->comment = g_strdup("");
273 gai->conv_num=call_num;
277 tapinfo->graph_analysis->list = g_list_append(tapinfo->graph_analysis->list, gai);
283 /****************************************************************************/
284 /* Append str to frame_label and comment in a graph item */
285 /* return 0 if the frame_num is not in the graph list */
286 int append_to_frame_graph(voip_calls_tapinfo_t *tapinfo _U_, guint32 frame_num, const gchar *new_frame_label, const gchar *new_comment)
288 graph_analysis_item_t *gai;
290 gchar *tmp_str = NULL;
291 gchar *tmp_str2 = NULL;
293 list = g_list_first(tapinfo->graph_analysis->list);
297 if (gai->frame_num == frame_num){
298 tmp_str = gai->frame_label;
299 tmp_str2 = gai->comment;
301 if (new_frame_label != NULL){
302 gai->frame_label = g_strdup_printf("%s %s", gai->frame_label, new_frame_label);
307 if (new_comment != NULL){
308 gai->comment = g_strdup_printf("%s %s", gai->comment, new_comment);
313 list = g_list_next (list);
315 if (tmp_str == NULL) return 0; /* it is not in the list */
320 /****************************************************************************/
321 /* ***************************TAP for RTP **********************************/
322 /****************************************************************************/
324 /****************************************************************************/
325 /* when there is a [re]reading of RTP packet's */
326 void voip_rtp_reset(voip_rtp_tapinfo_t *tapinfo)
329 /* free the data items first */
330 list = g_list_first(tapinfo->list);
334 list = g_list_next(list);
336 g_list_free(tapinfo->list);
337 tapinfo->list = NULL;
338 tapinfo->nstreams = 0;
342 /****************************************************************************/
343 /* whenever a RTP packet is seen by the tap listener */
345 RTP_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *RTPinfo)
347 voip_rtp_tapinfo_t *tapinfo = &the_tapinfo_rtp_struct;
348 voip_rtp_stream_info_t *tmp_listinfo;
349 voip_rtp_stream_info_t *strinfo = NULL;
352 const struct _rtp_info *pi = RTPinfo;
354 /* do not consider RTP packets without a setup frame */
355 if (pi->info_setup_frame_num == 0){
359 /* check wether we already have a RTP stream with this setup frame and ssrc in the list */
360 list = g_list_first(tapinfo->list);
363 tmp_listinfo=list->data;
364 if ( (tmp_listinfo->setup_frame_number == pi->info_setup_frame_num) && (tmp_listinfo->ssrc == pi->info_sync_src) ){
365 strinfo = (voip_rtp_stream_info_t*)(list->data);
368 list = g_list_next (list);
371 /* not in the list? then create a new entry */
373 strinfo = g_malloc(sizeof(voip_rtp_stream_info_t));
374 COPY_ADDRESS(&(strinfo->src_addr), &(pinfo->src));
375 strinfo->src_port = pinfo->srcport;
376 COPY_ADDRESS(&(strinfo->dest_addr), &(pinfo->dst));
377 strinfo->dest_port = pinfo->destport;
378 strinfo->ssrc = pi->info_sync_src;
379 strinfo->pt = pi->info_payload_type;
380 strinfo->npackets = 0;
381 strinfo->first_frame_num = pinfo->fd->num;
382 strinfo->start_rel_sec = pinfo->fd->rel_secs;
383 strinfo->start_rel_usec = pinfo->fd->rel_usecs;
384 strinfo->setup_frame_number = pi->info_setup_frame_num;
385 tapinfo->list = g_list_append(tapinfo->list, strinfo);
389 /* Add the info to the existing RTP stream */
391 strinfo->stop_rel_sec = pinfo->fd->rel_secs;
392 strinfo->stop_rel_usec = pinfo->fd->rel_usecs;
397 /****************************************************************************/
398 /* whenever a redraw in the RTP tap listener */
399 void RTP_packet_draw(void *prs _U_)
401 voip_rtp_tapinfo_t *rtp_tapinfo = &the_tapinfo_rtp_struct;
402 GList* rtp_streams_list;
403 voip_rtp_stream_info_t *rtp_listinfo;
404 GList* voip_calls_graph_list;
406 graph_analysis_item_t *gai;
407 graph_analysis_item_t *new_gai;
411 /* add each rtp stream to the graph */
412 rtp_streams_list = g_list_first(rtp_tapinfo->list);
413 while (rtp_streams_list)
415 rtp_listinfo = rtp_streams_list->data;
417 /* using the setup frame number of the RTP stream, we get the call number that it belongs */
418 voip_calls_graph_list = g_list_first(the_tapinfo_struct.graph_analysis->list);
420 while (voip_calls_graph_list)
422 gai = voip_calls_graph_list->data;
423 conv_num = gai->conv_num;
424 /* if we get the setup frame number, then get the time position to graph the RTP arrow */
425 if (rtp_listinfo->setup_frame_number == gai->frame_num){
426 while(voip_calls_graph_list){
427 gai = voip_calls_graph_list->data;
428 /* if RTP was already in the Graph, just update the comment information */
429 if (rtp_listinfo->first_frame_num == gai->frame_num){
430 duration = (rtp_listinfo->stop_rel_sec*1000000 + rtp_listinfo->stop_rel_usec) - (rtp_listinfo->start_rel_sec*1000000 + rtp_listinfo->start_rel_usec);
431 g_free(gai->comment);
432 gai->comment = g_strdup_printf("RTP Num packets:%d Duration:%d.%03ds ssrc:%d", rtp_listinfo->npackets, duration/1000000,(duration%1000000)/1000, rtp_listinfo->ssrc);
434 /* add the RTP item to the graph if was not there*/
435 } else if (rtp_listinfo->first_frame_num<gai->frame_num){
436 new_gai = g_malloc(sizeof(graph_analysis_item_t));
437 new_gai->frame_num = rtp_listinfo->first_frame_num;
438 new_gai->time = (double)rtp_listinfo->start_rel_sec + (double)rtp_listinfo->start_rel_usec/1000000;
439 g_memmove(&new_gai->ip_src, rtp_listinfo->src_addr.data, 4);
440 g_memmove(&new_gai->ip_dst, rtp_listinfo->dest_addr.data, 4);
441 new_gai->port_src = rtp_listinfo->src_port;
442 new_gai->port_dst = rtp_listinfo->dest_port;
443 duration = (rtp_listinfo->stop_rel_sec*1000000 + rtp_listinfo->stop_rel_usec) - (rtp_listinfo->start_rel_sec*1000000 + rtp_listinfo->start_rel_usec);
444 new_gai->frame_label = g_strdup_printf("RTP (%s)", val_to_str(rtp_listinfo->pt, rtp_payload_type_short_vals, "%u"));
445 new_gai->comment = g_strdup_printf("RTP Num packets:%d Duration:%d.%03ds ssrc:%d", rtp_listinfo->npackets, duration/1000000,(duration%1000000)/1000, rtp_listinfo->ssrc);
446 new_gai->conv_num = conv_num;
447 new_gai->display=FALSE;
448 new_gai->line_style = 2; /* the arrow line will be 2 pixels width */
449 the_tapinfo_struct.graph_analysis->list = g_list_insert(the_tapinfo_struct.graph_analysis->list, new_gai, item);
453 voip_calls_graph_list = g_list_next(voip_calls_graph_list);
458 voip_calls_graph_list = g_list_next(voip_calls_graph_list);
461 rtp_streams_list = g_list_next(rtp_streams_list);
465 static gboolean have_RTP_tap_listener=FALSE;
466 /****************************************************************************/
470 GString *error_string;
472 if(have_RTP_tap_listener==FALSE)
474 /* don't register tap listener, if we have it already */
475 error_string = register_tap_listener("rtp", &(the_tapinfo_rtp_struct), NULL,
480 if (error_string != NULL) {
481 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
483 g_string_free(error_string, TRUE);
486 have_RTP_tap_listener=TRUE;
492 /* XXX just copied from gtk/rpc_stat.c */
493 void protect_thread_critical_region(void);
494 void unprotect_thread_critical_region(void);
496 /****************************************************************************/
498 remove_tap_listener_rtp(void)
500 protect_thread_critical_region();
501 remove_tap_listener(&(the_tapinfo_rtp_struct.rtp_dummy));
502 unprotect_thread_critical_region();
504 have_RTP_tap_listener=FALSE;
507 /****************************************************************************/
508 /* ***************************TAP for SIP **********************************/
509 /****************************************************************************/
511 /****************************************************************************/
512 /* whenever a SIP packet is seen by the tap listener */
514 SIPcalls_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *SIPinfo)
516 voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
517 /* we just take note of the ISUP data here; when we receive the MTP3 part everything will
518 be compared with existing calls */
520 voip_calls_info_t *tmp_listinfo;
521 voip_calls_info_t *strinfo = NULL;
522 sip_calls_info_t *tmp_sipinfo;
524 guint32 tmp_src, tmp_dst;
525 gchar *frame_label = NULL;
526 gchar *comment = NULL;
528 const sip_info_value_t *pi = SIPinfo;
530 /* do not consider packets without call_id */
531 if (pi->tap_call_id ==NULL){
535 /* check wether we already have a call with these parameters in the list */
536 list = g_list_first(tapinfo->strinfo_list);
539 tmp_listinfo=list->data;
540 if (tmp_listinfo->protocol == VOIP_SIP){
541 tmp_sipinfo = tmp_listinfo->prot_info;
542 if (strcmp(tmp_sipinfo->call_identifier,pi->tap_call_id)==0){
543 strinfo = (voip_calls_info_t*)(list->data);
547 list = g_list_next (list);
550 /* not in the list? then create a new entry if the message is INVITE -i.e. if this session is a call*/
551 if ((strinfo==NULL) &&(pi->request_method!=NULL)){
552 if (strcmp(pi->request_method,"INVITE")==0){
553 strinfo = g_malloc(sizeof(voip_calls_info_t));
554 strinfo->call_active_state = VOIP_ACTIVE;
555 strinfo->call_state = VOIP_CALL_SETUP;
556 strinfo->from_identity=g_strdup(pi->tap_from_addr);
557 strinfo->to_identity=g_strdup(pi->tap_to_addr);
558 g_memmove(&(strinfo->initial_speaker), pinfo->src.data, 4);
559 strinfo->first_frame_num=pinfo->fd->num;
560 strinfo->selected=FALSE;
561 strinfo->start_sec=pinfo->fd->rel_secs;
562 strinfo->start_usec=pinfo->fd->rel_usecs;
563 strinfo->protocol=VOIP_SIP;
564 strinfo->prot_info=g_malloc(sizeof(sip_calls_info_t));
565 tmp_sipinfo=strinfo->prot_info;
566 tmp_sipinfo->call_identifier=strdup(pi->tap_call_id);
567 tmp_sipinfo->sip_state=SIP_INVITE_SENT;
568 tmp_sipinfo->invite_cseq=pi->tap_cseq_number;
569 strinfo->npackets = 0;
570 strinfo->call_num = tapinfo->ncalls++;
571 tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);
575 g_free(pi->tap_from_addr);
576 g_free(pi->tap_to_addr);
577 g_free(pi->tap_call_id);
581 /* let's analyze the call state */
583 g_memmove(&(tmp_src), pinfo->src.data, 4);
584 g_memmove(&(tmp_dst), pinfo->dst.data, 4);
586 if (pi->request_method == NULL){
587 frame_label = g_strdup_printf("%d %s", pi->response_code, pi->reason_phrase );
588 comment = g_strdup_printf("SIP Status");
590 if ((pi->tap_cseq_number == tmp_sipinfo->invite_cseq)&&(tmp_dst==strinfo->initial_speaker)){
591 if ((pi->response_code > 199) && (pi->response_code<300) && (tmp_sipinfo->sip_state == SIP_INVITE_SENT)){
592 tmp_sipinfo->sip_state = SIP_200_REC;
594 else if ((pi->response_code>299)&&(tmp_sipinfo->sip_state == SIP_INVITE_SENT)){
595 strinfo->call_state = VOIP_REJECTED;
596 tapinfo->rejected_calls++;
602 frame_label = g_strdup(pi->request_method);
604 if ((strcmp(pi->request_method,"INVITE")==0)&&(tmp_src == strinfo->initial_speaker)){
605 tmp_sipinfo->invite_cseq = pi->tap_cseq_number;
606 comment = g_strdup_printf("SIP From: %s To:%s", strinfo->from_identity, strinfo->to_identity);
608 else if ((strcmp(pi->request_method,"ACK")==0)&&(pi->tap_cseq_number == tmp_sipinfo->invite_cseq)
609 &&(tmp_src == strinfo->initial_speaker)&&(tmp_sipinfo->sip_state==SIP_200_REC)){
610 strinfo->call_state = VOIP_IN_CALL;
611 comment = g_strdup_printf("SIP Request");
613 else if (strcmp(pi->request_method,"BYE")==0){
614 strinfo->call_state = VOIP_COMPLETED;
615 tapinfo->completed_calls++;
616 comment = g_strdup_printf("SIP Request");
618 else if ((strcmp(pi->request_method,"CANCEL")==0)&&(pi->tap_cseq_number == tmp_sipinfo->invite_cseq)
619 &&(tmp_src == strinfo->initial_speaker)&&(strinfo->call_state==VOIP_CALL_SETUP)){
620 strinfo->call_state = VOIP_CANCELLED;
621 tmp_sipinfo->sip_state = SIP_CANCEL_SENT;
622 comment = g_strdup_printf("SIP Request");
624 comment = g_strdup_printf("SIP Request");
628 strinfo->stop_sec=pinfo->fd->rel_secs;
629 strinfo->stop_usec=pinfo->fd->rel_usecs;
630 strinfo->last_frame_num=pinfo->fd->num;
631 ++(strinfo->npackets);
632 /* increment the packets counter of all calls */
633 ++(tapinfo->npackets);
635 /* add to the graph */
636 add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num);
640 return 1; /* refresh output */
644 /****************************************************************************/
645 const voip_calls_tapinfo_t* voip_calls_get_info(void)
647 return &the_tapinfo_struct;
651 /****************************************************************************/
653 /****************************************************************************/
654 static gboolean have_SIP_tap_listener=FALSE;
655 /****************************************************************************/
657 sip_calls_init_tap(void)
659 GString *error_string;
661 if(have_SIP_tap_listener==FALSE)
663 /* don't register tap listener, if we have it already */
664 error_string = register_tap_listener("sip", &(the_tapinfo_struct.sip_dummy), NULL,
665 voip_calls_dlg_reset,
669 if (error_string != NULL) {
670 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
672 g_string_free(error_string, TRUE);
675 have_SIP_tap_listener=TRUE;
681 /* XXX just copied from gtk/rpc_stat.c */
682 void protect_thread_critical_region(void);
683 void unprotect_thread_critical_region(void);
685 /****************************************************************************/
687 remove_tap_listener_sip_calls(void)
689 protect_thread_critical_region();
690 remove_tap_listener(&(the_tapinfo_struct.sip_dummy));
691 unprotect_thread_critical_region();
693 have_SIP_tap_listener=FALSE;
696 /****************************************************************************/
697 /* ***************************TAP for ISUP **********************************/
698 /****************************************************************************/
700 static gchar isup_called_number[255], isup_calling_number[255];
701 static guint16 isup_cic;
702 static guint8 isup_message_type;
703 static guint8 isup_cause_value;
705 /****************************************************************************/
706 /* whenever a isup_ packet is seen by the tap listener */
708 isup_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *isup_info _U_)
710 voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
711 const isup_tap_rec_t *pi = isup_info;
713 if (pi->calling_number!=NULL){
714 strcpy(isup_calling_number, pi->calling_number);
716 if (pi->called_number!=NULL){
717 strcpy(isup_called_number, pi->called_number);
719 isup_message_type = pi->message_type;
720 isup_cause_value = pi->cause_value;
721 isup_cic = pinfo->circuit_id;
726 /****************************************************************************/
728 static gboolean have_isup_tap_listener=FALSE;
731 isup_calls_init_tap(void)
733 GString *error_string;
736 if(have_isup_tap_listener==FALSE)
738 error_string = register_tap_listener("isup", &(the_tapinfo_struct.isup_dummy),
740 voip_calls_dlg_reset,
745 if (error_string != NULL) {
746 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
748 g_string_free(error_string, TRUE);
751 have_isup_tap_listener=TRUE;
755 /****************************************************************************/
758 remove_tap_listener_isup_calls(void)
760 protect_thread_critical_region();
761 remove_tap_listener(&(the_tapinfo_struct.isup_dummy));
762 unprotect_thread_critical_region();
764 have_isup_tap_listener=FALSE;
768 /****************************************************************************/
769 /* ***************************TAP for MTP3 **********************************/
770 /****************************************************************************/
773 /****************************************************************************/
774 /* whenever a mtp3_ packet is seen by the tap listener */
776 mtp3_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *mtp3_info _U_)
778 voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
779 voip_calls_info_t *tmp_listinfo;
780 voip_calls_info_t *strinfo = NULL;
781 isup_calls_info_t *tmp_isupinfo;
782 gboolean found = FALSE;
784 gboolean right_pair = TRUE;
786 gchar *frame_label = NULL;
787 gchar *comment = NULL;
790 const mtp3_tap_rec_t *pi = mtp3_info;
792 /* check wether we already have a call with these parameters in the list */
793 list = g_list_first(tapinfo->strinfo_list);
796 tmp_listinfo=list->data;
797 if ((tmp_listinfo->protocol == VOIP_ISUP)&&(tmp_listinfo->call_active_state==VOIP_ACTIVE)){
798 tmp_isupinfo = tmp_listinfo->prot_info;
799 if ((tmp_isupinfo->cic == isup_cic)&&(tmp_isupinfo->ni == pi->addr_opc.ni)){
800 if ((tmp_isupinfo->opc == pi->addr_opc.pc)&&(tmp_isupinfo->dpc == pi->addr_dpc.pc)){
803 else if ((tmp_isupinfo->dpc == pi->addr_opc.pc)&&(tmp_isupinfo->opc == pi->addr_dpc.pc)){
810 /* if there is an IAM for a call that is not in setup state, that means the previous call in the same
811 cic is no longer active */
812 if (tmp_listinfo->call_state == VOIP_CALL_SETUP){
815 else if (isup_message_type != 1){
819 tmp_listinfo->call_active_state=VOIP_INACTIVE;
823 strinfo = (voip_calls_info_t*)(list->data);
828 list = g_list_next (list);
831 /* not in the list? then create a new entry if the message is IAM
832 -i.e. if this session is a call*/
835 if ((strinfo==NULL) &&(isup_message_type==1)){
837 strinfo = g_malloc(sizeof(voip_calls_info_t));
838 strinfo->call_active_state = VOIP_ACTIVE;
839 strinfo->call_state = VOIP_UNKNOWN;
840 g_memmove(&(strinfo->initial_speaker), pinfo->src.data, 4);
841 strinfo->selected=FALSE;
842 strinfo->first_frame_num=pinfo->fd->num;
843 strinfo->start_sec=pinfo->fd->rel_secs;
844 strinfo->start_usec=pinfo->fd->rel_usecs;
845 strinfo->protocol=VOIP_ISUP;
846 strinfo->from_identity=g_strdup(isup_calling_number);
847 strinfo->to_identity=g_strdup(isup_called_number);
848 strinfo->prot_info=g_malloc(sizeof(isup_calls_info_t));
849 tmp_isupinfo=strinfo->prot_info;
850 tmp_isupinfo->opc = pi->addr_opc.pc;
851 tmp_isupinfo->dpc = pi->addr_dpc.pc;
852 tmp_isupinfo->ni = pi->addr_opc.ni;
853 tmp_isupinfo->cic = pinfo->circuit_id;
854 strinfo->npackets = 0;
855 strinfo->call_num = tapinfo->ncalls++;
856 tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);
860 strinfo->stop_sec=pinfo->fd->rel_secs;
861 strinfo->stop_usec=pinfo->fd->rel_usecs;
862 strinfo->last_frame_num=pinfo->fd->num;
863 ++(strinfo->npackets);
865 /* Let's analyze the call state */
868 for (i=0;(isup_message_type_value[i].strptr!=NULL)&& (isup_message_type_value[i].value!=isup_message_type);i++);
870 if (isup_message_type_value[i].value==isup_message_type){
871 frame_label = g_strdup(isup_message_type_value_acro[i].strptr);
874 frame_label = g_strdup_printf("Unknown");
877 if (strinfo->npackets == 1){ /* this is the first packet, that must be an IAM */
878 comment = g_strdup_printf("Call from %s to %s",
879 isup_calling_number, isup_called_number);
881 else if (strinfo->npackets == 2){ /* in the second packet we show the SPs */
883 comment = g_strdup_printf("%i-%i -> %i-%i. Cic:%i",
884 pi->addr_opc.ni, pi->addr_opc.pc,
885 pi->addr_opc.ni, pi->addr_dpc.pc, pinfo->circuit_id);
889 comment = g_strdup_printf("%i-%i -> %i-%i. Cic:%i",
890 pi->addr_opc.ni, pi->addr_dpc.pc,
891 pi->addr_opc.ni, pi->addr_opc.pc, pinfo->circuit_id);
896 switch(isup_message_type){
898 strinfo->call_state=VOIP_CALL_SETUP;
900 case 7: /* CONNECT */
902 strinfo->call_state=VOIP_IN_CALL;
904 case 12: /* RELEASE */
905 if (strinfo->call_state==VOIP_CALL_SETUP){
907 strinfo->call_state=VOIP_CANCELLED;
910 strinfo->call_state=VOIP_REJECTED;
911 tapinfo->rejected_calls++;
914 else if (strinfo->call_state == VOIP_IN_CALL){
915 strinfo->call_state = VOIP_COMPLETED;
916 tapinfo->completed_calls++;
918 for (i=0;(q931_cause_code_vals[i].strptr!=NULL)&& (q931_cause_code_vals[i].value!=isup_cause_value);i++);
919 if (q931_cause_code_vals[i].value==isup_cause_value){
920 comment = g_strdup_printf("Cause %i - %s",isup_cause_value, q931_cause_code_vals[i].strptr);
923 comment = g_strdup_printf("Cause %i",isup_cause_value);
928 /* increment the packets counter of all calls */
929 ++(tapinfo->npackets);
931 /* add to the graph */
932 add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num);
941 /****************************************************************************/
943 static gboolean have_mtp3_tap_listener=FALSE;
946 mtp3_calls_init_tap(void)
948 GString *error_string;
951 if(have_mtp3_tap_listener==FALSE)
953 error_string = register_tap_listener("mtp3", &(the_tapinfo_struct.mtp3_dummy),
955 voip_calls_dlg_reset,
960 if (error_string != NULL) {
961 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
963 g_string_free(error_string, TRUE);
966 have_mtp3_tap_listener=TRUE;
970 /****************************************************************************/
973 remove_tap_listener_mtp3_calls(void)
975 protect_thread_critical_region();
976 remove_tap_listener(&(the_tapinfo_struct.mtp3_dummy));
977 unprotect_thread_critical_region();
979 have_mtp3_tap_listener=FALSE;
982 /****************************************************************************/
983 /* ***************************TAP for Q931 **********************************/
984 /****************************************************************************/
986 static gchar *q931_calling_number;
987 static gchar *q931_called_number;
988 static guint8 q931_cause_value;
989 static gint32 q931_crv;
990 static guint32 q931_frame_num;
992 /****************************************************************************/
993 /* whenever a q931_ packet is seen by the tap listener */
995 q931_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *q931_info _U_)
997 voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
998 const q931_packet_info *pi = q931_info;
1000 /* free previously allocated q931_calling/ed_number */
1001 g_free(q931_calling_number);
1002 g_free(q931_called_number);
1004 if (pi->calling_number!=NULL)
1005 q931_calling_number = g_strdup(pi->calling_number);
1007 q931_calling_number = g_strdup("");
1009 if (pi->called_number!=NULL)
1010 q931_called_number = g_strdup(pi->called_number);
1012 q931_called_number = g_strdup("");
1013 q931_cause_value = pi->cause_value;
1014 q931_frame_num = pinfo->fd->num;
1020 /****************************************************************************/
1021 static gboolean have_q931_tap_listener=FALSE;
1024 q931_calls_init_tap(void)
1026 GString *error_string;
1029 if(have_q931_tap_listener==FALSE)
1031 error_string = register_tap_listener("q931", &(the_tapinfo_struct.q931_dummy),
1033 voip_calls_dlg_reset,
1038 if (error_string != NULL) {
1039 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1041 g_string_free(error_string, TRUE);
1044 have_q931_tap_listener=TRUE;
1048 /****************************************************************************/
1051 remove_tap_listener_q931_calls(void)
1053 protect_thread_critical_region();
1054 remove_tap_listener(&(the_tapinfo_struct.q931_dummy));
1055 unprotect_thread_critical_region();
1057 have_q931_tap_listener=FALSE;
1060 /****************************************************************************/
1061 /****************************TAP for H323 ***********************************/
1062 /****************************************************************************/
1065 static const guint8 guid_allzero[GUID_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1066 /* defines specific H323 data */
1068 void add_h245_Address(h323_calls_info_t *h323info, guint32 h245_address, guint16 h245_port)
1070 h245_address_t *h245_add = NULL;
1072 h245_add = g_malloc(sizeof(h245_address_t));
1073 h245_add->h245_address = h245_address;
1074 h245_add->h245_port = h245_port;
1076 h323info->h245_list = g_list_append(h323info->h245_list, h245_add);
1079 /****************************************************************************/
1080 /* whenever a H225 packet is seen by the tap listener */
1082 H225calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *H225info)
1084 voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
1085 voip_calls_info_t *tmp_listinfo;
1086 voip_calls_info_t *strinfo = NULL;
1087 h323_calls_info_t *tmp_h323info;
1091 guint32 tmp_src, tmp_dst;
1093 const h225_packet_info *pi = H225info;
1095 /* if not guid and RAS return because did not belong to a call */
1096 if ((memcmp(pi->guid, guid_allzero, GUID_LEN) == 0) && (pi->msg_type == H225_RAS))
1100 if ( (memcmp(pi->guid, guid_allzero, GUID_LEN) == 0) && (q931_frame_num == pinfo->fd->num) ){
1101 /* check wether we already have a call with this Q931 CRV */
1102 list = g_list_first(tapinfo->strinfo_list);
1105 tmp_listinfo=list->data;
1106 if (tmp_listinfo->protocol == VOIP_H323){
1107 tmp_h323info = tmp_listinfo->prot_info;
1108 if ( ((tmp_h323info->q931_crv == q931_crv) || (tmp_h323info->q931_crv2 == q931_crv)) && (q931_crv!=-1)){
1109 strinfo = (voip_calls_info_t*)(list->data);
1113 list = g_list_next (list);
1115 if (strinfo==NULL) return 0;
1117 /* check wether we already have a call with this guid in the list */
1118 list = g_list_first(tapinfo->strinfo_list);
1121 tmp_listinfo=list->data;
1122 if (tmp_listinfo->protocol == VOIP_H323){
1123 tmp_h323info = tmp_listinfo->prot_info;
1124 if (memcmp(tmp_h323info->guid, pi->guid,GUID_LEN)==0){
1125 strinfo = (voip_calls_info_t*)(list->data);
1129 list = g_list_next (list);
1133 /* not in the list? then create a new entry */
1134 if ((strinfo==NULL)){
1135 strinfo = g_malloc(sizeof(voip_calls_info_t));
1136 strinfo->call_active_state = VOIP_ACTIVE;
1137 strinfo->call_state = VOIP_UNKNOWN;
1138 strinfo->from_identity=g_strdup("");
1139 strinfo->to_identity=g_strdup("");
1141 g_memmove(&(strinfo->initial_speaker), pinfo->src.data,4);
1142 strinfo->selected=FALSE;
1143 strinfo->first_frame_num=pinfo->fd->num;
1144 strinfo->start_sec=pinfo->fd->rel_secs;
1145 strinfo->start_usec=pinfo->fd->rel_usecs;
1146 strinfo->protocol=VOIP_H323;
1147 strinfo->prot_info=g_malloc(sizeof(h323_calls_info_t));
1148 tmp_h323info = strinfo->prot_info;
1149 tmp_h323info->guid = (guint8 *) g_memdup(pi->guid,GUID_LEN);
1150 tmp_h323info->h225SetupAddr = 0;
1151 tmp_h323info->h245_list = NULL;
1152 tmp_h323info->is_faststart_Setup = FALSE;
1153 tmp_h323info->is_faststart_Proc = FALSE;
1154 tmp_h323info->is_h245Tunneling = FALSE;
1155 tmp_h323info->is_h245 = FALSE;
1156 tmp_h323info->q931_crv = -1;
1157 tmp_h323info->q931_crv2 = -1;
1158 strinfo->call_num = tapinfo->ncalls++;
1159 strinfo->npackets = 0;
1161 tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);
1166 /* let's analyze the call state */
1168 g_memmove(&(tmp_src), pinfo->src.data, 4);
1169 g_memmove(&(tmp_dst), pinfo->dst.data, 4);
1171 strinfo->stop_sec=pinfo->fd->rel_secs;
1172 strinfo->stop_usec=pinfo->fd->rel_usecs;
1173 strinfo->last_frame_num=pinfo->fd->num;
1174 ++(strinfo->npackets);
1175 /* increment the packets counter of all calls */
1176 ++(tapinfo->npackets);
1178 /* change the status */
1179 if (pi->msg_type == H225_CS){
1180 if (tmp_h323info->q931_crv == -1) {
1181 tmp_h323info->q931_crv = q931_crv;
1182 } else if (tmp_h323info->q931_crv != q931_crv) {
1183 tmp_h323info->q931_crv2 = q931_crv;
1186 if (pi->is_h245 == TRUE){
1187 add_h245_Address(tmp_h323info, pi->h245_address, pi->h245_port);
1190 if (pi->cs_type != H225_RELEASE_COMPLET) tmp_h323info->is_h245Tunneling = pi->is_h245Tunneling;
1192 frame_label = g_strdup(pi->frame_label);
1194 switch(pi->cs_type){
1196 tmp_h323info->is_faststart_Setup = pi->is_faststart;
1198 /* set te calling and called number from the Q931 packet */
1199 if (q931_frame_num == pinfo->fd->num){
1200 if (q931_calling_number != NULL){
1201 g_free(strinfo->from_identity);
1202 strinfo->from_identity=g_strdup(q931_calling_number);
1204 if (q931_called_number != NULL){
1205 g_free(strinfo->to_identity);
1206 strinfo->to_identity=g_strdup(q931_called_number);
1209 if (tmp_h323info->h225SetupAddr == 0) g_memmove(&(tmp_h323info->h225SetupAddr), pinfo->src.data,4);
1210 strinfo->call_state=VOIP_CALL_SETUP;
1211 comment = g_strdup_printf("H225 From: %s To:%s TunnH245:%s FS:%s", strinfo->from_identity, strinfo->to_identity, (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
1212 (pi->is_faststart==TRUE?"on":"off"));
1215 strinfo->call_state=VOIP_IN_CALL;
1216 if (pi->is_faststart == TRUE) tmp_h323info->is_faststart_Proc = TRUE;
1217 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
1218 (pi->is_faststart==TRUE?"on":"off"));
1220 case H225_RELEASE_COMPLET:
1221 g_memmove(&(tmp_src), pinfo->src.data, 4);
1222 if (strinfo->call_state==VOIP_CALL_SETUP){
1223 if (tmp_h323info->h225SetupAddr == tmp_src){ /* forward direction */
1224 strinfo->call_state=VOIP_CANCELLED;
1227 strinfo->call_state=VOIP_REJECTED;
1228 tapinfo->rejected_calls++;
1231 else if (strinfo->call_state == VOIP_IN_CALL){
1232 strinfo->call_state = VOIP_COMPLETED;
1233 tapinfo->completed_calls++;
1235 /* get the Q931 Release cause code */
1236 if (q931_frame_num == pinfo->fd->num &&
1237 q931_cause_value != 0xFF){
1238 comment = g_strdup_printf("H225 Q931 Rel Cause (%i):%s", q931_cause_value, val_to_str(q931_cause_value, q931_cause_code_vals, "<unknown>"));
1239 } else { /* Cause not set */
1240 comment = g_strdup("H225 No Q931 Rel Cause");
1245 case H225_CALL_PROCEDING:
1246 if (pi->is_faststart == TRUE) tmp_h323info->is_faststart_Proc = TRUE;
1247 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
1248 (pi->is_faststart==TRUE?"on":"off"));
1251 comment = g_strdup_printf("H225 TunnH245:%s FS:%s", (tmp_h323info->is_h245Tunneling==TRUE?"on":"off"),
1252 (pi->is_faststart==TRUE?"on":"off"));
1255 } else if (pi->msg_type == H225_RAS){
1256 frame_label = g_strdup_printf("%s", val_to_str(pi->msg_tag, RasMessage_vals, "<unknown>"));
1257 comment = g_strdup("H225 RAS");
1259 frame_label = g_strdup("H225: Unknown");
1260 comment = g_strdup("");
1263 /* add to graph analysis */
1264 if (!append_to_frame_graph(tapinfo, pinfo->fd->num, pi->frame_label, comment)) /* if the frame number exists in graph, append to it*/
1265 add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num); /* if not exist, add to the graph */
1267 g_free(frame_label);
1271 return 1; /* refresh output */
1275 /****************************************************************************/
1277 /****************************************************************************/
1278 static gboolean have_H225_tap_listener=FALSE;
1279 /****************************************************************************/
1281 h225_calls_init_tap(void)
1283 GString *error_string;
1285 if(have_H225_tap_listener==FALSE)
1287 /* don't register tap listener, if we have it already */
1288 error_string = register_tap_listener("h225", &(the_tapinfo_struct.h225_dummy), NULL,
1289 voip_calls_dlg_reset,
1294 if (error_string != NULL) {
1295 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1297 g_string_free(error_string, TRUE);
1300 have_H225_tap_listener=TRUE;
1306 /* XXX just copied from gtk/rpc_stat.c */
1307 void protect_thread_critical_region(void);
1308 void unprotect_thread_critical_region(void);
1310 /****************************************************************************/
1312 remove_tap_listener_h225_calls(void)
1314 protect_thread_critical_region();
1315 remove_tap_listener(&(the_tapinfo_struct.h225_dummy));
1316 unprotect_thread_critical_region();
1318 have_H225_tap_listener=FALSE;
1322 /****************************************************************************/
1323 /* whenever a H245dg packet is seen by the tap listener (when H245 tunneling is ON) */
1325 H245dgcalls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *H245info)
1327 voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
1328 voip_calls_info_t *tmp_listinfo;
1329 voip_calls_info_t *strinfo = NULL;
1330 h323_calls_info_t *tmp_h323info;
1335 guint32 tmp_src, tmp_dst;
1336 h245_address_t *h245_add = NULL;
1338 const h245_packet_info *pi = H245info;
1340 /* if H245 tunneling is on, append to graph */
1341 if (append_to_frame_graph(tapinfo, pinfo->fd->num, pi->frame_label, pi->comment)) return 1;
1344 /* it is not Tunneling or it is not in the list. So check if there is no tunneling
1345 and there is a call with this H245 address */
1346 list = g_list_first(tapinfo->strinfo_list);
1349 tmp_listinfo=list->data;
1350 if (tmp_listinfo->protocol == VOIP_H323){
1351 tmp_h323info = tmp_listinfo->prot_info;
1353 g_memmove(&(tmp_src), pinfo->src.data, 4);
1354 g_memmove(&(tmp_dst), pinfo->dst.data, 4);
1355 list2 = g_list_first(tmp_h323info->h245_list);
1358 h245_add=list2->data;
1359 if ( ((h245_add->h245_address == tmp_src) && (h245_add->h245_port == pinfo->srcport))
1360 || ((h245_add->h245_address == tmp_dst) && (h245_add->h245_port == pinfo->destport)) ){
1361 strinfo = (voip_calls_info_t*)(list->data);
1363 ++(strinfo->npackets);
1364 /* increment the packets counter of all calls */
1365 ++(tapinfo->npackets);
1369 list2 = g_list_next(list2);
1371 if (strinfo!=NULL) break;
1373 list = g_list_next(list);
1377 frame_label = g_strdup(pi->frame_label);
1378 comment = g_strdup(pi->comment);
1379 add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num);
1380 g_free(frame_label);
1384 return 1; /* refresh output */
1388 /****************************************************************************/
1390 /****************************************************************************/
1391 static gboolean have_H245dg_tap_listener=FALSE;
1392 /****************************************************************************/
1394 h245dg_calls_init_tap(void)
1396 GString *error_string;
1398 if(have_H245dg_tap_listener==FALSE)
1400 /* don't register tap listener, if we have it already */
1401 error_string = register_tap_listener("h245dg", &(the_tapinfo_struct.h245dg_dummy), NULL,
1402 voip_calls_dlg_reset,
1407 if (error_string != NULL) {
1408 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1410 g_string_free(error_string, TRUE);
1413 have_H245dg_tap_listener=TRUE;
1418 /* XXX just copied from gtk/rpc_stat.c */
1419 void protect_thread_critical_region(void);
1420 void unprotect_thread_critical_region(void);
1422 /****************************************************************************/
1424 remove_tap_listener_h245dg_calls(void)
1426 protect_thread_critical_region();
1427 remove_tap_listener(&(the_tapinfo_struct.h245dg_dummy));
1428 unprotect_thread_critical_region();
1430 have_H245dg_tap_listener=FALSE;
1434 /****************************************************************************/
1435 /****************************TAP for SDP PROTOCOL ***************************/
1436 /****************************************************************************/
1437 /* whenever a SDP packet is seen by the tap listener */
1439 SDPcalls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *SDPinfo)
1441 voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
1442 const sdp_packet_info *pi = SDPinfo;
1443 char summary_str[50];
1445 /* Append to graph the SDP summary if the packet exists */
1446 g_snprintf(summary_str, 50, "SDP (%s)", pi->summary_str);
1447 append_to_frame_graph(tapinfo, pinfo->fd->num, summary_str, NULL);
1449 return 1; /* refresh output */
1453 /****************************************************************************/
1455 /****************************************************************************/
1456 static gboolean have_sdp_tap_listener=FALSE;
1457 /****************************************************************************/
1459 sdp_calls_init_tap(void)
1461 GString *error_string;
1463 if(have_sdp_tap_listener==FALSE)
1465 /* don't register tap listener, if we have it already */
1466 error_string = register_tap_listener("sdp", &(the_tapinfo_struct.sdp_dummy), NULL,
1467 voip_calls_dlg_reset,
1472 if (error_string != NULL) {
1473 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1475 g_string_free(error_string, TRUE);
1478 have_sdp_tap_listener=TRUE;
1483 /* XXX just copied from gtk/rpc_stat.c */
1484 void protect_thread_critical_region(void);
1485 void unprotect_thread_critical_region(void);
1487 /****************************************************************************/
1489 remove_tap_listener_sdp_calls(void)
1491 protect_thread_critical_region();
1492 remove_tap_listener(&(the_tapinfo_struct.sdp_dummy));
1493 unprotect_thread_critical_region();
1495 have_sdp_tap_listener=FALSE;
1502 /****************************************************************************/
1503 /* ***************************TAP for OTHER PROTOCOL **********************************/
1504 /****************************************************************************/
1506 /****************************************************************************/
1507 /* whenever a prot_ packet is seen by the tap listener */
1510 prot_calls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prot_info _U_)
1512 voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
1514 strinfo->stop_sec=pinfo->fd->rel_secs;
1515 strinfo->stop_usec=pinfo->fd->rel_usecs;
1516 strinfo->last_frame_num=pinfo->fd->num;
1517 ++(strinfo->npackets);
1518 ++(tapinfo->npackets);
1524 /****************************************************************************/
1526 static gboolean have_prot__tap_listener=FALSE;
1529 prot_calls_init_tap(void)
1531 GString *error_string;
1533 if(have_prot__tap_listener==FALSE)
1535 error_string = register_tap_listener("prot_", &(the_tapinfo_struct.prot__dummy),
1537 voip_calls_dlg_reset,
1542 if (error_string != NULL) {
1543 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1545 g_string_free(error_string, TRUE);
1548 have_prot__tap_listener=TRUE;
1552 /****************************************************************************/
1555 remove_tap_listener_prot__calls(void)
1557 protect_thread_critical_region();
1558 remove_tap_listener(&(the_tapinfo_struct.prot__dummy));
1559 unprotect_thread_critical_region();
1561 have_prot__tap_listener=FALSE;