2 * Routines for packet capture
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
37 #include <epan/packet.h>
38 #include <epan/dfilter/dfilter.h>
40 #include "ui/capture.h"
41 #include "caputils/capture_ifinfo.h"
42 #include <capchild/capture_sync.h>
43 #include "capture_info.h"
44 #include "ui/capture_ui_utils.h"
46 #include "caputils/capture-pcap-util.h"
47 #include <epan/prefs.h>
50 #include "caputils/capture-wpcap.h"
53 #include "ui/simple_dialog.h"
54 #include "ui/ui_util.h"
56 #include "wsutil/file_util.h"
59 typedef struct if_stat_cache_item_s {
62 } if_stat_cache_item_t;
64 struct if_stat_cache_s {
66 ws_process_id fork_child;
67 GList *cache_list; /* List of if_stat_chache_entry_t */
70 /* this callback mechanism should possibly be replaced by the g_signal_...() stuff (if I only would know how :-) */
72 capture_callback_t cb_fct;
74 } capture_callback_data_t;
76 static GList *capture_callbacks = NULL;
79 capture_callback_invoke(int event, capture_session *cap_session)
81 capture_callback_data_t *cb;
82 GList *cb_item = capture_callbacks;
84 /* there should be at least one interested */
85 g_assert(cb_item != NULL);
87 while(cb_item != NULL) {
88 cb = (capture_callback_data_t *)cb_item->data;
89 cb->cb_fct(event, cap_session, cb->user_data);
90 cb_item = g_list_next(cb_item);
96 capture_callback_add(capture_callback_t func, gpointer user_data)
98 capture_callback_data_t *cb;
100 cb = (capture_callback_data_t *)g_malloc(sizeof(capture_callback_data_t));
102 cb->user_data = user_data;
104 capture_callbacks = g_list_append(capture_callbacks, cb);
108 capture_callback_remove(capture_callback_t func, gpointer user_data)
110 capture_callback_data_t *cb;
111 GList *cb_item = capture_callbacks;
113 while(cb_item != NULL) {
114 cb = (capture_callback_data_t *)cb_item->data;
115 if(cb->cb_fct == func && cb->user_data == user_data) {
116 capture_callbacks = g_list_remove(capture_callbacks, cb);
120 cb_item = g_list_next(cb_item);
123 g_assert_not_reached();
129 * @return TRUE if the capture starts successfully, FALSE otherwise.
132 capture_start(capture_options *capture_opts, capture_session *cap_session, void(*update_cb)(void))
137 cap_session->state = CAPTURE_PREPARING;
138 cap_session->count = 0;
139 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Start ...");
140 source = get_iface_list_string(capture_opts, IFLIST_SHOW_FILTER);
141 cf_set_tempfile_source((capture_file *)cap_session->cf, source->str);
142 g_string_free(source, TRUE);
143 /* try to start the capture child process */
144 ret = sync_pipe_start(capture_opts, cap_session, update_cb);
146 if(capture_opts->save_file != NULL) {
147 g_free(capture_opts->save_file);
148 capture_opts->save_file = NULL;
151 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Start failed.");
152 cap_session->state = CAPTURE_STOPPED;
154 /* the capture child might not respond shortly after bringing it up */
155 /* (for example: it will block if no input arrives from an input capture pipe (e.g. mkfifo)) */
157 /* to prevent problems, bring the main GUI into "capture mode" right after a successful */
158 /* spawn/exec of the capture child, without waiting for any response from it */
159 capture_callback_invoke(capture_cb_capture_prepared, cap_session);
161 if(capture_opts->show_info)
162 capture_info_open(cap_session);
170 capture_stop(capture_session *cap_session)
172 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Stop ...");
174 capture_callback_invoke(capture_cb_capture_stopping, cap_session);
176 /* stop the capture child gracefully */
177 sync_pipe_stop(cap_session);
182 capture_restart(capture_session *cap_session)
184 capture_options *capture_opts = cap_session->capture_opts;
186 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Restart");
188 capture_opts->restart = TRUE;
189 capture_stop(cap_session);
194 capture_kill_child(capture_session *cap_session)
196 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "Capture Kill");
198 /* kill the capture child */
199 sync_pipe_kill(cap_session->fork_child);
202 /* We've succeeded in doing a (non real-time) capture; try to read it into a new capture file */
204 capture_input_read_all(capture_session *cap_session, gboolean is_tempfile,
205 gboolean drops_known, guint32 drops)
207 capture_options *capture_opts = cap_session->capture_opts;
210 /* Capture succeeded; attempt to open the capture file. */
211 if (cf_open((capture_file *)cap_session->cf, capture_opts->save_file, WTAP_TYPE_AUTO, is_tempfile, &err) != CF_OK) {
212 /* We're not doing a capture any more, so we don't have a save file. */
216 /* Set the read filter to NULL. */
217 /* XXX - this is odd here; try to put it somewhere where it fits better */
218 cf_set_rfcode((capture_file *)cap_session->cf, NULL);
220 /* Get the packet-drop statistics.
222 XXX - there are currently no packet-drop statistics stored
223 in libpcap captures, and that's what we're reading.
225 At some point, we will add support in Wiretap to return
226 packet-drop statistics for capture file formats that store it,
227 and will make "cf_read()" get those statistics from Wiretap.
228 We clear the statistics (marking them as "not known") in
229 "cf_open()", and "cf_read()" will only fetch them and mark
230 them as known if Wiretap supplies them, so if we get the
231 statistics now, after calling "cf_open()" but before calling
232 "cf_read()", the values we store will be used by "cf_read()".
234 If a future libpcap capture file format stores the statistics,
235 we'll put them into the capture file that we write, and will
236 thus not have to set them here - "cf_read()" will get them from
237 the file and use them. */
239 cf_set_drops_known((capture_file *)cap_session->cf, TRUE);
241 /* XXX - on some systems, libpcap doesn't bother filling in
242 "ps_ifdrop" - it doesn't even set it to zero - so we don't
243 bother looking at it.
245 Ideally, libpcap would have an interface that gave us
246 several statistics - perhaps including various interface
247 error statistics - and would tell us which of them it
248 supplies, allowing us to display only the ones it does. */
249 cf_set_drops((capture_file *)cap_session->cf, drops);
252 /* read in the packet data */
253 switch (cf_read((capture_file *)cap_session->cf, FALSE)) {
257 /* Just because we got an error, that doesn't mean we were unable
258 to read any of the file; we handle what we could get from the
262 case CF_READ_ABORTED:
263 /* User wants to quit program. Exit by leaving the main loop,
264 so that any quit functions we registered get called. */
265 main_window_nested_quit();
269 /* if we didn't capture even a single packet, close the file again */
270 if(cap_session->count == 0 && !capture_opts->restart) {
271 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
272 "%sNo packets captured.%s\n"
274 "As no data was captured, closing the %scapture file.\n"
277 "Help about capturing can be found at\n"
279 " https://wiki.wireshark.org/CaptureSetup"
282 "Wireless (Wi-Fi/WLAN):\n"
283 "Try to switch off promiscuous mode in the Capture Options"
286 simple_dialog_primary_start(), simple_dialog_primary_end(),
287 (cf_is_tempfile((capture_file *)cap_session->cf)) ? "temporary " : "");
288 cf_close((capture_file *)cap_session->cf);
294 /* capture child tells us we have a new (or the first) capture file */
296 capture_input_new_file(capture_session *cap_session, gchar *new_file)
298 capture_options *capture_opts = cap_session->capture_opts;
299 gboolean is_tempfile;
302 if(cap_session->state == CAPTURE_PREPARING) {
303 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture started");
305 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "File: \"%s\"", new_file);
307 g_assert(cap_session->state == CAPTURE_PREPARING || cap_session->state == CAPTURE_RUNNING);
309 /* free the old filename */
310 if(capture_opts->save_file != NULL) {
311 /* we start a new capture file, close the old one (if we had one before). */
312 /* (we can only have an open capture file in real_time_mode!) */
313 if( ((capture_file *) cap_session->cf)->state != FILE_CLOSED) {
314 if(capture_opts->real_time_mode) {
315 capture_callback_invoke(capture_cb_capture_update_finished, cap_session);
316 cf_finish_tail((capture_file *)cap_session->cf, &err);
317 cf_close((capture_file *)cap_session->cf);
319 capture_callback_invoke(capture_cb_capture_fixed_finished, cap_session);
322 g_free(capture_opts->save_file);
324 cf_set_tempfile((capture_file *)cap_session->cf, FALSE);
326 /* we didn't have a save_file before; must be a tempfile */
328 cf_set_tempfile((capture_file *)cap_session->cf, TRUE);
331 /* save the new filename */
332 capture_opts->save_file = g_strdup(new_file);
334 /* if we are in real-time mode, open the new file now */
335 if(capture_opts->real_time_mode) {
336 /* Attempt to open the capture file and set up to read from it. */
337 switch(cf_open((capture_file *)cap_session->cf, capture_opts->save_file, WTAP_TYPE_AUTO, is_tempfile, &err)) {
341 /* Don't unlink (delete) the save file - leave it around,
342 for debugging purposes. */
343 g_free(capture_opts->save_file);
344 capture_opts->save_file = NULL;
348 capture_callback_invoke(capture_cb_capture_prepared, cap_session);
351 if(capture_opts->show_info) {
352 if (!capture_info_new_file(new_file))
356 if(capture_opts->real_time_mode) {
357 capture_callback_invoke(capture_cb_capture_update_started, cap_session);
359 capture_callback_invoke(capture_cb_capture_fixed_started, cap_session);
361 cap_session->state = CAPTURE_RUNNING;
367 /* capture child tells us we have new packets to read */
369 capture_input_new_packets(capture_session *cap_session, int to_read)
371 capture_options *capture_opts = cap_session->capture_opts;
374 g_assert(capture_opts->save_file);
376 if(capture_opts->real_time_mode) {
377 /* Read from the capture file the number of records the child told us it added. */
378 switch (cf_continue_tail((capture_file *)cap_session->cf, to_read, &err)) {
382 /* Just because we got an error, that doesn't mean we were unable
383 to read any of the file; we handle what we could get from the
386 XXX - abort on a read error? */
387 capture_callback_invoke(capture_cb_capture_update_continue, cap_session);
390 case CF_READ_ABORTED:
391 /* Kill the child capture process; the user wants to exit, and we
392 shouldn't just leave it running. */
393 capture_kill_child(cap_session);
397 cf_fake_continue_tail((capture_file *)cap_session->cf);
399 capture_callback_invoke(capture_cb_capture_fixed_continue, cap_session);
402 /* update the main window so we get events (e.g. from the stop toolbar button) */
403 /* This causes a hang on Windows (see bug 7305). Do we need this on any platform? */
405 main_window_update();
408 if(capture_opts->show_info)
409 capture_info_new_packets(to_read);
413 /* Capture child told us how many dropped packets it counted.
416 capture_input_drops(capture_session *cap_session, guint32 dropped)
418 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "%u packet%s dropped", dropped, plurality(dropped, "", "s"));
420 g_assert(cap_session->state == CAPTURE_RUNNING);
422 cf_set_drops_known((capture_file *)cap_session->cf, TRUE);
423 cf_set_drops((capture_file *)cap_session->cf, dropped);
427 /* Capture child told us that an error has occurred while starting/running
429 The buffer we're handed has *two* null-terminated strings in it - a
430 primary message and a secondary message, one right after the other.
431 The secondary message might be a null string.
434 capture_input_error_message(capture_session *cap_session, char *error_msg,
435 char *secondary_error_msg)
437 gchar *safe_error_msg;
438 gchar *safe_secondary_error_msg;
440 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Error message from child: \"%s\", \"%s\"",
441 error_msg, secondary_error_msg);
443 g_assert(cap_session->state == CAPTURE_PREPARING || cap_session->state == CAPTURE_RUNNING);
445 safe_error_msg = simple_dialog_format_message(error_msg);
446 if (*secondary_error_msg != '\0') {
447 /* We have both primary and secondary messages. */
448 safe_secondary_error_msg = simple_dialog_format_message(secondary_error_msg);
449 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s%s%s\n\n%s",
450 simple_dialog_primary_start(), safe_error_msg,
451 simple_dialog_primary_end(), safe_secondary_error_msg);
452 g_free(safe_secondary_error_msg);
454 /* We have only a primary message. */
455 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s%s%s",
456 simple_dialog_primary_start(), safe_error_msg,
457 simple_dialog_primary_end());
459 g_free(safe_error_msg);
461 /* the capture child will close the sync_pipe if required, nothing to do for now */
464 /* Capture child told us that an error has occurred while parsing a
465 capture filter when starting/running the capture.
468 capture_input_cfilter_error_message(capture_session *cap_session, guint i,
471 capture_options *capture_opts = cap_session->capture_opts;
472 dfilter_t *rfcode = NULL;
475 gchar *safe_cfilter_error_msg;
476 interface_options interface_opts;
478 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture filter error message from child: \"%s\"", error_message);
480 g_assert(cap_session->state == CAPTURE_PREPARING || cap_session->state == CAPTURE_RUNNING);
481 g_assert(i < capture_opts->ifaces->len);
483 interface_opts = g_array_index(capture_opts->ifaces, interface_options, i);
484 safe_cfilter = simple_dialog_format_message(interface_opts.cfilter);
485 safe_descr = simple_dialog_format_message(interface_opts.descr);
486 safe_cfilter_error_msg = simple_dialog_format_message(error_message);
487 /* Did the user try a display filter? */
488 if (dfilter_compile(interface_opts.cfilter, &rfcode, NULL) && rfcode != NULL) {
489 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
490 "%sInvalid capture filter \"%s\" for interface %s.%s\n"
492 "That string looks like a valid display filter; however, it isn't a valid\n"
493 "capture filter (%s).\n"
495 "Note that display filters and capture filters don't have the same syntax,\n"
496 "so you can't use most display filter expressions as capture filters.\n"
498 "See the User's Guide for a description of the capture filter syntax.",
499 simple_dialog_primary_start(), safe_cfilter, safe_descr,
500 simple_dialog_primary_end(), safe_cfilter_error_msg);
501 dfilter_free(rfcode);
503 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
504 "%sInvalid capture filter \"%s\" for interface %s.%s\n"
506 "That string isn't a valid capture filter (%s).\n"
507 "See the User's Guide for a description of the capture filter syntax.",
508 simple_dialog_primary_start(), safe_cfilter, safe_descr,
509 simple_dialog_primary_end(), safe_cfilter_error_msg);
511 g_free(safe_cfilter_error_msg);
513 g_free(safe_cfilter);
515 /* the capture child will close the sync_pipe if required, nothing to do for now */
518 /* capture child closed its side of the pipe, do the required cleanup */
520 capture_input_closed(capture_session *cap_session, gchar *msg)
522 capture_options *capture_opts = cap_session->capture_opts;
525 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture stopped.");
526 g_assert(cap_session->state == CAPTURE_PREPARING || cap_session->state == CAPTURE_RUNNING);
529 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", msg);
531 if(cap_session->state == CAPTURE_PREPARING) {
532 /* We didn't start a capture; note that the attempt to start it
534 capture_callback_invoke(capture_cb_capture_failed, cap_session);
536 /* We started a capture; process what's left of the capture file if
537 we were in "update list of packets in real time" mode, or process
538 all of it if we weren't. */
539 if(capture_opts->real_time_mode) {
540 cf_read_status_t status;
542 /* Read what remains of the capture file. */
543 status = cf_finish_tail((capture_file *)cap_session->cf, &err);
545 /* Tell the GUI we are not doing a capture any more.
546 Must be done after the cf_finish_tail(), so file lengths are
547 correctly displayed */
548 capture_callback_invoke(capture_cb_capture_update_finished, cap_session);
550 /* Finish the capture. */
554 if (cap_session->count == 0 && !capture_opts->restart) {
555 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
556 "%sNo packets captured.%s\n"
558 "As no data was captured, closing the %scapture file.\n"
561 "Help about capturing can be found at\n"
563 " https://wiki.wireshark.org/CaptureSetup"
566 "Wireless (Wi-Fi/WLAN):\n"
567 "Try to switch off promiscuous mode in the Capture Options."
570 simple_dialog_primary_start(), simple_dialog_primary_end(),
571 cf_is_tempfile((capture_file *)cap_session->cf) ? "temporary " : "");
572 cf_close((capture_file *)cap_session->cf);
576 /* Just because we got an error, that doesn't mean we were unable
577 to read any of the file; we handle what we could get from the
581 case CF_READ_ABORTED:
582 /* Exit by leaving the main loop, so that any quit functions
583 we registered get called. */
588 /* first of all, we are not doing a capture any more */
589 capture_callback_invoke(capture_cb_capture_fixed_finished, cap_session);
591 /* this is a normal mode capture and if no error happened, read in the capture file data */
592 if(capture_opts->save_file != NULL) {
593 capture_input_read_all(cap_session, cf_is_tempfile((capture_file *)cap_session->cf),
594 cf_get_drops_known((capture_file *)cap_session->cf), cf_get_drops((capture_file *)cap_session->cf));
599 if(capture_opts->show_info)
600 capture_info_close();
602 cap_session->state = CAPTURE_STOPPED;
604 /* if we couldn't open a capture file, there's nothing more for us to do */
605 if(capture_opts->save_file == NULL) {
606 cf_close((capture_file *)cap_session->cf);
610 /* does the user wants to restart the current capture? */
611 if(capture_opts->restart) {
612 capture_opts->restart = FALSE;
614 ws_unlink(capture_opts->save_file);
616 /* If we have a ring buffer, the original save file has been overwritten
617 with the "ring filename". Restore it before starting again */
618 if ((capture_opts->multi_files_on) && (capture_opts->orig_save_file != NULL)) {
619 g_free(capture_opts->save_file);
620 capture_opts->save_file = g_strdup(capture_opts->orig_save_file);
623 /* if it was a tempfile, throw away the old filename (so it will become a tempfile again) */
624 if(cf_is_tempfile((capture_file *)cap_session->cf)) {
625 g_free(capture_opts->save_file);
626 capture_opts->save_file = NULL;
629 /* ... and start the capture again */
630 if (capture_opts->ifaces->len == 0) {
631 collect_ifaces(capture_opts);
634 /* close the currently loaded capture file */
635 cf_close((capture_file *)cap_session->cf);
637 capture_start(capture_opts, cap_session,NULL); /*XXX is this NULL ok or we need an update_cb???*/
639 /* We're not doing a capture any more, so we don't have a save file. */
640 g_free(capture_opts->save_file);
641 capture_opts->save_file = NULL;
646 capture_stat_start(capture_options *capture_opts) {
648 ws_process_id fork_child;
650 if_stat_cache_t *sc = NULL;
651 if_stat_cache_item_t *sc_item;
655 /* Fire up dumpcap. */
657 * XXX - on systems with BPF, the number of BPF devices limits the
658 * number of devices on which you can capture simultaneously.
662 * 1) this might fail if you run out of BPF devices
666 * 2) opening every interface could leave too few BPF devices
667 * for *other* programs.
669 * It also means the system could end up getting a lot of traffic
670 * that it has to pass through the networking stack and capture
671 * mechanism, so opening all the devices and presenting packet
672 * counts might not always be a good idea.
674 if (sync_interface_stats_open(&stat_fd, &fork_child, &msg, NULL) == 0) {
675 sc = (if_stat_cache_t *)g_malloc(sizeof(if_stat_cache_t));
676 sc->stat_fd = stat_fd;
677 sc->fork_child = fork_child;
678 sc->cache_list = NULL;
680 /* Initialize the cache */
681 for (i = 0; i < capture_opts->all_ifaces->len; i++) {
682 device = g_array_index(capture_opts->all_ifaces, interface_t, i);
683 if (device.type != IF_PIPE) {
684 sc_item = (if_stat_cache_item_t *)g_malloc0(sizeof(if_stat_cache_item_t));
685 sc_item->name = g_strdup(device.if_info.name);
686 sc->cache_list = g_list_append(sc->cache_list, sc_item);
690 g_free(msg); /* XXX: should we display this to the user ? */
695 #define MAX_STAT_LINE_LEN 500
698 capture_stat_cache_update(if_stat_cache_t *sc) {
699 gchar stat_line[MAX_STAT_LINE_LEN] = "";
702 if_stat_cache_item_t *sc_item;
707 while (sync_pipe_gets_nonblock(sc->stat_fd, stat_line, MAX_STAT_LINE_LEN) > 0) {
708 g_strstrip(stat_line);
709 stat_parts = g_strsplit(stat_line, "\t", 3);
710 if (stat_parts[0] == NULL || stat_parts[1] == NULL ||
711 stat_parts[2] == NULL) {
712 g_strfreev(stat_parts);
715 for (sc_entry = sc->cache_list; sc_entry != NULL; sc_entry = g_list_next(sc_entry)) {
716 sc_item = (if_stat_cache_item_t *)sc_entry->data;
717 if (strcmp(sc_item->name, stat_parts[0]) == 0) {
718 sc_item->ps.ps_recv = (u_int) strtoul(stat_parts[1], NULL, 10);
719 sc_item->ps.ps_drop = (u_int) strtoul(stat_parts[2], NULL, 10);
722 g_strfreev(stat_parts);
727 capture_stats(if_stat_cache_t *sc, char *ifname, struct pcap_stat *ps) {
729 if_stat_cache_item_t *sc_item;
731 if (!sc || !ifname || !ps) {
735 capture_stat_cache_update(sc);
736 for (sc_entry = sc->cache_list; sc_entry != NULL; sc_entry = g_list_next(sc_entry)) {
737 sc_item = (if_stat_cache_item_t *)sc_entry->data;
738 if (strcmp(sc_item->name, ifname) == 0) {
739 memcpy(ps, &sc_item->ps, sizeof(struct pcap_stat));
747 capture_stat_stop(if_stat_cache_t *sc) {
749 if_stat_cache_item_t *sc_item;
756 ret = sync_interface_stats_close(&sc->stat_fd, &sc->fork_child, &msg);
758 /* XXX - report failure? */
762 for (sc_entry = sc->cache_list; sc_entry != NULL; sc_entry = g_list_next(sc_entry)) {
763 sc_item = (if_stat_cache_item_t *)sc_entry->data;
764 g_free(sc_item->name);
770 #endif /* HAVE_LIBPCAP */
773 * Editor modelines - https://www.wireshark.org/tools/modelines.html
778 * indent-tabs-mode: nil
781 * ex: set shiftwidth=2 tabstop=8 expandtab:
782 * :indentSize=2:tabSize=8:noTabs=true: