2 * Routines for packet capture
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0-or-later
12 #define WS_LOG_DOMAIN LOG_DOMAIN_CAPTURE
22 #include <ws_exit_codes.h>
24 #include <epan/packet.h>
25 #include <epan/dfilter/dfilter.h>
28 #include "ui/capture.h"
29 #include "capture/capture_ifinfo.h"
30 #include <capture/capture_sync.h>
31 #include "capture/iface_monitor.h"
32 #include "ui/capture_info.h"
33 #include "ui/capture_ui_utils.h"
34 #include "ui/iface_lists.h"
37 #include "capture/capture-pcap-util.h"
40 #include "capture/capture-wpcap.h"
43 #include "ui/simple_dialog.h"
44 #include "ui/ws_ui_util.h"
46 #include "wsutil/file_util.h"
47 #include "wsutil/str_util.h"
48 #include <wsutil/filesystem.h>
49 #include <wsutil/wslog.h>
50 #include <wsutil/ws_assert.h>
52 typedef struct if_stat_cache_item_s
{
55 } if_stat_cache_item_t
;
57 struct if_stat_cache_s
{
59 ws_process_id fork_child
;
60 GList
*cache_list
; /* List of if_stat_chache_entry_t */
63 /* this callback mechanism should possibly be replaced by the g_signal_...() stuff (if I only would know how :-) */
65 capture_callback_t cb_fct
;
67 } capture_callback_data_t
;
69 static GList
*capture_callbacks
;
72 capture_callback_invoke(int event
, capture_session
*cap_session
)
74 capture_callback_data_t
*cb
;
75 GList
*cb_item
= capture_callbacks
;
77 /* there should be at least one interested */
78 ws_assert(cb_item
!= NULL
);
80 while(cb_item
!= NULL
) {
81 cb
= (capture_callback_data_t
*)cb_item
->data
;
82 cb
->cb_fct(event
, cap_session
, cb
->user_data
);
83 cb_item
= g_list_next(cb_item
);
89 capture_callback_add(capture_callback_t func
, void *user_data
)
91 capture_callback_data_t
*cb
;
93 cb
= g_new(capture_callback_data_t
, 1);
95 cb
->user_data
= user_data
;
97 capture_callbacks
= g_list_prepend(capture_callbacks
, cb
);
101 capture_callback_remove(capture_callback_t func
, void *user_data
)
103 capture_callback_data_t
*cb
;
104 GList
*cb_item
= capture_callbacks
;
106 while(cb_item
!= NULL
) {
107 cb
= (capture_callback_data_t
*)cb_item
->data
;
108 if(cb
->cb_fct
== func
&& cb
->user_data
== user_data
) {
109 capture_callbacks
= g_list_remove(capture_callbacks
, cb
);
113 cb_item
= g_list_next(cb_item
);
116 ws_assert_not_reached();
122 * @return true if the capture starts successfully, false otherwise.
125 capture_start(capture_options
*capture_opts
, GPtrArray
*capture_comments
,
126 capture_session
*cap_session
, info_data_t
* cap_data
,
127 void(*update_cb
)(void))
131 cap_session
->state
= CAPTURE_PREPARING
;
132 cap_session
->count
= 0;
133 ws_message("Capture Start ...");
134 source
= get_iface_list_string(capture_opts
, IFLIST_SHOW_FILTER
);
135 cf_set_tempfile_source((capture_file
*)cap_session
->cf
, source
->str
);
136 g_string_free(source
, TRUE
);
137 iface_mon_enable(false);
138 /* try to start the capture child process */
139 if (!sync_pipe_start(capture_opts
, capture_comments
, cap_session
,
140 cap_data
, update_cb
)) {
141 iface_mon_enable(true);
142 /* We failed to start the capture child. */
143 if(capture_opts
->save_file
!= NULL
) {
144 g_free(capture_opts
->save_file
);
145 capture_opts
->save_file
= NULL
;
148 ws_message("Capture Start failed.");
149 cap_session
->state
= CAPTURE_STOPPED
;
153 // Do we need data structures for ignoring duplicate frames?
154 if (prefs
.ignore_dup_frames
&& capture_opts
->real_time_mode
) {
155 fifo_string_cache_init(&cap_session
->frame_dup_cache
,
156 prefs
.ignore_dup_frames_cache_entries
, g_free
);
157 cap_session
->frame_cksum
= g_checksum_new(G_CHECKSUM_SHA256
);
160 /* the capture child might not respond shortly after bringing it up */
161 /* (for example: it will block if no input arrives from an input capture pipe (e.g. mkfifo)) */
163 /* to prevent problems, bring the main GUI into "capture mode" right after a successful */
164 /* spawn/exec of the capture child, without waiting for any response from it */
165 capture_callback_invoke(capture_cb_capture_prepared
, cap_session
);
167 wtap_rec_init(&cap_session
->rec
);
168 ws_buffer_init(&cap_session
->buf
, 1514);
170 cap_session
->wtap
= NULL
;
172 if (capture_opts
->show_info
) {
173 if (cap_data
->counts
.counts_hash
!= NULL
)
175 /* Clean up any previous lists of packet counts */
176 g_hash_table_destroy(cap_data
->counts
.counts_hash
);
179 cap_data
->counts
.counts_hash
= g_hash_table_new_full(g_direct_hash
, g_direct_equal
, NULL
, g_free
);
180 cap_data
->counts
.other
= 0;
181 cap_data
->counts
.total
= 0;
183 cap_data
->ui
.counts
= &cap_data
->counts
;
185 capture_info_ui_create(&cap_data
->ui
, cap_session
);
193 capture_stop(capture_session
*cap_session
)
195 ws_message("Capture Stop ...");
197 capture_callback_invoke(capture_cb_capture_stopping
, cap_session
);
199 if (!extcap_session_stop(cap_session
)) {
200 extcap_request_stop(cap_session
);
201 cap_session
->capture_opts
->stop_after_extcaps
= true;
203 /* stop the capture child gracefully */
204 sync_pipe_stop(cap_session
);
210 capture_kill_child(capture_session
*cap_session
)
212 ws_info("Capture Kill");
214 /* kill the capture child */
215 sync_pipe_kill(cap_session
->fork_child
);
219 #define NO_PACKETS_CAPTURED_PLATFORM_HELP \
221 "Wireless (Wi-Fi/WLAN):\n" \
222 "Try to switch off promiscuous mode in the Capture Options."
224 #define NO_PACKETS_CAPTURED_PLATFORM_HELP
228 capture_input_no_packets(capture_session
*cap_session
)
230 simple_message_box(ESD_TYPE_INFO
, NULL
,
231 "Help about capturing can be found at "
232 WS_WIKI_URL("CaptureSetup")
233 NO_PACKETS_CAPTURED_PLATFORM_HELP
,
234 "No packets captured. "
235 "As no data was captured, closing the %scapture file.",
236 (cf_is_tempfile((capture_file
*)cap_session
->cf
)) ? "temporary " : "");
237 cf_close((capture_file
*)cap_session
->cf
);
240 /* We've succeeded in doing a (non real-time) capture; try to read it into a new capture file */
242 capture_input_read_all(capture_session
*cap_session
, bool is_tempfile
,
243 bool drops_known
, uint32_t drops
)
245 capture_options
*capture_opts
= cap_session
->capture_opts
;
248 /* Capture succeeded; attempt to open the capture file. */
249 if (cf_open((capture_file
*)cap_session
->cf
, capture_opts
->save_file
, WTAP_TYPE_AUTO
, is_tempfile
, &err
) != CF_OK
) {
250 /* We're not doing a capture any more, so we don't have a save file. */
254 /* Set the read filter to NULL. */
255 /* XXX - this is odd here; try to put it somewhere where it fits better */
256 cf_set_rfcode((capture_file
*)cap_session
->cf
, NULL
);
258 /* Get the packet-drop statistics.
260 XXX - there are currently no packet-drop statistics stored
261 in libpcap captures, and that's what we're reading.
263 At some point, we will add support in Wiretap to return
264 packet-drop statistics for capture file formats that store it,
265 and will make "cf_read()" get those statistics from Wiretap.
266 We clear the statistics (marking them as "not known") in
267 "cf_open()", and "cf_read()" will only fetch them and mark
268 them as known if Wiretap supplies them, so if we get the
269 statistics now, after calling "cf_open()" but before calling
270 "cf_read()", the values we store will be used by "cf_read()".
272 If a future libpcap capture file format stores the statistics,
273 we'll put them into the capture file that we write, and will
274 thus not have to set them here - "cf_read()" will get them from
275 the file and use them. */
277 cf_set_drops_known((capture_file
*)cap_session
->cf
, true);
279 /* XXX - on some systems, libpcap doesn't bother filling in
280 "ps_ifdrop" - it doesn't even set it to zero - so we don't
281 bother looking at it.
283 Ideally, libpcap would have an interface that gave us
284 several statistics - perhaps including various interface
285 error statistics - and would tell us which of them it
286 supplies, allowing us to display only the ones it does. */
287 cf_set_drops((capture_file
*)cap_session
->cf
, drops
);
290 /* read in the packet data */
291 switch (cf_read((capture_file
*)cap_session
->cf
, /*reloading=*/false)) {
295 /* Just because we got an error, that doesn't mean we were unable
296 to read any of the file; we handle what we could get from the
300 case CF_READ_ABORTED
:
301 /* The user asked to abort the read, but that might be to
302 restart the capture, so let the caller decide whether
304 //exit_application(0);
308 /* if we didn't capture even a single packet, report that and
309 close the file again */
310 if(cap_session
->count
== 0 && !capture_opts
->restart
) {
311 capture_input_no_packets(cap_session
);
317 cf_open_error_message(int err
, char *err_info
)
320 static char errmsg_errno
[1024 + 1];
326 case WTAP_ERR_NOT_REGULAR_FILE
:
327 errmsg
= "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
330 case WTAP_ERR_FILE_UNKNOWN_FORMAT
:
331 /* Seen only when opening a capture file for reading. */
332 errmsg
= "The file \"%s\" isn't a capture file in a format Wireshark understands.";
335 case WTAP_ERR_UNSUPPORTED
:
336 snprintf(errmsg_errno
, sizeof(errmsg_errno
),
337 "The file \"%%s\" contains record data that Wireshark doesn't support.\n"
338 "(%s)", err_info
!= NULL
? err_info
: "no information supplied");
340 errmsg
= errmsg_errno
;
343 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED
:
344 errmsg
= "The file \"%s\" is a capture for a network type that Wireshark doesn't support.";
347 case WTAP_ERR_BAD_FILE
:
348 snprintf(errmsg_errno
, sizeof(errmsg_errno
),
349 "The file \"%%s\" appears to be damaged or corrupt.\n"
350 "(%s)", err_info
!= NULL
? err_info
: "no information supplied");
352 errmsg
= errmsg_errno
;
355 case WTAP_ERR_CANT_OPEN
:
356 errmsg
= "The file \"%s\" could not be opened for some unknown reason.";
359 case WTAP_ERR_SHORT_READ
:
360 errmsg
= "The file \"%s\" appears to have been cut short"
361 " in the middle of a packet or other data.";
364 case WTAP_ERR_DECOMPRESS
:
365 snprintf(errmsg_errno
, sizeof(errmsg_errno
),
366 "The file \"%%s\" cannot be decompressed; it may be damaged or corrupt.\n"
367 "(%s)", err_info
!= NULL
? err_info
: "no information supplied");
369 errmsg
= errmsg_errno
;
372 case WTAP_ERR_INTERNAL
:
373 snprintf(errmsg_errno
, sizeof(errmsg_errno
),
374 "An internal error occurred opening the file \"%%s\".\n"
375 "(%s)", err_info
!= NULL
? err_info
: "no information supplied");
377 errmsg
= errmsg_errno
;
380 case WTAP_ERR_DECOMPRESSION_NOT_SUPPORTED
:
381 snprintf(errmsg_errno
, sizeof(errmsg_errno
),
382 "The file \"%%s\" cannot be decompressed; it is compressed in a way that We don't support.\n"
383 "(%s)", err_info
!= NULL
? err_info
: "no information supplied");
385 errmsg
= errmsg_errno
;
389 snprintf(errmsg_errno
, sizeof(errmsg_errno
),
390 "The file \"%%s\" could not be opened: %s.",
392 errmsg
= errmsg_errno
;
397 errmsg
= file_open_error_message(err
, false);
401 /* capture child tells us we have a new (or the first) capture file */
403 capture_input_new_file(capture_session
*cap_session
, char *new_file
)
405 capture_options
*capture_opts
= cap_session
->capture_opts
;
411 if(cap_session
->state
== CAPTURE_PREPARING
) {
412 ws_message("Capture started");
414 ws_message("File: \"%s\"", new_file
);
416 ws_assert(cap_session
->state
== CAPTURE_PREPARING
|| cap_session
->state
== CAPTURE_RUNNING
);
418 /* free the old filename */
419 if(capture_opts
->save_file
!= NULL
) {
420 /* we start a new capture file, close the old one (if we had one before). */
421 /* (we can only have an open capture file in real_time_mode!) */
422 if (((capture_file
*)cap_session
->cf
)->state
== FILE_READ_PENDING
) {
423 capture_callback_invoke(capture_cb_capture_fixed_finished
, cap_session
);
424 } else if (((capture_file
*)cap_session
->cf
)->state
!= FILE_CLOSED
) {
425 cap_session
->session_will_restart
= true;
426 capture_callback_invoke(capture_cb_capture_update_finished
, cap_session
);
427 cf_finish_tail((capture_file
*)cap_session
->cf
,
428 &cap_session
->rec
, &cap_session
->buf
, &err
,
429 &cap_session
->frame_dup_cache
, cap_session
->frame_cksum
);
430 cf_close((capture_file
*)cap_session
->cf
);
432 g_free(capture_opts
->save_file
);
434 cf_set_tempfile((capture_file
*)cap_session
->cf
, false);
436 /* we didn't have a save_file before; must be a tempfile */
438 cf_set_tempfile((capture_file
*)cap_session
->cf
, true);
441 /* save the new filename */
442 capture_opts
->save_file
= g_strdup(new_file
);
444 /* if we are in real-time mode, open the new file now */
445 if(capture_opts
->real_time_mode
) {
446 /* Attempt to open the capture file and set up to read from it. */
447 switch(cf_open((capture_file
*)cap_session
->cf
, capture_opts
->save_file
, WTAP_TYPE_AUTO
, is_tempfile
, &err
)) {
451 /* Don't unlink (delete) the save file - leave it around,
452 for debugging purposes. */
453 g_free(capture_opts
->save_file
);
454 capture_opts
->save_file
= NULL
;
458 capture_callback_invoke(capture_cb_capture_prepared
, cap_session
);
461 if(capture_opts
->show_info
) {
462 if (cap_session
->wtap
!= NULL
) {
463 wtap_close(cap_session
->wtap
);
466 cap_session
->wtap
= wtap_open_offline(new_file
, WTAP_TYPE_AUTO
, &err
, &err_info
, false);
467 if (!cap_session
->wtap
) {
468 err_msg
= ws_strdup_printf(cf_open_error_message(err
, err_info
),
470 ws_warning("capture_input_new_file: %d (%s)", err
, err_msg
);
476 if(capture_opts
->real_time_mode
) {
477 capture_callback_invoke(capture_cb_capture_update_started
, cap_session
);
479 capture_callback_invoke(capture_cb_capture_fixed_started
, cap_session
);
481 cap_session
->state
= CAPTURE_RUNNING
;
487 capture_info_packet(info_data_t
* cap_info
, int wtap_linktype
, const unsigned char *pd
, uint32_t caplen
, union wtap_pseudo_header
*pseudo_header
)
489 capture_packet_info_t cpinfo
;
491 /* Setup the capture packet structure */
492 cpinfo
.counts
= cap_info
->counts
.counts_hash
;
494 cap_info
->counts
.total
++;
495 if (!try_capture_dissector("wtap_encap", wtap_linktype
, pd
, 0, caplen
, &cpinfo
, pseudo_header
))
496 cap_info
->counts
.other
++;
499 /* new packets arrived */
501 capture_info_new_packets(int to_read
, wtap
*wth
, info_data_t
* cap_info
)
508 union wtap_pseudo_header
*pseudo_header
;
511 cap_info
->ui
.new_packets
= to_read
;
513 /*ws_warning("new packets: %u", to_read);*/
516 ws_buffer_init(&buf
, 1514);
517 while (to_read
> 0) {
519 if (wtap_read(wth
, &rec
, &buf
, &err
, &err_info
, &data_offset
)) {
520 if (rec
.rec_type
== REC_TYPE_PACKET
) {
521 pseudo_header
= &rec
.rec_header
.packet_header
.pseudo_header
;
522 wtap_linktype
= rec
.rec_header
.packet_header
.pkt_encap
;
524 capture_info_packet(cap_info
, wtap_linktype
,
525 ws_buffer_start_ptr(&buf
),
526 rec
.rec_header
.packet_header
.caplen
,
529 /*ws_warning("new packet");*/
532 wtap_rec_reset(&rec
);
535 wtap_rec_cleanup(&rec
);
536 ws_buffer_free(&buf
);
538 capture_info_ui_update(&cap_info
->ui
);
541 /* capture child tells us we have new packets to read */
543 capture_input_new_packets(capture_session
*cap_session
, int to_read
)
545 capture_options
*capture_opts
= cap_session
->capture_opts
;
548 ws_assert(capture_opts
->save_file
);
550 if(capture_opts
->real_time_mode
) {
551 if (((capture_file
*)cap_session
->cf
)->state
== FILE_READ_PENDING
) {
552 /* Attempt to open the capture file and set up to read from it. */
553 switch (cf_open((capture_file
*)cap_session
->cf
, capture_opts
->save_file
, WTAP_TYPE_AUTO
, cf_is_tempfile((capture_file
*)cap_session
->cf
), &err
)) {
557 /* Don't unlink (delete) the save file - leave it around,
558 for debugging purposes. */
559 g_free(capture_opts
->save_file
);
560 capture_opts
->save_file
= NULL
;
561 capture_kill_child(cap_session
);
563 capture_callback_invoke(capture_cb_capture_update_started
, cap_session
);
565 /* Read from the capture file the number of records the child told us it added. */
566 to_read
+= cap_session
->count_pending
;
567 cap_session
->count_pending
= 0;
568 switch (cf_continue_tail((capture_file
*)cap_session
->cf
, to_read
,
569 &cap_session
->rec
, &cap_session
->buf
, &err
,
570 &cap_session
->frame_dup_cache
, cap_session
->frame_cksum
)) {
574 /* Just because we got an error, that doesn't mean we were unable
575 to read any of the file; we handle what we could get from the
578 XXX - abort on a read error? */
579 capture_callback_invoke(capture_cb_capture_update_continue
, cap_session
);
582 case CF_READ_ABORTED
:
583 /* Kill the child capture process; the user wants to exit, and we
584 shouldn't just leave it running. */
585 capture_kill_child(cap_session
);
589 cf_fake_continue_tail((capture_file
*)cap_session
->cf
);
590 cap_session
->count_pending
+= to_read
;
592 capture_callback_invoke(capture_cb_capture_fixed_continue
, cap_session
);
595 if(cap_session
->wtap
)
596 capture_info_new_packets(to_read
, cap_session
->wtap
, cap_session
->cap_data_info
);
600 /* Capture child told us how many dropped packets it counted.
603 capture_input_drops(capture_session
*cap_session
, uint32_t dropped
, const char* interface_name
)
605 if (interface_name
!= NULL
) {
606 ws_info("%u packet%s dropped from %s", dropped
, plurality(dropped
, "", "s"), interface_name
);
608 ws_info("%u packet%s dropped", dropped
, plurality(dropped
, "", "s"));
611 ws_assert(cap_session
->state
== CAPTURE_RUNNING
);
613 cf_set_drops_known((capture_file
*)cap_session
->cf
, true);
614 cf_set_drops((capture_file
*)cap_session
->cf
, dropped
);
618 /* Capture child told us that an error has occurred while starting/running
620 The buffer we're handed has *two* null-terminated strings in it - a
621 primary message and a secondary message, one right after the other.
622 The secondary message might be a null string.
625 capture_input_error(capture_session
*cap_session _U_
, char *error_msg
,
626 char *secondary_error_msg
)
628 char *safe_error_msg
;
629 char *safe_secondary_error_msg
;
631 /* The primary message might be an empty string, e.g. when the error was
632 * from extcap. (The extcap stderr is gathered when the session closes
633 * and printed in capture_input_closed below.) */
634 if (*error_msg
!= '\0') {
635 ws_message("Error message from child: \"%s\", \"%s\"", error_msg
, secondary_error_msg
);
638 ws_assert(cap_session
->state
== CAPTURE_PREPARING
|| cap_session
->state
== CAPTURE_RUNNING
);
640 safe_error_msg
= simple_dialog_format_message(error_msg
);
641 if (secondary_error_msg
!= NULL
&& *secondary_error_msg
!= '\0') {
642 /* We have both primary and secondary messages. */
643 safe_secondary_error_msg
= simple_dialog_format_message(secondary_error_msg
);
644 simple_message_box(ESD_TYPE_ERROR
, NULL
, safe_secondary_error_msg
,
645 "%s", safe_error_msg
);
646 g_free(safe_secondary_error_msg
);
648 /* We have only a primary message. */
649 simple_message_box(ESD_TYPE_ERROR
, NULL
, NULL
, "%s", safe_error_msg
);
651 g_free(safe_error_msg
);
653 /* the capture child will close the sync_pipe if required, nothing to do for now */
656 /* Capture child told us that an error has occurred while parsing a
657 capture filter when starting/running the capture.
660 capture_input_cfilter_error(capture_session
*cap_session
, unsigned i
,
661 const char *error_message
)
663 capture_options
*capture_opts
= cap_session
->capture_opts
;
664 dfilter_t
*rfcode
= NULL
;
667 char *safe_cfilter_error_msg
;
668 const char *secondary_error_msg
;
669 interface_options
*interface_opts
;
671 ws_message("Capture filter error message from child: \"%s\"", error_message
);
673 ws_assert(cap_session
->state
== CAPTURE_PREPARING
|| cap_session
->state
== CAPTURE_RUNNING
);
674 ws_assert(i
< capture_opts
->ifaces
->len
);
676 interface_opts
= &g_array_index(capture_opts
->ifaces
, interface_options
, i
);
677 safe_cfilter
= simple_dialog_format_message(interface_opts
->cfilter
);
678 safe_descr
= simple_dialog_format_message(interface_opts
->descr
);
679 safe_cfilter_error_msg
= simple_dialog_format_message(error_message
);
680 /* Did the user try a display filter? */
681 if (dfilter_compile(interface_opts
->cfilter
, &rfcode
, NULL
) && rfcode
!= NULL
) {
682 secondary_error_msg
=
683 "That string looks like a valid display filter.\n"
685 "Note that display filters and capture filters don't have the same syntax,\n"
686 "so you can't use most display filter expressions as capture filters.\n"
688 "See the User's Guide for a description of the capture filter syntax.";
690 secondary_error_msg
=
691 "See the User's Guide for a description of the capture filter syntax.";
693 simple_message_box(ESD_TYPE_ERROR
, NULL
,
695 "\"%s\" is not a valid capture filter for interface \"%s\" (%s).",
696 safe_cfilter
, safe_descr
, safe_cfilter_error_msg
);
697 g_free(safe_cfilter_error_msg
);
699 g_free(safe_cfilter
);
701 /* the capture child will close the sync_pipe if required, nothing to do for now */
704 /* capture child closed its side of the pipe, do the required cleanup */
706 capture_input_closed(capture_session
*cap_session
, char *msg
)
708 capture_options
*capture_opts
= cap_session
->capture_opts
;
711 ws_message("Capture stopped.");
712 ws_assert(cap_session
->state
== CAPTURE_PREPARING
|| cap_session
->state
== CAPTURE_RUNNING
);
714 if (msg
!= NULL
&& msg
[0] != '\0') {
715 ESD_TYPE_E dlg_type
= ESD_TYPE_ERROR
;
716 if (strstr(msg
, " WARNING] ")) {
717 dlg_type
= ESD_TYPE_WARN
;
720 * ws_log prefixes log messages with a timestamp delimited by " -- " and possibly
721 * a function name delimited by "(): ". Log it to sterr, but omit it in the UI.
723 char **msg_lines
= g_strsplit(msg
, "\n", 0);
724 GString
* gui_msg
= g_string_new(NULL
);
726 for (char **line
= msg_lines
; *line
!= NULL
; line
++) {
727 if (gui_msg
->len
> 0) {
728 g_string_append(gui_msg
, "\n");
730 char *plain_msg
= strstr(*line
, "(): ");
731 if (plain_msg
!= NULL
) {
732 plain_msg
+= strlen("(): ");
733 } else if ((plain_msg
= strstr(*line
, " -- ")) != NULL
) {
734 plain_msg
+= strlen(" -- ");
738 g_string_append(gui_msg
, plain_msg
);
740 ws_warning("%s", msg
);
741 simple_dialog(dlg_type
, ESD_BTN_OK
, "%s", gui_msg
->str
);
742 g_string_free(gui_msg
, TRUE
);
743 g_strfreev(msg_lines
);
746 wtap_rec_cleanup(&cap_session
->rec
);
747 ws_buffer_free(&cap_session
->buf
);
748 if(cap_session
->state
== CAPTURE_PREPARING
) {
749 /* We started the capture child, but we didn't manage to start
750 the capture process; note that the attempt to start it
752 capture_callback_invoke(capture_cb_capture_failed
, cap_session
);
754 /* We started a capture; process what's left of the capture file if
755 we were in "update list of packets in real time" mode, or process
756 all of it if we weren't. */
757 if(((capture_file
*)cap_session
->cf
)->state
== FILE_READ_IN_PROGRESS
) {
758 cf_read_status_t status
;
760 /* Read what remains of the capture file. */
761 status
= cf_finish_tail((capture_file
*)cap_session
->cf
,
762 &cap_session
->rec
, &cap_session
->buf
, &err
,
763 &cap_session
->frame_dup_cache
, cap_session
->frame_cksum
);
765 // The real-time reading of the pcap is done. Now we can clear the
766 // dup-frame cache, if present. But check that we actually have
767 // data structures to clear (by checking frame-checksum); the user
768 // could have changed the preference *during* the live capture.
769 if (cap_session
->frame_cksum
!= NULL
) {
770 fifo_string_cache_free(&cap_session
->frame_dup_cache
);
771 g_checksum_free(cap_session
->frame_cksum
);
772 cap_session
->frame_cksum
= NULL
;
775 /* Tell the GUI we are not doing a capture any more.
776 Must be done after the cf_finish_tail(), so file lengths are
777 correctly displayed */
778 cap_session
->session_will_restart
= false;
779 capture_callback_invoke(capture_cb_capture_update_finished
, cap_session
);
781 /* Finish the capture. */
785 if (cap_session
->count
== 0 && !capture_opts
->restart
) {
786 capture_input_no_packets(cap_session
);
790 /* Just because we got an error, that doesn't mean we were unable
791 to read any of the file; we handle what we could get from the
795 case CF_READ_ABORTED
:
796 /* The user asked to abort the read, but that might be to
797 restart the capture, so let the caller decide whether
799 //exit_application(0);
802 } else if (((capture_file
*)cap_session
->cf
)->state
== FILE_READ_PENDING
) {
803 /* first of all, we are not doing a capture any more */
804 capture_callback_invoke(capture_cb_capture_fixed_finished
, cap_session
);
806 /* this is a normal mode capture and if no error happened, read in the capture file data */
807 if(capture_opts
->save_file
!= NULL
) {
808 capture_input_read_all(cap_session
, cf_is_tempfile((capture_file
*)cap_session
->cf
),
809 cf_get_drops_known((capture_file
*)cap_session
->cf
), cf_get_drops((capture_file
*)cap_session
->cf
));
812 /* First, tell the GUI we are not capturing nor stopping a capture
813 anymore. We need to do this if we're aborting the capture but
814 not quitting the program (e.g., restarting the capture.) */
815 capture_callback_invoke(capture_cb_capture_update_finished
, cap_session
);
817 if (cap_session
->frame_cksum
!= NULL
) {
818 fifo_string_cache_free(&cap_session
->frame_dup_cache
);
819 g_checksum_free(cap_session
->frame_cksum
);
820 cap_session
->frame_cksum
= NULL
;
823 cf_close((capture_file
*)cap_session
->cf
);
827 capture_info_ui_destroy(&cap_session
->cap_data_info
->ui
);
828 if(cap_session
->wtap
) {
829 wtap_close(cap_session
->wtap
);
830 cap_session
->wtap
= NULL
;
833 cap_session
->state
= CAPTURE_STOPPED
;
835 /* if we couldn't open a capture file, there's nothing more for us to do */
836 if(capture_opts
->save_file
== NULL
) {
837 cf_close((capture_file
*)cap_session
->cf
);
841 /* does the user wants to restart the current capture? */
842 if(capture_opts
->restart
) {
843 capture_opts
->restart
= false;
845 /* If we have a ring buffer, the original save file has been overwritten
846 with the "ring filename". Restore it before starting again */
847 if ((capture_opts
->multi_files_on
) && (capture_opts
->orig_save_file
!= NULL
)) {
848 g_free(capture_opts
->save_file
);
849 capture_opts
->save_file
= g_strdup(capture_opts
->orig_save_file
);
852 /* If it was a tempfile, throw away the old filename (so it will become a tempfile again) */
853 if (cf_is_tempfile((capture_file
*)cap_session
->cf
)) {
854 g_free(capture_opts
->save_file
);
855 capture_opts
->save_file
= NULL
;
859 /* If we're in multiple file mode, restore the original save file
860 name (template), so that it will be used if a new capture is started
861 without opening the Capture Options dialog. Any files we just wrote
862 won't get overwritten. If we set it to NULL, a tempfile name would
863 be used, but that doesn't work in multiple file mode - we could turn
864 off multiple file mode instead, but that would change the behavior
865 if the Capture Options dialog is re-opened. */
866 if ((capture_opts
->multi_files_on
) && (capture_opts
->orig_save_file
!= NULL
)) {
867 g_free(capture_opts
->save_file
);
868 capture_opts
->save_file
= g_strdup(capture_opts
->orig_save_file
);
870 /* We're not doing a capture any more, so we don't have a save file.
871 If a new capture is started without opening the Capture Options
872 dialog (Start button or double-clicking on an interface from
873 the welcome screen), we'll use a tempfile. Thus if our current
874 capture is to a permanent file, we won't overwrite it. */
875 g_free(capture_opts
->save_file
);
876 capture_opts
->save_file
= NULL
;
882 capture_stat_start(capture_options
*capture_opts
)
885 ws_process_id fork_child
;
887 if_stat_cache_t
*sc
= g_new0(if_stat_cache_t
, 1);
888 if_stat_cache_item_t
*sc_item
;
893 sc
->fork_child
= WS_INVALID_PID
;
895 /* Fire up dumpcap. */
897 * XXX - on systems with BPF, the number of BPF devices limits the
898 * number of devices on which you can capture simultaneously.
902 * 1) this might fail if you run out of BPF devices
906 * 2) opening every interface could leave too few BPF devices
907 * for *other* programs.
909 * It also means the system could end up getting a lot of traffic
910 * that it has to pass through the networking stack and capture
911 * mechanism, so opening all the devices and presenting packet
912 * counts might not always be a good idea.
914 if (sync_interface_stats_open(&stat_fd
, &fork_child
, NULL
, &msg
, NULL
) == 0) {
915 sc
->stat_fd
= stat_fd
;
916 sc
->fork_child
= fork_child
;
918 /* Initialize the cache */
919 for (i
= 0; i
< capture_opts
->all_ifaces
->len
; i
++) {
920 device
= &g_array_index(capture_opts
->all_ifaces
, interface_t
, i
);
921 if (device
->if_info
.type
!= IF_PIPE
&& device
->if_info
.type
!= IF_EXTCAP
) {
922 sc_item
= g_new0(if_stat_cache_item_t
, 1);
923 ws_assert(device
->if_info
.name
);
924 sc_item
->name
= g_strdup(device
->if_info
.name
);
925 sc
->cache_list
= g_list_prepend(sc
->cache_list
, sc_item
);
929 ws_warning("%s", msg
);
930 g_free(msg
); /* XXX: should we display this to the user via the GUI? */
936 capture_interface_stat_start(capture_options
*capture_opts _U_
, GList
**if_list
)
939 ws_process_id fork_child
;
941 if_stat_cache_t
*sc
= g_new0(if_stat_cache_t
, 1);
942 if_stat_cache_item_t
*sc_item
;
946 sc
->fork_child
= WS_INVALID_PID
;
948 /* Fire up dumpcap. */
950 * XXX - on systems with BPF, the number of BPF devices limits the
951 * number of devices on which you can capture simultaneously.
955 * 1) this might fail if you run out of BPF devices
959 * 2) opening every interface could leave too few BPF devices
960 * for *other* programs.
962 * It also means the system could end up getting a lot of traffic
963 * that it has to pass through the networking stack and capture
964 * mechanism, so opening all the devices and presenting packet
965 * counts might not always be a good idea.
967 /* XXX - We should use capture_opts to control whether we request
968 * the monitor_mode version of the supported link-types for interfaces.
971 iface_mon_enable(false);
972 status
= sync_interface_stats_open(&stat_fd
, &fork_child
, &data
, &msg
, NULL
);
973 iface_mon_enable(true);
974 /* In order to initialize the stat cache (below), we need to have
975 * filled in capture_opts->all_ifaces
977 * Note that the operation above can return a failed status but
978 * valid data, e.g. if dumpcap returns an interface list but none
979 * of them have permission to do a capture.
982 char *err_msg
= NULL
;
983 *if_list
= deserialize_interface_list(data
, &err
, &err_msg
);
985 ws_info("%s", err_msg
);
989 sc
->stat_fd
= stat_fd
;
990 sc
->fork_child
= fork_child
;
992 /* Initialize the cache */
993 for (GList
*if_entry
= *if_list
; if_entry
!= NULL
; if_entry
= g_list_next(if_entry
)) {
994 if_info_t
*if_info
= (if_info_t
*)if_entry
->data
;
995 /* We just got this list from dumpcap so it shouldn't
996 * contain stdin, pipes, extcaps, or remote interfaces
997 * list. We could test if_info->type and the name to
998 * exclude those types from the cache anyway, though.
1000 sc_item
= g_new0(if_stat_cache_item_t
, 1);
1001 ws_assert(if_info
->name
);
1002 sc_item
->name
= g_strdup(if_info
->name
);
1003 sc
->cache_list
= g_list_prepend(sc
->cache_list
, sc_item
);
1005 } else if (status
== WS_EXIT_NO_INTERFACES
) {
1007 * No interfaces were found. If that's not the
1008 * result of an error when fetching the local
1009 * interfaces, let the user know.
1012 g_free(msg
); /* XXX: should we display this to the user via the GUI? */
1014 ws_warning("%s", msg
);
1015 g_free(msg
); /* XXX: should we display this to the user via the GUI? */
1018 #ifdef HAVE_PCAP_REMOTE
1019 *if_list
= append_remote_list(*if_list
);
1022 *if_list
= append_extcap_interface_list(*if_list
);
1026 #define MAX_STAT_LINE_LEN 500
1029 capture_stat_cache_update(if_stat_cache_t
*sc
)
1031 char stat_line
[MAX_STAT_LINE_LEN
] = "";
1034 if_stat_cache_item_t
*sc_item
;
1036 if (!sc
|| sc
->fork_child
== WS_INVALID_PID
) {
1040 while (sync_pipe_gets_nonblock(sc
->stat_fd
, stat_line
, MAX_STAT_LINE_LEN
) > 0) {
1041 g_strstrip(stat_line
);
1042 stat_parts
= g_strsplit(stat_line
, "\t", 3);
1043 if (stat_parts
[0] == NULL
|| stat_parts
[1] == NULL
||
1044 stat_parts
[2] == NULL
) {
1045 g_strfreev(stat_parts
);
1048 for (sc_entry
= sc
->cache_list
; sc_entry
!= NULL
; sc_entry
= g_list_next(sc_entry
)) {
1049 sc_item
= (if_stat_cache_item_t
*)sc_entry
->data
;
1050 if (strcmp(sc_item
->name
, stat_parts
[0]) == 0) {
1051 sc_item
->ps
.ps_recv
= (u_int
) strtoul(stat_parts
[1], NULL
, 10);
1052 sc_item
->ps
.ps_drop
= (u_int
) strtoul(stat_parts
[2], NULL
, 10);
1055 g_strfreev(stat_parts
);
1060 capture_stats(if_stat_cache_t
*sc
, char *ifname
, struct pcap_stat
*ps
)
1063 if_stat_cache_item_t
*sc_item
;
1065 if (!sc
|| sc
->fork_child
== WS_INVALID_PID
|| !ifname
|| !ps
) {
1069 capture_stat_cache_update(sc
);
1070 for (sc_entry
= sc
->cache_list
; sc_entry
!= NULL
; sc_entry
= g_list_next(sc_entry
)) {
1071 sc_item
= (if_stat_cache_item_t
*)sc_entry
->data
;
1072 if (strcmp(sc_item
->name
, ifname
) == 0) {
1073 memcpy(ps
, &sc_item
->ps
, sizeof(struct pcap_stat
));
1081 capture_stat_stop(if_stat_cache_t
*sc
)
1084 if_stat_cache_item_t
*sc_item
;
1092 if (sc
->fork_child
!= WS_INVALID_PID
) {
1093 ret
= sync_interface_stats_close(&sc
->stat_fd
, &sc
->fork_child
, &msg
);
1095 /* XXX - report failure? */
1100 for (sc_entry
= sc
->cache_list
; sc_entry
!= NULL
; sc_entry
= g_list_next(sc_entry
)) {
1101 sc_item
= (if_stat_cache_item_t
*)sc_entry
->data
;
1102 g_free(sc_item
->name
);
1105 g_list_free(sc
->cache_list
);
1109 /* Initialize a capture session for our callbacks. */
1111 capture_input_init(capture_session
*cap_session
, capture_file
*cf
)
1113 capture_session_init(cap_session
, cf
,
1114 capture_input_new_file
, capture_input_new_packets
,
1115 capture_input_drops
, capture_input_error
,
1116 capture_input_cfilter_error
, capture_input_closed
);
1118 #endif /* HAVE_LIBPCAP */