2 * Routines for exporting PDU:s to file
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #include "pcap-encap.h"
32 #include "version_info.h"
33 #include "wsutil/tempfile.h"
36 #include <epan/exported_pdu.h>
38 #include "ui/alert_box.h"
39 #include "ui/simple_dialog.h"
41 #include "ui/gtk/capture_file_dlg.h"
42 #include "ui/gtk/dlg_utils.h"
43 #include "ui/gtk/gui_utils.h"
44 #include "ui/gtk/filter_dlg.h"
45 #include "ui/gtk/gtkglobals.h"
46 #include "ui/gtk/filter_autocomplete.h"
47 #include "ui/gtk/stock_icons.h"
49 #include "ui/gtk/old-gtk-compat.h"
51 #include "ui/gtk/export_pdu_dlg.h"
53 static GtkWidget
*export_pdu_dlg
= NULL
;
56 typedef struct _exp_pdu_t
{
57 GtkWidget
*filter_widget
;
58 GtkWidget
*tap_name_widget
;
64 /* Main entry point to the tap */
66 export_pdu_packet(void *tapdata
, packet_info
*pinfo
, epan_dissect_t
*edt _U_
, const void *data
)
68 const exp_pdu_data_t
*exp_pdu_data
= (exp_pdu_data_t
*)data
;
69 exp_pdu_t
*exp_pdu_tap_data
= (exp_pdu_t
*)tapdata
;
70 struct wtap_pkthdr pkthdr
;
75 buffer_len
= exp_pdu_data
->tvb_length
+ exp_pdu_data
->tlv_buffer_len
;
76 packet_buf
= (guint8
*)g_malloc(buffer_len
);
78 if(exp_pdu_data
->tlv_buffer_len
> 0){
79 memcpy(packet_buf
, exp_pdu_data
->tlv_buffer
, exp_pdu_data
->tlv_buffer_len
);
80 g_free(exp_pdu_data
->tlv_buffer
);
82 if(exp_pdu_data
->tvb_length
> 0){
83 tvb_memcpy(exp_pdu_data
->pdu_tvb
, packet_buf
+exp_pdu_data
->tlv_buffer_len
, 0, exp_pdu_data
->tvb_length
);
85 pkthdr
.ts
.secs
= pinfo
->fd
->abs_ts
.secs
;
86 pkthdr
.ts
.nsecs
= pinfo
->fd
->abs_ts
.nsecs
;
87 pkthdr
.caplen
= pkthdr
.len
= buffer_len
;
89 pkthdr
.pkt_encap
= exp_pdu_tap_data
->pkt_encap
;
90 pkthdr
.interface_id
= 0;
91 pkthdr
.presence_flags
= 0;
92 pkthdr
.opt_comment
= g_strdup(pinfo
->pkt_comment
);
93 pkthdr
.drop_count
= 0;
94 pkthdr
.pack_flags
= 0;
95 pkthdr
.presence_flags
= WTAP_HAS_CAP_LEN
|WTAP_HAS_INTERFACE_ID
|WTAP_HAS_TS
|WTAP_HAS_PACK_FLAGS
;
97 wtap_dump(exp_pdu_tap_data
->wdh
, &pkthdr
, packet_buf
, &err
);
100 g_free(pkthdr
.opt_comment
);
102 return FALSE
; /* Do not redraw */
106 export_pdu_reset(void *data _U_
)
111 /* Redraw the whole stats window */
113 export_pdu_draw(void *data _U_
)
119 exp_pdu_file_open(exp_pdu_t
*exp_pdu_tap_data
)
122 char *tmpname
, *capfile_name
;
126 wtapng_section_t
*shb_hdr
;
127 wtapng_iface_descriptions_t
*idb_inf
;
128 wtapng_if_descr_t int_data
;
129 GString
*os_info_str
;
132 /* Choose a random name for the temporary import buffer */
133 import_file_fd
= create_tempfile(&tmpname
, "Wireshark_PDU_");
134 capfile_name
= g_strdup(tmpname
);
136 /* Create data for SHB */
137 os_info_str
= g_string_new("");
138 get_os_version_info(os_info_str
);
140 g_snprintf(appname
, sizeof(appname
), "Wireshark " VERSION
"%s", wireshark_svnversion
);
142 shb_hdr
= g_new(wtapng_section_t
,1);
143 shb_hdr
->section_length
= -1;
145 shb_hdr
->opt_comment
= g_strdup_printf("Dump of PDU:s from %s", cfile
.filename
);
146 shb_hdr
->shb_hardware
= NULL
; /* UTF-8 string containing the
147 * description of the hardware used to create this section.
149 shb_hdr
->shb_os
= os_info_str
->str
; /* UTF-8 string containing the name
150 * of the operating system used to create this section.
152 g_string_free(os_info_str
, FALSE
); /* The actual string is not freed */
153 shb_hdr
->shb_user_appl
= appname
; /* UTF-8 string containing the name
154 * of the application used to create this section.
158 /* Create fake IDB info */
159 idb_inf
= g_new(wtapng_iface_descriptions_t
,1);
160 idb_inf
->number_of_interfaces
= 1;
161 idb_inf
->interface_data
= g_array_new(FALSE
, FALSE
, sizeof(wtapng_if_descr_t
));
163 /* create the fake interface data */
164 int_data
.wtap_encap
= WTAP_ENCAP_WIRESHARK_UPPER_PDU
;
165 int_data
.time_units_per_second
= 1000000; /* default microsecond resolution */
166 int_data
.link_type
= wtap_wtap_encap_to_pcap_encap(WTAP_ENCAP_WIRESHARK_UPPER_PDU
);
167 int_data
.snap_len
= WTAP_MAX_PACKET_SIZE
;
168 int_data
.if_name
= g_strdup("Fake IF, PDU->Export");
169 int_data
.opt_comment
= NULL
;
170 int_data
.if_description
= NULL
;
171 int_data
.if_speed
= 0;
172 int_data
.if_tsresol
= 6;
173 int_data
.if_filter_str
= NULL
;
174 int_data
.bpf_filter_len
= 0;
175 int_data
.if_filter_bpf_bytes
= NULL
;
176 int_data
.if_os
= NULL
;
177 int_data
.if_fcslen
= -1;
178 int_data
.num_stat_entries
= 0; /* Number of ISB:s */
179 int_data
.interface_statistics
= NULL
;
181 g_array_append_val(idb_inf
->interface_data
, int_data
);
183 exp_pdu_tap_data
->wdh
= wtap_dump_fdopen_ng(import_file_fd
, WTAP_FILE_TYPE_SUBTYPE_PCAPNG
, WTAP_ENCAP_WIRESHARK_UPPER_PDU
, WTAP_MAX_PACKET_SIZE
, FALSE
, shb_hdr
, idb_inf
, &err
);
184 if (exp_pdu_tap_data
->wdh
== NULL
) {
185 open_failure_alert_box(capfile_name
, err
, TRUE
);
191 cf_retap_packets(&cfile
);
194 if (!wtap_dump_close(exp_pdu_tap_data
->wdh
, &err
)) {
195 write_failure_alert_box(capfile_name
, err
);
198 remove_tap_listener(exp_pdu_tap_data
);
200 if (cf_open(&cfile
, capfile_name
, TRUE
/* temporary file */, &err
) != CF_OK
) {
201 open_failure_alert_box(capfile_name
, err
, FALSE
);
205 switch (cf_read(&cfile
, FALSE
)) {
208 /* Just because we got an error, that doesn't mean we were unable
209 to read any of the file; we handle what we could get from the
213 case CF_READ_ABORTED
:
214 /* The user bailed out of re-reading the capture file; the
215 capture file has been closed - just free the capture file name
216 string and return (without changing the last containing
222 g_free(capfile_name
);
227 export_pdu_destroy_cb(GtkWidget
*win _U_
, gpointer user_data _U_
)
229 /* Note that we no longer have a export_pdu dialog box. */
230 export_pdu_dlg
= NULL
;
234 do_export_pdu(gpointer data
)
236 const char *filter
= NULL
;
237 GString
*error_string
;
238 exp_pdu_t
*exp_pdu_tap_data
= (exp_pdu_t
*)data
;
239 gchar
*tap_name
= NULL
;
241 filter
= gtk_entry_get_text(GTK_ENTRY(exp_pdu_tap_data
->filter_widget
));
242 tap_name
= gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(exp_pdu_tap_data
->tap_name_widget
));
244 /* Register this tap listener now */
245 error_string
= register_tap_listener(tap_name
, /* The name of the tap we want to listen to */
246 exp_pdu_tap_data
, /* instance identifier/pointer to a struct holding
247 * all state variables */
248 filter
, /* pointer to a filter string */
249 TL_REQUIRES_NOTHING
, /* flags for the tap listener */
254 /* Error. We failed to attach to the tap. Clean up */
255 simple_dialog(ESD_TYPE_ERROR
, ESD_BTN_OK
, "%s", error_string
->str
);
256 g_free(exp_pdu_tap_data
);
257 g_string_free(error_string
, TRUE
);
261 exp_pdu_file_open(exp_pdu_tap_data
);
262 window_destroy(export_pdu_dlg
);
267 export_pdu_show_cb(GtkWidget
*w _U_
, gpointer d _U_
)
270 GtkWidget
*main_vb
, *bbox
, *close_bt
, *ok_bt
;
271 GtkWidget
*grid
, *filter_bt
;
272 exp_pdu_t
*exp_pdu_tap_data
;
273 const char *filter
= NULL
;
276 static construct_args_t args
= {
277 "Wireshark: Export PDUs Filter",
278 TRUE
, /* dialog should have an Apply button */
279 FALSE
, /* if parent text widget should be activated on "Ok" or "Apply" */
280 FALSE
/* dialog is modal and transient to the parent window */
283 if (export_pdu_dlg
!= NULL
) {
284 /* There's already a export_pdu dialog box; reactivate it. */
285 reactivate_window(export_pdu_dlg
);
289 exp_pdu_tap_data
= (exp_pdu_t
*)g_malloc(sizeof(exp_pdu_t
));
290 exp_pdu_tap_data
->pkt_encap
= wtap_wtap_encap_to_pcap_encap(WTAP_ENCAP_WIRESHARK_UPPER_PDU
);
292 export_pdu_dlg
= window_new(GTK_WINDOW_TOPLEVEL
, "Wireshark: Export PDU:s to pcap-ng file");
294 g_signal_connect(export_pdu_dlg
, "delete_event", G_CALLBACK(window_delete_event_cb
), NULL
);
295 g_signal_connect(export_pdu_dlg
, "destroy", G_CALLBACK(export_pdu_destroy_cb
), NULL
);
297 main_vb
= ws_gtk_box_new(GTK_ORIENTATION_VERTICAL
, 0, FALSE
);
298 gtk_container_set_border_width(GTK_CONTAINER(main_vb
), 3);
299 gtk_container_add(GTK_CONTAINER(export_pdu_dlg
), main_vb
);
302 grid
= ws_gtk_grid_new();
303 ws_gtk_grid_set_column_spacing(GTK_GRID(grid
), 6);
304 ws_gtk_grid_set_row_spacing(GTK_GRID(grid
), 3);
305 gtk_box_pack_start(GTK_BOX(main_vb
), grid
, TRUE
, TRUE
, 0);
309 filter_bt
=gtk_button_new_from_stock(WIRESHARK_STOCK_DISPLAY_FILTER_ENTRY
);
310 g_signal_connect(filter_bt
, "clicked", G_CALLBACK(display_filter_construct_cb
), &args
);
311 ws_gtk_grid_attach_defaults(GTK_GRID(grid
), filter_bt
, 0, row
, 1, 1);
312 gtk_widget_show(filter_bt
);
315 exp_pdu_tap_data
->filter_widget
=gtk_entry_new();
316 g_signal_connect(exp_pdu_tap_data
->filter_widget
, "changed", G_CALLBACK(filter_te_syntax_check_cb
), NULL
);
317 g_object_set_data(G_OBJECT(grid
), E_FILT_AUTOCOMP_PTR_KEY
, NULL
);
318 g_signal_connect(exp_pdu_tap_data
->filter_widget
, "key-press-event", G_CALLBACK (filter_string_te_key_pressed_cb
), NULL
);
319 g_object_set_data(G_OBJECT(filter_bt
), E_FILT_TE_PTR_KEY
, exp_pdu_tap_data
->filter_widget
);
321 filter
=gtk_entry_get_text(GTK_ENTRY(main_display_filter_widget
));
323 gtk_entry_set_text(GTK_ENTRY(exp_pdu_tap_data
->filter_widget
), filter
);
325 colorize_filter_te_as_empty(exp_pdu_tap_data
->filter_widget
);
328 ws_gtk_grid_attach_defaults(GTK_GRID(grid
), exp_pdu_tap_data
->filter_widget
, 1, row
, 1, 1);
329 gtk_widget_show(exp_pdu_tap_data
->filter_widget
);
332 /* Select which tap to run */
334 exp_pdu_tap_data
->tap_name_widget
= gtk_combo_box_text_new();
335 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(exp_pdu_tap_data
->tap_name_widget
), EXPORT_PDU_TAP_NAME_LAYER_7
);
336 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(exp_pdu_tap_data
->tap_name_widget
), EXPORT_PDU_TAP_NAME_LAYER_3
);
337 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(exp_pdu_tap_data
->tap_name_widget
), EXPORT_PDU_TAP_NAME_DVB_CI
);
338 gtk_combo_box_set_active(GTK_COMBO_BOX(exp_pdu_tap_data
->tap_name_widget
), 0);
340 ws_gtk_grid_attach_defaults(GTK_GRID(grid
), exp_pdu_tap_data
->tap_name_widget
, 0, row
, 1, 1);
341 gtk_widget_show(exp_pdu_tap_data
->tap_name_widget
);
343 /* Setup the button row */
345 bbox
= dlg_button_row_new(GTK_STOCK_OK
, GTK_STOCK_CANCEL
, NULL
);
346 gtk_box_pack_end(GTK_BOX(main_vb
), bbox
, FALSE
, FALSE
, 3);
348 close_bt
= (GtkWidget
*)g_object_get_data(G_OBJECT(bbox
), GTK_STOCK_CANCEL
);
349 window_set_cancel_button(export_pdu_dlg
, close_bt
, window_cancel_button_cb
);
350 gtk_widget_set_tooltip_text(close_bt
, "Close this dialog");
352 ok_bt
= (GtkWidget
*)g_object_get_data(G_OBJECT(bbox
), GTK_STOCK_OK
);
353 g_signal_connect(ok_bt
, "clicked", G_CALLBACK(file_export_pdu_ok_cb
), exp_pdu_tap_data
);
354 gtk_widget_grab_default(ok_bt
);
355 gtk_widget_set_tooltip_text(ok_bt
, "Export PDU:s to a temporary capture file");
357 gtk_widget_show_all(export_pdu_dlg
);
358 window_present(export_pdu_dlg
);