2 * Routines for packet capture
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
43 #ifdef HAVE_SYS_TYPES_H
44 #include <sys/types.h>
47 #ifdef HAVE_SYS_SOCKET_H
48 #include <sys/socket.h>
51 #ifdef HAVE_NETINET_IN_H
52 #include <netinet/in.h>
55 #ifdef HAVE_SYS_SOCKET_H
56 #include <sys/socket.h> /* needed to define AF_ values on UNIX */
59 #ifdef HAVE_WINSOCK2_H
60 #include <winsock2.h> /* needed to define AF_ values on Windows */
63 #ifdef NEED_INET_V6DEFS_H
64 # include "inet_v6defs.h"
72 #include <epan/packet.h>
73 #include <epan/dfilter/dfilter.h>
74 #include <epan/ws_strsplit.h>
77 #include "capture_sync.h"
78 #include "capture_info.h"
79 #include "capture_ui_utils.h"
81 #include "capture-pcap-util.h"
82 #include "alert_box.h"
83 #include "simple_dialog.h"
84 #include <epan/prefs.h>
85 #include "conditions.h"
86 #include "ringbuffer.h"
89 #include "capture-wpcap.h"
92 #include "file_util.h"
100 * @return TRUE if the capture starts successfully, FALSE otherwise.
103 capture_start(capture_options *capture_opts)
108 /* close the currently loaded capture file */
109 cf_close(capture_opts->cf);
111 g_assert(capture_opts->state == CAPTURE_STOPPED);
112 capture_opts->state = CAPTURE_PREPARING;
114 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Start ...");
116 /* try to start the capture child process */
117 ret = sync_pipe_start(capture_opts);
119 if(capture_opts->save_file != NULL) {
120 g_free(capture_opts->save_file);
121 capture_opts->save_file = NULL;
124 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Start failed!");
125 capture_opts->state = CAPTURE_STOPPED;
127 /* the capture child might not respond shortly after bringing it up */
128 /* (especially it will block, if no input coming from an input capture pipe (e.g. mkfifo) is coming in) */
130 /* to prevent problems, bring the main GUI into "capture mode" right after successfully */
131 /* spawn/exec the capture child, without waiting for any response from it */
132 cf_callback_invoke(cf_cb_live_capture_prepared, capture_opts);
134 if(capture_opts->show_info)
135 capture_info_open(capture_opts->iface);
143 capture_stop(capture_options *capture_opts)
145 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Stop ...");
147 cf_callback_invoke(cf_cb_live_capture_stopping, capture_opts);
149 /* stop the capture child gracefully */
150 sync_pipe_stop(capture_opts);
155 capture_restart(capture_options *capture_opts)
157 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Restart");
159 capture_opts->restart = TRUE;
160 capture_stop(capture_opts);
165 capture_kill_child(capture_options *capture_opts)
167 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "Capture Kill");
169 /* kill the capture child */
170 sync_pipe_kill(capture_opts->fork_child);
175 /* We've succeeded a (non real-time) capture, try to read it into a new capture file */
177 capture_input_read_all(capture_options *capture_opts, gboolean is_tempfile, gboolean drops_known,
183 /* Capture succeeded; attempt to open the capture file. */
184 if (cf_open(capture_opts->cf, capture_opts->save_file, is_tempfile, &err) != CF_OK) {
185 /* We're not doing a capture any more, so we don't have a save
190 /* Set the read filter to NULL. */
191 /* XXX - this is odd here, try to put it somewhere, where it fits better */
192 cf_set_rfcode(capture_opts->cf, NULL);
194 /* Get the packet-drop statistics.
196 XXX - there are currently no packet-drop statistics stored
197 in libpcap captures, and that's what we're reading.
199 At some point, we will add support in Wiretap to return
200 packet-drop statistics for capture file formats that store it,
201 and will make "cf_read()" get those statistics from Wiretap.
202 We clear the statistics (marking them as "not known") in
203 "cf_open()", and "cf_read()" will only fetch them and mark
204 them as known if Wiretap supplies them, so if we get the
205 statistics now, after calling "cf_open()" but before calling
206 "cf_read()", the values we store will be used by "cf_read()".
208 If a future libpcap capture file format stores the statistics,
209 we'll put them into the capture file that we write, and will
210 thus not have to set them here - "cf_read()" will get them from
211 the file and use them. */
213 cf_set_drops_known(capture_opts->cf, TRUE);
215 /* XXX - on some systems, libpcap doesn't bother filling in
216 "ps_ifdrop" - it doesn't even set it to zero - so we don't
217 bother looking at it.
219 Ideally, libpcap would have an interface that gave us
220 several statistics - perhaps including various interface
221 error statistics - and would tell us which of them it
222 supplies, allowing us to display only the ones it does. */
223 cf_set_drops(capture_opts->cf, drops);
226 /* read in the packet data */
227 switch (cf_read(capture_opts->cf)) {
231 /* Just because we got an error, that doesn't mean we were unable
232 to read any of the file; we handle what we could get from the
236 case CF_READ_ABORTED:
237 /* User wants to quit program. Exit by leaving the main loop,
238 so that any quit functions we registered get called. */
239 main_window_nested_quit();
243 /* if we didn't captured even a single packet, close the file again */
244 if(cf_get_packet_count(capture_opts->cf) == 0 && !capture_opts->restart) {
245 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
246 "%sNo packets captured!%s\n"
248 "As no data was captured, closing the %scapture file!\n"
251 "Help about capturing can be found at:\n"
253 " http://wiki.wireshark.org/CaptureSetup"
256 "Wireless (Wi-Fi/WLAN):\n"
257 "Try to switch off promiscuous mode in the Capture Options!"
260 simple_dialog_primary_start(), simple_dialog_primary_end(),
261 (cf_is_tempfile(capture_opts->cf)) ? "temporary " : "");
262 cf_close(capture_opts->cf);
268 /* capture child tells us we have a new (or the first) capture file */
270 capture_input_new_file(capture_options *capture_opts, gchar *new_file)
272 gboolean is_tempfile;
276 if(capture_opts->state == CAPTURE_PREPARING) {
277 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture started!");
279 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "File: \"%s\"", new_file);
281 g_assert(capture_opts->state == CAPTURE_PREPARING || capture_opts->state == CAPTURE_RUNNING);
283 /* free the old filename */
284 if(capture_opts->save_file != NULL) {
285 /* we start a new capture file, close the old one (if we had one before) */
286 /* (we can only have an open capture file in real_time_mode!) */
287 if( ((capture_file *) capture_opts->cf)->state != FILE_CLOSED) {
288 cf_callback_invoke(cf_cb_live_capture_update_finished, capture_opts->cf);
289 cf_finish_tail(capture_opts->cf, &err);
290 cf_close(capture_opts->cf);
292 g_free(capture_opts->save_file);
294 cf_set_tempfile(capture_opts->cf, FALSE);
296 /* we didn't had a save_file before, must be a tempfile */
298 cf_set_tempfile(capture_opts->cf, TRUE);
301 /* save the new filename */
302 capture_opts->save_file = g_strdup(new_file);
304 /* if we are in real-time mode, open the new file now */
305 if(capture_opts->real_time_mode) {
306 /* Attempt to open the capture file and set up to read from it. */
307 switch(cf_start_tail(capture_opts->cf, capture_opts->save_file, is_tempfile, &err)) {
311 /* Don't unlink (delete) the save file - leave it around,
312 for debugging purposes. */
313 g_free(capture_opts->save_file);
314 capture_opts->save_file = NULL;
320 if(capture_opts->show_info) {
321 if (!capture_info_new_file(new_file))
325 if(capture_opts->real_time_mode) {
326 cf_callback_invoke(cf_cb_live_capture_update_started, capture_opts);
328 cf_callback_invoke(cf_cb_live_capture_fixed_started, capture_opts);
330 capture_opts->state = CAPTURE_RUNNING;
336 /* capture child tells us we have new packets to read */
338 capture_input_new_packets(capture_options *capture_opts, int to_read)
343 g_assert(capture_opts->save_file);
345 if(capture_opts->real_time_mode) {
346 /* Read from the capture file the number of records the child told us it added. */
347 switch (cf_continue_tail(capture_opts->cf, to_read, &err)) {
351 /* Just because we got an error, that doesn't mean we were unable
352 to read any of the file; we handle what we could get from the
355 XXX - abort on a read error? */
356 cf_callback_invoke(cf_cb_live_capture_update_continue, capture_opts->cf);
359 case CF_READ_ABORTED:
360 /* Kill the child capture process; the user wants to exit, and we
361 shouldn't just leave it running. */
362 capture_kill_child(capture_opts);
366 /* increase capture file packet counter by the number or incoming packets */
367 cf_set_packet_count(capture_opts->cf,
368 cf_get_packet_count(capture_opts->cf) + to_read);
370 cf_callback_invoke(cf_cb_live_capture_fixed_continue, capture_opts->cf);
373 /* update the main window, so we get events (e.g. from the stop toolbar button) */
374 main_window_update();
376 if(capture_opts->show_info)
377 capture_info_new_packets(to_read);
381 /* Capture child told us how many dropped packets it counted.
384 capture_input_drops(capture_options *capture_opts, int dropped)
386 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "%d packet%s dropped", dropped, plurality(dropped, "", "s"));
388 g_assert(capture_opts->state == CAPTURE_RUNNING);
390 cf_set_drops_known(capture_opts->cf, TRUE);
391 cf_set_drops(capture_opts->cf, dropped);
395 /* Capture child told us that an error has occurred while starting/running
397 The buffer we're handed has *two* null-terminated strings in it - a
398 primary message and a secondary message, one right after the other.
399 The secondary message might be a null string.
402 capture_input_error_message(capture_options *capture_opts, char *error_msg, char *secondary_error_msg)
404 gchar *safe_error_msg;
405 gchar *safe_secondary_error_msg;
407 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Error message from child: \"%s\", \"%s\"",
408 error_msg, secondary_error_msg);
410 g_assert(capture_opts->state == CAPTURE_PREPARING || capture_opts->state == CAPTURE_RUNNING);
412 safe_error_msg = simple_dialog_format_message(error_msg);
413 if (*secondary_error_msg != '\0') {
414 /* We have both primary and secondary messages. */
415 safe_secondary_error_msg = simple_dialog_format_message(secondary_error_msg);
416 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s%s%s\n\n%s",
417 simple_dialog_primary_start(), safe_error_msg,
418 simple_dialog_primary_end(), safe_secondary_error_msg);
419 g_free(safe_secondary_error_msg);
421 /* We have only a primary message. */
422 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s%s%s",
423 simple_dialog_primary_start(), safe_error_msg,
424 simple_dialog_primary_end());
426 g_free(safe_error_msg);
428 /* the capture child will close the sync_pipe if required, nothing to do for now */
433 /* Capture child told us that an error has occurred while parsing a
434 capture filter when starting/running the capture.
437 capture_input_cfilter_error_message(capture_options *capture_opts, char *error_message)
439 dfilter_t *rfcode = NULL;
440 gchar *safe_cfilter = simple_dialog_format_message(capture_opts->cfilter);
441 gchar *safe_cfilter_error_msg = simple_dialog_format_message(error_message);
443 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture filter error message from child: \"%s\"", error_message);
445 g_assert(capture_opts->state == CAPTURE_PREPARING || capture_opts->state == CAPTURE_RUNNING);
447 /* Did the user try a display filter? */
448 if (dfilter_compile(capture_opts->cfilter, &rfcode) && rfcode != NULL) {
449 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
450 "%sInvalid capture filter: \"%s\"!%s\n"
452 "That string looks like a valid display filter; however, it isn't a valid\n"
453 "capture filter (%s).\n"
455 "Note that display filters and capture filters don't have the same syntax,\n"
456 "so you can't use most display filter expressions as capture filters.\n"
458 "See the User's Guide for a description of the capture filter syntax.",
459 simple_dialog_primary_start(), safe_cfilter,
460 simple_dialog_primary_end(), safe_cfilter_error_msg);
461 dfilter_free(rfcode);
463 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
464 "%sInvalid capture filter: \"%s\"!%s\n"
466 "That string isn't a valid capture filter (%s).\n"
467 "See the User's Guide for a description of the capture filter syntax.",
468 simple_dialog_primary_start(), safe_cfilter,
469 simple_dialog_primary_end(), safe_cfilter_error_msg);
471 g_free(safe_cfilter_error_msg);
472 g_free(safe_cfilter);
474 /* the capture child will close the sync_pipe if required, nothing to do for now */
478 /* capture child closed its side of the pipe, do the required cleanup */
480 capture_input_closed(capture_options *capture_opts)
483 int packet_count_save;
485 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture stopped!");
486 g_assert(capture_opts->state == CAPTURE_PREPARING || capture_opts->state == CAPTURE_RUNNING);
488 /* if we didn't started the capture, do a fake start */
489 /* (happens if we got an error message - we won't get a filename then) */
490 if(capture_opts->state == CAPTURE_PREPARING) {
491 if(capture_opts->real_time_mode) {
492 cf_callback_invoke(cf_cb_live_capture_update_started, capture_opts);
494 cf_callback_invoke(cf_cb_live_capture_fixed_started, capture_opts);
498 if(capture_opts->real_time_mode) {
499 cf_read_status_t status;
501 /* Read what remains of the capture file. */
502 status = cf_finish_tail(capture_opts->cf, &err);
504 /* XXX: If -Q (quit-after-cap) then cf->count clr'd below so save it first */
505 packet_count_save = cf_get_packet_count(capture_opts->cf);
506 /* Tell the GUI, we are not doing a capture any more.
507 Must be done after the cf_finish_tail(), so file lengths are displayed
509 cf_callback_invoke(cf_cb_live_capture_update_finished, capture_opts->cf);
511 /* Finish the capture. */
515 if ((packet_count_save == 0) && !capture_opts->restart) {
516 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
517 "%sNo packets captured!%s\n"
519 "As no data was captured, closing the %scapture file!\n"
522 "Help about capturing can be found at:\n"
524 " http://wiki.wireshark.org/CaptureSetup"
527 "Wireless (Wi-Fi/WLAN):\n"
528 "Try to switch off promiscuous mode in the Capture Options!"
531 simple_dialog_primary_start(), simple_dialog_primary_end(),
532 cf_is_tempfile(capture_opts->cf) ? "temporary " : "");
533 cf_close(capture_opts->cf);
537 /* Just because we got an error, that doesn't mean we were unable
538 to read any of the file; we handle what we could get from the
542 case CF_READ_ABORTED:
543 /* Exit by leaving the main loop, so that any quit functions
544 we registered get called. */
549 /* first of all, we are not doing a capture any more */
550 cf_callback_invoke(cf_cb_live_capture_fixed_finished, capture_opts->cf);
552 /* this is a normal mode capture and if no error happened, read in the capture file data */
553 if(capture_opts->save_file != NULL) {
554 capture_input_read_all(capture_opts, cf_is_tempfile(capture_opts->cf),
555 cf_get_drops_known(capture_opts->cf), cf_get_drops(capture_opts->cf));
559 if(capture_opts->show_info)
560 capture_info_close();
562 capture_opts->state = CAPTURE_STOPPED;
564 /* if we couldn't open a capture file, there's nothing more for us to do */
565 if(capture_opts->save_file == NULL) {
566 cf_close(capture_opts->cf);
570 /* does the user wants to restart the current capture? */
571 if(capture_opts->restart) {
572 capture_opts->restart = FALSE;
574 eth_unlink(capture_opts->save_file);
576 /* if it was a tempfile, throw away the old filename (so it will become a tempfile again) */
577 if(cf_is_tempfile(capture_opts->cf)) {
578 g_free(capture_opts->save_file);
579 capture_opts->save_file = NULL;
582 /* ... and start the capture again */
583 capture_start(capture_opts);
585 /* We're not doing a capture any more, so we don't have a save file. */
586 g_free(capture_opts->save_file);
587 capture_opts->save_file = NULL;
592 * Fetch the interface list from a child process (dumpcap).
594 * @return A GList containing if_info_t structs if successful, NULL otherwise.
597 /* XXX - We parse simple text output to get our interface list. Should
598 * we use "real" data serialization instead, e.g. via XML? */
600 capture_interface_list(int *err, char **err_str)
602 GList *if_list = NULL;
605 gchar **raw_list, **if_parts, **addr_parts;
610 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface List ...");
612 /* Try to get our interface list */
613 *err = sync_interface_list_open(&msg);
615 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface List failed!");
627 /* Split our lines */
628 raw_list = g_strsplit(msg, "\n", 0);
631 for (i = 0; raw_list[i] != NULL; i++) {
632 if_parts = g_strsplit(raw_list[i], "\t", 4);
633 if (if_parts[0] == NULL || if_parts[1] == NULL || if_parts[2] == NULL ||
634 if_parts[3] == NULL) {
635 g_strfreev(if_parts);
639 /* Number followed by the name, e.g "1. eth0" */
640 name = strchr(if_parts[0], ' ');
644 g_strfreev(if_parts);
648 if_info = g_malloc0(sizeof(if_info_t));
649 if_info->name = g_strdup(name);
650 if (strlen(if_parts[1]) > 0)
651 if_info->description = g_strdup(if_parts[1]);
652 addr_parts = g_strsplit(if_parts[2], ",", 0);
653 for (j = 0; addr_parts[j] != NULL; j++) {
654 if_addr = g_malloc0(sizeof(if_addr_t));
655 if (inet_pton(AF_INET, addr_parts[j], &if_addr->ip_addr.ip4_addr)) {
656 if_addr->type = AT_IPv4;
657 } else if (inet_pton(AF_INET6, addr_parts[j],
658 &if_addr->ip_addr.ip6_addr)) {
659 if_addr->type = AT_IPv6;
665 if_info->ip_addr = g_slist_append(if_info->ip_addr, if_addr);
668 if (strcmp(if_parts[3], "loopback") == 0)
669 if_info->loopback = TRUE;
670 g_strfreev(if_parts);
671 g_strfreev(addr_parts);
672 if_list = g_list_append(if_list, if_info);
674 g_strfreev(raw_list);
676 /* Check to see if we built a list */
677 if (if_list == NULL) {
679 *err_str = g_strdup("No interfaces found");
680 *err = NO_INTERFACES_FOUND;
686 #endif /* HAVE_LIBPCAP */