Fix ex "modeline" so it works;
[obnox/wireshark/wip.git] / gtk / rtp_stream.c
1 /* rtp_stream.c
2  * RTP streams summary addition for Wireshark
3  *
4  * $Id$
5  *
6  * Copyright 2003, Alcatel Business Systems
7  * By Lars Ruoff <lars.ruoff@gmx.net>
8  *
9  * Wireshark - Network traffic analyzer
10  * By Gerald Combs <gerald@wireshark.org>
11  * Copyright 1998 Gerald Combs
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation,  Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26  */
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <stdio.h>
33 #include <string.h>
34
35 #ifdef HAVE_FCNTL_H
36 #include <fcntl.h>
37 #endif
38
39 #ifdef HAVE_SYS_TYPES_H
40 # include <sys/types.h>
41 #endif
42
43
44 #include <epan/epan.h>
45 #include <epan/packet.h>
46 #include <epan/tap.h>
47 #include <epan/dissectors/packet-rtp.h>
48 #include <epan/addr_resolv.h>
49
50 #include "../globals.h"
51 #include "../alert_box.h"
52 #include "../simple_dialog.h"
53 #include "../tap-rtp-common.h"
54 #include <wsutil/file_util.h>
55
56 #include "gtk/rtp_stream.h"
57 #include "gtk/rtp_stream_dlg.h"
58 #include "gtk/main.h"
59
60 /* The one and only global rtpstream_tapinfo_t structure for tshark and wireshark.
61  */
62 static rtpstream_tapinfo_t the_tapinfo_struct =
63         {0, NULL, 0, TAP_ANALYSE, NULL, NULL, NULL, 0, FALSE};
64
65
66 /****************************************************************************/
67 /* redraw the output */
68 static void rtpstream_draw(void *arg _U_)
69 {
70 /* XXX: see rtpstream_on_update in rtp_streams_dlg.c for comments
71         g_signal_emit_by_name(top_level, "signal_rtpstream_update");
72 */
73         rtpstream_dlg_update(the_tapinfo_struct.strinfo_list);
74         return;
75 }
76
77
78 /****************************************************************************/
79 /* scan for RTP streams */
80 void rtpstream_scan(void)
81 {
82         gboolean was_registered = the_tapinfo_struct.is_registered;
83         if (!the_tapinfo_struct.is_registered)
84                 register_tap_listener_rtp_stream();
85
86         the_tapinfo_struct.mode = TAP_ANALYSE;
87         cf_retap_packets(&cfile);
88
89         if (!was_registered)
90                 remove_tap_listener_rtp_stream();
91 }
92
93
94 /****************************************************************************/
95 /* save rtp dump of stream_fwd */
96 gboolean rtpstream_save(rtp_stream_info_t* stream, const gchar *filename)
97 {
98         gboolean was_registered = the_tapinfo_struct.is_registered;
99         /* open file for saving */
100         the_tapinfo_struct.save_file = ws_fopen(filename, "wb");
101         if (the_tapinfo_struct.save_file==NULL) {
102                 open_failure_alert_box(filename, errno, TRUE);
103                 return FALSE;
104         }
105
106         rtp_write_header(stream, the_tapinfo_struct.save_file);
107         if (ferror(the_tapinfo_struct.save_file)) {
108                 write_failure_alert_box(filename, errno);
109                 fclose(the_tapinfo_struct.save_file);
110                 return FALSE;
111         }
112
113         if (!the_tapinfo_struct.is_registered)
114                 register_tap_listener_rtp_stream();
115
116         the_tapinfo_struct.mode = TAP_SAVE;
117         the_tapinfo_struct.filter_stream_fwd = stream;
118         cf_retap_packets(&cfile);
119         the_tapinfo_struct.mode = TAP_ANALYSE;
120
121         if (!was_registered)
122                 remove_tap_listener_rtp_stream();
123
124         if (ferror(the_tapinfo_struct.save_file)) {
125                 write_failure_alert_box(filename, errno);
126                 fclose(the_tapinfo_struct.save_file);
127                 return FALSE;
128         }
129
130         if (fclose(the_tapinfo_struct.save_file) == EOF) {
131                 write_failure_alert_box(filename, errno);
132                 return FALSE;
133         }
134         return TRUE;
135 }
136
137
138 /****************************************************************************/
139 /* mark packets in stream_fwd or stream_rev */
140 void rtpstream_mark(rtp_stream_info_t* stream_fwd, rtp_stream_info_t* stream_rev)
141 {
142         gboolean was_registered = the_tapinfo_struct.is_registered;
143         if (!the_tapinfo_struct.is_registered)
144                 register_tap_listener_rtp_stream();
145
146         the_tapinfo_struct.mode = TAP_MARK;
147         the_tapinfo_struct.filter_stream_fwd = stream_fwd;
148         the_tapinfo_struct.filter_stream_rev = stream_rev;
149         cf_retap_packets(&cfile);
150         the_tapinfo_struct.mode = TAP_ANALYSE;
151
152         if (!was_registered)
153                 remove_tap_listener_rtp_stream();
154 }
155
156
157 /****************************************************************************/
158 const rtpstream_tapinfo_t* rtpstream_get_info(void)
159 {
160         return &the_tapinfo_struct;
161 }
162
163
164 /****************************************************************************/
165 /* TAP INTERFACE */
166 /****************************************************************************/
167
168 /****************************************************************************/
169 void
170 remove_tap_listener_rtp_stream(void)
171 {
172         if (the_tapinfo_struct.is_registered) {
173                 protect_thread_critical_region();
174                 remove_tap_listener(&the_tapinfo_struct);
175                 unprotect_thread_critical_region();
176
177                 the_tapinfo_struct.is_registered = FALSE;
178         }
179 }
180
181
182 /****************************************************************************/
183 void
184 register_tap_listener_rtp_stream(void)
185 {
186         GString *error_string;
187
188         if (!the_tapinfo_struct.is_registered) {
189                 error_string = register_tap_listener("rtp", &the_tapinfo_struct,
190                         NULL, 0, rtpstream_reset_cb, rtpstream_packet,
191                         rtpstream_draw);
192
193                 if (error_string != NULL) {
194                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
195                                       "%s", error_string->str);
196                         g_string_free(error_string, TRUE);
197                         exit(1);
198                 }
199
200                 the_tapinfo_struct.is_registered = TRUE;
201         }
202 }