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>
60 #include <epan/packet.h>
61 #include <epan/dfilter/dfilter.h>
62 #include <epan/ws_strsplit.h>
65 #include "capture_sync.h"
66 #include "capture_info.h"
67 #include "capture_ui_utils.h"
69 #include "capture-pcap-util.h"
70 #include "alert_box.h"
71 #include "simple_dialog.h"
72 #include <epan/prefs.h>
73 #include "conditions.h"
74 #include "ringbuffer.h"
77 #include "capture-wpcap.h"
80 #include "file_util.h"
88 * @return TRUE if the capture starts successfully, FALSE otherwise.
91 capture_start(capture_options *capture_opts)
96 /* close the currently loaded capture file */
97 cf_close(capture_opts->cf);
99 g_assert(capture_opts->state == CAPTURE_STOPPED);
100 capture_opts->state = CAPTURE_PREPARING;
102 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Start ...");
104 /* try to start the capture child process */
105 ret = sync_pipe_start(capture_opts);
107 if(capture_opts->save_file != NULL) {
108 g_free(capture_opts->save_file);
109 capture_opts->save_file = NULL;
112 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Start failed!");
113 capture_opts->state = CAPTURE_STOPPED;
115 /* the capture child might not respond shortly after bringing it up */
116 /* (especially it will block, if no input coming from an input capture pipe (e.g. mkfifo) is coming in) */
118 /* to prevent problems, bring the main GUI into "capture mode" right after successfully */
119 /* spawn/exec the capture child, without waiting for any response from it */
120 cf_callback_invoke(cf_cb_live_capture_prepared, capture_opts);
122 if(capture_opts->show_info)
123 capture_info_open(capture_opts->iface);
131 capture_stop(capture_options *capture_opts)
133 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Stop ...");
135 cf_callback_invoke(cf_cb_live_capture_stopping, capture_opts);
137 /* stop the capture child gracefully */
138 sync_pipe_stop(capture_opts);
143 capture_restart(capture_options *capture_opts)
145 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Restart");
147 capture_opts->restart = TRUE;
148 capture_stop(capture_opts);
153 capture_kill_child(capture_options *capture_opts)
155 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "Capture Kill");
157 /* kill the capture child */
158 sync_pipe_kill(capture_opts->fork_child);
163 /* We've succeeded a (non real-time) capture, try to read it into a new capture file */
165 capture_input_read_all(capture_options *capture_opts, gboolean is_tempfile, gboolean drops_known,
171 /* Capture succeeded; attempt to open the capture file. */
172 if (cf_open(capture_opts->cf, capture_opts->save_file, is_tempfile, &err) != CF_OK) {
173 /* We're not doing a capture any more, so we don't have a save
178 /* Set the read filter to NULL. */
179 /* XXX - this is odd here, try to put it somewhere, where it fits better */
180 cf_set_rfcode(capture_opts->cf, NULL);
182 /* Get the packet-drop statistics.
184 XXX - there are currently no packet-drop statistics stored
185 in libpcap captures, and that's what we're reading.
187 At some point, we will add support in Wiretap to return
188 packet-drop statistics for capture file formats that store it,
189 and will make "cf_read()" get those statistics from Wiretap.
190 We clear the statistics (marking them as "not known") in
191 "cf_open()", and "cf_read()" will only fetch them and mark
192 them as known if Wiretap supplies them, so if we get the
193 statistics now, after calling "cf_open()" but before calling
194 "cf_read()", the values we store will be used by "cf_read()".
196 If a future libpcap capture file format stores the statistics,
197 we'll put them into the capture file that we write, and will
198 thus not have to set them here - "cf_read()" will get them from
199 the file and use them. */
201 cf_set_drops_known(capture_opts->cf, TRUE);
203 /* XXX - on some systems, libpcap doesn't bother filling in
204 "ps_ifdrop" - it doesn't even set it to zero - so we don't
205 bother looking at it.
207 Ideally, libpcap would have an interface that gave us
208 several statistics - perhaps including various interface
209 error statistics - and would tell us which of them it
210 supplies, allowing us to display only the ones it does. */
211 cf_set_drops(capture_opts->cf, drops);
214 /* read in the packet data */
215 switch (cf_read(capture_opts->cf)) {
219 /* Just because we got an error, that doesn't mean we were unable
220 to read any of the file; we handle what we could get from the
224 case CF_READ_ABORTED:
225 /* User wants to quit program. Exit by leaving the main loop,
226 so that any quit functions we registered get called. */
227 main_window_nested_quit();
231 /* if we didn't captured even a single packet, close the file again */
232 if(cf_get_packet_count(capture_opts->cf) == 0 && !capture_opts->restart) {
233 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
234 "%sNo packets captured!%s\n"
236 "As no data was captured, closing the %scapture file!\n"
239 "Help about capturing can be found at:\n"
241 " http://wiki.wireshark.org/CaptureSetup"
244 "Wireless (Wi-Fi/WLAN):\n"
245 "Try to switch off promiscuous mode in the Capture Options!"
248 simple_dialog_primary_start(), simple_dialog_primary_end(),
249 (cf_is_tempfile(capture_opts->cf)) ? "temporary " : "");
250 cf_close(capture_opts->cf);
256 /* capture child tells us we have a new (or the first) capture file */
258 capture_input_new_file(capture_options *capture_opts, gchar *new_file)
260 gboolean is_tempfile;
264 if(capture_opts->state == CAPTURE_PREPARING) {
265 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture started!");
267 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "File: \"%s\"", new_file);
269 g_assert(capture_opts->state == CAPTURE_PREPARING || capture_opts->state == CAPTURE_RUNNING);
271 /* free the old filename */
272 if(capture_opts->save_file != NULL) {
273 /* we start a new capture file, close the old one (if we had one before) */
274 /* (we can only have an open capture file in real_time_mode!) */
275 if( ((capture_file *) capture_opts->cf)->state != FILE_CLOSED) {
276 cf_callback_invoke(cf_cb_live_capture_update_finished, capture_opts->cf);
277 cf_finish_tail(capture_opts->cf, &err);
278 cf_close(capture_opts->cf);
280 g_free(capture_opts->save_file);
282 cf_set_tempfile(capture_opts->cf, FALSE);
284 /* we didn't had a save_file before, must be a tempfile */
286 cf_set_tempfile(capture_opts->cf, TRUE);
289 /* save the new filename */
290 capture_opts->save_file = g_strdup(new_file);
292 /* if we are in real-time mode, open the new file now */
293 if(capture_opts->real_time_mode) {
294 /* Attempt to open the capture file and set up to read from it. */
295 switch(cf_start_tail(capture_opts->cf, capture_opts->save_file, is_tempfile, &err)) {
299 /* Don't unlink (delete) the save file - leave it around,
300 for debugging purposes. */
301 g_free(capture_opts->save_file);
302 capture_opts->save_file = NULL;
308 if(capture_opts->show_info) {
309 if (!capture_info_new_file(new_file))
313 if(capture_opts->real_time_mode) {
314 cf_callback_invoke(cf_cb_live_capture_update_started, capture_opts);
316 cf_callback_invoke(cf_cb_live_capture_fixed_started, capture_opts);
318 capture_opts->state = CAPTURE_RUNNING;
324 /* capture child tells us we have new packets to read */
326 capture_input_new_packets(capture_options *capture_opts, int to_read)
331 g_assert(capture_opts->save_file);
333 if(capture_opts->real_time_mode) {
334 /* Read from the capture file the number of records the child told us it added. */
335 switch (cf_continue_tail(capture_opts->cf, to_read, &err)) {
339 /* Just because we got an error, that doesn't mean we were unable
340 to read any of the file; we handle what we could get from the
343 XXX - abort on a read error? */
344 cf_callback_invoke(cf_cb_live_capture_update_continue, capture_opts->cf);
347 case CF_READ_ABORTED:
348 /* Kill the child capture process; the user wants to exit, and we
349 shouldn't just leave it running. */
350 capture_kill_child(capture_opts);
354 /* increase capture file packet counter by the number or incoming packets */
355 cf_set_packet_count(capture_opts->cf,
356 cf_get_packet_count(capture_opts->cf) + to_read);
358 cf_callback_invoke(cf_cb_live_capture_fixed_continue, capture_opts->cf);
361 /* update the main window, so we get events (e.g. from the stop toolbar button) */
362 main_window_update();
364 if(capture_opts->show_info)
365 capture_info_new_packets(to_read);
369 /* Capture child told us how many dropped packets it counted.
372 capture_input_drops(capture_options *capture_opts, int dropped)
374 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "%d packet%s dropped", dropped, plurality(dropped, "", "s"));
376 g_assert(capture_opts->state == CAPTURE_RUNNING);
378 cf_set_drops_known(capture_opts->cf, TRUE);
379 cf_set_drops(capture_opts->cf, dropped);
383 /* Capture child told us that an error has occurred while starting/running
385 The buffer we're handed has *two* null-terminated strings in it - a
386 primary message and a secondary message, one right after the other.
387 The secondary message might be a null string.
390 capture_input_error_message(capture_options *capture_opts, char *error_msg, char *secondary_error_msg)
392 gchar *safe_error_msg;
393 gchar *safe_secondary_error_msg;
395 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Error message from child: \"%s\", \"%s\"",
396 error_msg, secondary_error_msg);
398 g_assert(capture_opts->state == CAPTURE_PREPARING || capture_opts->state == CAPTURE_RUNNING);
400 safe_error_msg = simple_dialog_format_message(error_msg);
401 if (*secondary_error_msg != '\0') {
402 /* We have both primary and secondary messages. */
403 safe_secondary_error_msg = simple_dialog_format_message(secondary_error_msg);
404 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s%s%s\n\n%s",
405 simple_dialog_primary_start(), safe_error_msg,
406 simple_dialog_primary_end(), safe_secondary_error_msg);
407 g_free(safe_secondary_error_msg);
409 /* We have only a primary message. */
410 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s%s%s",
411 simple_dialog_primary_start(), safe_error_msg,
412 simple_dialog_primary_end());
414 g_free(safe_error_msg);
416 /* the capture child will close the sync_pipe if required, nothing to do for now */
421 /* Capture child told us that an error has occurred while parsing a
422 capture filter when starting/running the capture.
425 capture_input_cfilter_error_message(capture_options *capture_opts, char *error_message)
427 dfilter_t *rfcode = NULL;
428 gchar *safe_cfilter = simple_dialog_format_message(capture_opts->cfilter);
429 gchar *safe_cfilter_error_msg = simple_dialog_format_message(error_message);
431 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture filter error message from child: \"%s\"", error_message);
433 g_assert(capture_opts->state == CAPTURE_PREPARING || capture_opts->state == CAPTURE_RUNNING);
435 /* Did the user try a display filter? */
436 if (dfilter_compile(capture_opts->cfilter, &rfcode) && rfcode != NULL) {
437 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
438 "%sInvalid capture filter: \"%s\"!%s\n"
440 "That string looks like a valid display filter; however, it isn't a valid\n"
441 "capture filter (%s).\n"
443 "Note that display filters and capture filters don't have the same syntax,\n"
444 "so you can't use most display filter expressions as capture filters.\n"
446 "See the User's Guide for a description of the capture filter syntax.",
447 simple_dialog_primary_start(), safe_cfilter,
448 simple_dialog_primary_end(), safe_cfilter_error_msg);
449 dfilter_free(rfcode);
451 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
452 "%sInvalid capture filter: \"%s\"!%s\n"
454 "That string isn't a valid capture filter (%s).\n"
455 "See the User's Guide for a description of the capture filter syntax.",
456 simple_dialog_primary_start(), safe_cfilter,
457 simple_dialog_primary_end(), safe_cfilter_error_msg);
459 g_free(safe_cfilter_error_msg);
460 g_free(safe_cfilter);
462 /* the capture child will close the sync_pipe if required, nothing to do for now */
466 /* capture child closed its side of the pipe, do the required cleanup */
468 capture_input_closed(capture_options *capture_opts)
471 int packet_count_save;
473 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture stopped!");
474 g_assert(capture_opts->state == CAPTURE_PREPARING || capture_opts->state == CAPTURE_RUNNING);
476 /* if we didn't started the capture, do a fake start */
477 /* (happens if we got an error message - we won't get a filename then) */
478 if(capture_opts->state == CAPTURE_PREPARING) {
479 if(capture_opts->real_time_mode) {
480 cf_callback_invoke(cf_cb_live_capture_update_started, capture_opts);
482 cf_callback_invoke(cf_cb_live_capture_fixed_started, capture_opts);
486 if(capture_opts->real_time_mode) {
487 cf_read_status_t status;
489 /* Read what remains of the capture file. */
490 status = cf_finish_tail(capture_opts->cf, &err);
492 /* XXX: If -Q (quit-after-cap) then cf->count clr'd below so save it first */
493 packet_count_save = cf_get_packet_count(capture_opts->cf);
494 /* Tell the GUI, we are not doing a capture any more.
495 Must be done after the cf_finish_tail(), so file lengths are displayed
497 cf_callback_invoke(cf_cb_live_capture_update_finished, capture_opts->cf);
499 /* Finish the capture. */
503 if ((packet_count_save == 0) && !capture_opts->restart) {
504 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
505 "%sNo packets captured!%s\n"
507 "As no data was captured, closing the %scapture file!\n"
510 "Help about capturing can be found at:\n"
512 " http://wiki.wireshark.org/CaptureSetup"
515 "Wireless (Wi-Fi/WLAN):\n"
516 "Try to switch off promiscuous mode in the Capture Options!"
519 simple_dialog_primary_start(), simple_dialog_primary_end(),
520 cf_is_tempfile(capture_opts->cf) ? "temporary " : "");
521 cf_close(capture_opts->cf);
525 /* Just because we got an error, that doesn't mean we were unable
526 to read any of the file; we handle what we could get from the
530 case CF_READ_ABORTED:
531 /* Exit by leaving the main loop, so that any quit functions
532 we registered get called. */
537 /* first of all, we are not doing a capture any more */
538 cf_callback_invoke(cf_cb_live_capture_fixed_finished, capture_opts->cf);
540 /* this is a normal mode capture and if no error happened, read in the capture file data */
541 if(capture_opts->save_file != NULL) {
542 capture_input_read_all(capture_opts, cf_is_tempfile(capture_opts->cf),
543 cf_get_drops_known(capture_opts->cf), cf_get_drops(capture_opts->cf));
547 if(capture_opts->show_info)
548 capture_info_close();
550 capture_opts->state = CAPTURE_STOPPED;
552 /* if we couldn't open a capture file, there's nothing more for us to do */
553 if(capture_opts->save_file == NULL) {
554 cf_close(capture_opts->cf);
558 /* does the user wants to restart the current capture? */
559 if(capture_opts->restart) {
560 capture_opts->restart = FALSE;
562 eth_unlink(capture_opts->save_file);
564 /* if it was a tempfile, throw away the old filename (so it will become a tempfile again) */
565 if(cf_is_tempfile(capture_opts->cf)) {
566 g_free(capture_opts->save_file);
567 capture_opts->save_file = NULL;
570 /* ... and start the capture again */
571 capture_start(capture_opts);
573 /* We're not doing a capture any more, so we don't have a save file. */
574 g_free(capture_opts->save_file);
575 capture_opts->save_file = NULL;
580 * Fetch the interface list from a child process (dumpcap).
582 * @return A GList containing if_info_t structs if successful, NULL otherwise.
585 /* XXX - We parse simple text output to get our interface list. Should
586 * we use "real" data serialization instead, e.g. via XML? */
588 capture_interface_list(int *err, char **err_str)
590 GList *if_list = NULL;
593 gchar **raw_list, **if_parts, **addr_parts;
598 struct sockaddr_in *sa4;
599 struct sockaddr_in6 *sa6;
601 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface List ...");
603 /* Try to get our interface list */
604 *err = sync_interface_list_open(&msg);
606 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture Interface List failed!");
614 /* Split our lines */
615 raw_list = g_strsplit(msg, "\n", 0);
618 for (i = 0; raw_list[i] != NULL; i++) {
619 if_parts = g_strsplit(raw_list[i], "\t", 4);
620 if (if_parts[0] == NULL || if_parts[1] == NULL || if_parts[2] == NULL ||
621 if_parts[3] == NULL) {
622 g_strfreev(if_parts);
626 /* Number followed by the name, e.g "1. eth0" */
627 name = strchr(if_parts[0], ' ');
631 g_strfreev(if_parts);
635 if_info = g_malloc0(sizeof(if_info_t));
636 if_info->name = g_strdup(name);
637 if (strlen(if_parts[1]) > 0)
638 if_info->description = g_strdup(if_parts[1]);
639 addr_parts = g_strsplit(if_parts[2], ",", 0);
640 for (j = 0; addr_parts[j] != NULL; j++) {
641 /* XXX - We're failing to convert IPv6 addresses (on Ubuntu, at least) */
642 if (getaddrinfo(addr_parts[j], NULL, NULL, &ai) == 0) {
644 switch (ai->ai_family) {
646 if_addr = g_malloc0(sizeof(if_addr_t));
647 if_addr->type = AT_IPv4;
648 sa4 = (struct sockaddr_in *) ai->ai_addr;
649 if_addr->ip_addr.ip4_addr = sa4->sin_addr.s_addr;
652 if_addr = g_malloc0(sizeof(if_addr_t));
653 if_addr->type = AT_IPv6;
654 sa6 = (struct sockaddr_in6 *) ai->ai_addr;
655 memcpy(&if_addr->ip_addr.ip6_addr, sa6->sin6_addr.s6_addr, 16);
659 if_info->ip_addr = g_slist_append(if_info->ip_addr, if_addr);
664 if (strcmp(if_parts[3], "loopback") == 0)
665 if_info->loopback = TRUE;
666 g_strfreev(if_parts);
667 g_strfreev(addr_parts);
668 if_list = g_list_append(if_list, if_info);
670 g_strfreev(raw_list);
672 /* Check to see if we built a list */
673 if (if_list == NULL) {
675 *err_str = g_strdup("No interfaces found");
676 *err = NO_INTERFACES_FOUND;
682 #endif /* HAVE_LIBPCAP */