2 * Routines for capture options setting
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.
38 #ifdef HAVE_SYS_TYPES_H
39 # include <sys/types.h>
42 #ifdef HAVE_NETINET_IN_H
43 #include <netinet/in.h>
46 #ifdef HAVE_ARPA_INET_H
47 #include <arpa/inet.h>
50 #ifdef HAVE_SYS_SOCKET_H
51 #include <sys/socket.h> /* needed to define AF_ values on UNIX */
54 #ifdef HAVE_WINSOCK2_H
55 #include <winsock2.h> /* needed to define AF_ values on Windows */
58 #ifdef NEED_INET_V6DEFS_H
59 # include "inet_v6defs.h"
64 #include <epan/packet.h>
66 #include "capture_opts.h"
67 #include "ringbuffer.h"
68 #include "clopts_common.h"
69 #include "cmdarg_err.h"
71 #include "capture_ifinfo.h"
72 #include "capture-pcap-util.h"
73 #include <wsutil/file_util.h>
75 static gboolean capture_opts_output_to_pipe(const char *save_file, gboolean *is_pipe);
79 capture_opts_init(capture_options *capture_opts, void *cf)
81 capture_opts->cf = cf;
82 capture_opts->cfilter = g_strdup(""); /* No capture filter string specified */
83 capture_opts->iface = NULL; /* Default is "pick the first interface" */
84 capture_opts->iface_descr = NULL;
85 #ifdef HAVE_PCAP_REMOTE
86 capture_opts->src_type = CAPTURE_IFLOCAL;
87 capture_opts->remote_host = NULL;
88 capture_opts->remote_port = NULL;
89 capture_opts->auth_type = CAPTURE_AUTH_NULL;
90 capture_opts->auth_username = NULL;
91 capture_opts->auth_password = NULL;
92 capture_opts->datatx_udp = FALSE;
93 capture_opts->nocap_rpcap = TRUE;
94 capture_opts->nocap_local = FALSE;
95 #ifdef HAVE_PCAP_SETSAMPLING
96 capture_opts->sampling_method = CAPTURE_SAMP_NONE;
97 capture_opts->sampling_param = 0;
100 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
101 capture_opts->buffer_size = 1; /* 1 MB */
103 capture_opts->has_snaplen = FALSE;
104 capture_opts->snaplen = WTAP_MAX_PACKET_SIZE; /* snapshot length - default is
105 infinite, in effect */
106 capture_opts->promisc_mode = TRUE; /* promiscuous mode is the default */
107 #ifdef HAVE_PCAP_CREATE
108 capture_opts->monitor_mode = FALSE;
110 capture_opts->linktype = -1; /* the default linktype */
111 capture_opts->saving_to_file = FALSE;
112 capture_opts->save_file = NULL;
113 capture_opts->use_pcapng = FALSE; /* the default is pcap */
114 capture_opts->real_time_mode = TRUE;
115 capture_opts->show_info = TRUE;
116 capture_opts->quit_after_cap = FALSE;
117 capture_opts->restart = FALSE;
119 capture_opts->multi_files_on = FALSE;
120 capture_opts->has_file_duration = FALSE;
121 capture_opts->file_duration = 60; /* 1 min */
122 capture_opts->has_ring_num_files = FALSE;
123 capture_opts->ring_num_files = RINGBUFFER_MIN_NUM_FILES;
125 capture_opts->has_autostop_files = FALSE;
126 capture_opts->autostop_files = 1;
127 capture_opts->has_autostop_packets = FALSE;
128 capture_opts->autostop_packets = 0;
129 capture_opts->has_autostop_filesize = FALSE;
130 capture_opts->autostop_filesize = 1024; /* 1 MB */
131 capture_opts->has_autostop_duration = FALSE;
132 capture_opts->autostop_duration = 60; /* 1 min */
135 capture_opts->fork_child = -1; /* invalid process handle */
137 capture_opts->signal_pipe_write_fd = -1;
139 capture_opts->state = CAPTURE_STOPPED;
140 capture_opts->output_to_pipe = FALSE;
142 capture_opts->owner = getuid();
143 capture_opts->group = getgid();
148 /* log content of capture_opts */
150 capture_opts_log(const char *log_domain, GLogLevelFlags log_level, capture_options *capture_opts) {
151 g_log(log_domain, log_level, "CAPTURE OPTIONS :");
152 g_log(log_domain, log_level, "CFile : 0x%p", capture_opts->cf);
153 g_log(log_domain, log_level, "Filter : %s", capture_opts->cfilter);
154 g_log(log_domain, log_level, "Interface : %s", capture_opts->iface);
155 /* iface_descr may not been filled in and some C Libraries hate a null ptr for %s */
156 g_log(log_domain, log_level, "Interface Descr : %s",
157 capture_opts->iface_descr ? capture_opts->iface_descr : "<null>");
158 #ifdef HAVE_PCAP_REMOTE
159 g_log(log_domain, log_level, "Capture source : %s",
160 capture_opts->src_type == CAPTURE_IFLOCAL ? "Local interface" :
161 capture_opts->src_type == CAPTURE_IFREMOTE ? "Remote interface" :
163 if (capture_opts->src_type == CAPTURE_IFREMOTE) {
164 g_log(log_domain, log_level, "Remote host : %s", capture_opts->remote_host);
165 g_log(log_domain, log_level, "Remote port : %s", capture_opts->remote_port);
167 g_log(log_domain, log_level, "Authentication : %s",
168 capture_opts->auth_type == CAPTURE_AUTH_NULL ? "Null" :
169 capture_opts->auth_type == CAPTURE_AUTH_PWD ? "By username/password" :
171 if (capture_opts->auth_type == CAPTURE_AUTH_PWD) {
172 g_log(log_domain, log_level, "Auth username : %s", capture_opts->auth_password);
173 g_log(log_domain, log_level, "Auth password : <hidden>");
175 g_log(log_domain, log_level, "UDP data transfer : %u", capture_opts->datatx_udp);
176 g_log(log_domain, log_level, "No capture RPCAP : %u", capture_opts->nocap_rpcap);
177 g_log(log_domain, log_level, "No capture local : %u", capture_opts->nocap_local);
179 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
180 g_log(log_domain, log_level, "BufferSize : %u (MB)", capture_opts->buffer_size);
182 g_log(log_domain, log_level, "SnapLen (%u): %u", capture_opts->has_snaplen, capture_opts->snaplen);
183 g_log(log_domain, log_level, "Promisc : %u", capture_opts->promisc_mode);
184 g_log(log_domain, log_level, "LinkType : %d", capture_opts->linktype);
185 g_log(log_domain, log_level, "SavingToFile : %u", capture_opts->saving_to_file);
186 g_log(log_domain, log_level, "SaveFile : %s", (capture_opts->save_file) ? capture_opts->save_file : "");
187 g_log(log_domain, log_level, "Fileformat : %s", (capture_opts->use_pcapng) ? "PCAPNG" : "PCAP");
188 g_log(log_domain, log_level, "RealTimeMode : %u", capture_opts->real_time_mode);
189 g_log(log_domain, log_level, "ShowInfo : %u", capture_opts->show_info);
190 g_log(log_domain, log_level, "QuitAfterCap : %u", capture_opts->quit_after_cap);
192 g_log(log_domain, log_level, "MultiFilesOn : %u", capture_opts->multi_files_on);
193 g_log(log_domain, log_level, "FileDuration (%u): %u", capture_opts->has_file_duration, capture_opts->file_duration);
194 g_log(log_domain, log_level, "RingNumFiles (%u): %u", capture_opts->has_ring_num_files, capture_opts->ring_num_files);
196 g_log(log_domain, log_level, "AutostopFiles (%u): %u", capture_opts->has_autostop_files, capture_opts->autostop_files);
197 g_log(log_domain, log_level, "AutostopPackets (%u): %u", capture_opts->has_autostop_packets, capture_opts->autostop_packets);
198 g_log(log_domain, log_level, "AutostopFilesize(%u): %u (KB)", capture_opts->has_autostop_filesize, capture_opts->autostop_filesize);
199 g_log(log_domain, log_level, "AutostopDuration(%u): %u", capture_opts->has_autostop_duration, capture_opts->autostop_duration);
201 g_log(log_domain, log_level, "ForkChild : %d", capture_opts->fork_child);
203 g_log(log_domain, log_level, "SignalPipeWrite : %d", capture_opts->signal_pipe_write_fd);
208 * Given a string of the form "<autostop criterion>:<value>", as might appear
209 * as an argument to a "-a" option, parse it and set the criterion in
210 * question. Return an indication of whether it succeeded or failed
214 set_autostop_criterion(capture_options *capture_opts, const char *autostoparg)
218 colonp = strchr(autostoparg, ':');
226 * Skip over any white space (there probably won't be any, but
227 * as we allow it in the preferences file, we might as well
230 while (isspace((guchar)*p))
234 * Put the colon back, so if our caller uses, in an
235 * error message, the string they passed us, the message
241 if (strcmp(autostoparg,"duration") == 0) {
242 capture_opts->has_autostop_duration = TRUE;
243 capture_opts->autostop_duration = get_positive_int(p,"autostop duration");
244 } else if (strcmp(autostoparg,"filesize") == 0) {
245 capture_opts->has_autostop_filesize = TRUE;
246 capture_opts->autostop_filesize = get_positive_int(p,"autostop filesize");
247 } else if (strcmp(autostoparg,"files") == 0) {
248 capture_opts->multi_files_on = TRUE;
249 capture_opts->has_autostop_files = TRUE;
250 capture_opts->autostop_files = get_positive_int(p,"autostop files");
254 *colonp = ':'; /* put the colon back */
259 * Given a string of the form "<ring buffer file>:<duration>", as might appear
260 * as an argument to a "-b" option, parse it and set the arguments in
261 * question. Return an indication of whether it succeeded or failed
265 get_ring_arguments(capture_options *capture_opts, const char *arg)
267 gchar *p = NULL, *colonp;
269 colonp = strchr(arg, ':');
277 * Skip over any white space (there probably won't be any, but
278 * as we allow it in the preferences file, we might as well
281 while (isspace((guchar)*p))
285 * Put the colon back, so if our caller uses, in an
286 * error message, the string they passed us, the message
293 if (strcmp(arg,"files") == 0) {
294 capture_opts->has_ring_num_files = TRUE;
295 capture_opts->ring_num_files = get_natural_int(p, "number of ring buffer files");
296 } else if (strcmp(arg,"filesize") == 0) {
297 capture_opts->has_autostop_filesize = TRUE;
298 capture_opts->autostop_filesize = get_positive_int(p, "ring buffer filesize");
299 } else if (strcmp(arg,"duration") == 0) {
300 capture_opts->has_file_duration = TRUE;
301 capture_opts->file_duration = get_positive_int(p, "ring buffer duration");
304 *colonp = ':'; /* put the colon back */
308 #ifdef HAVE_PCAP_SETSAMPLING
310 * Given a string of the form "<sampling type>:<value>", as might appear
311 * as an argument to a "-m" option, parse it and set the arguments in
312 * question. Return an indication of whether it succeeded or failed
316 get_sampling_arguments(capture_options *capture_opts, const char *arg)
318 gchar *p = NULL, *colonp;
320 colonp = strchr(arg, ':');
327 while (isspace((guchar)*p))
334 if (strcmp(arg, "count") == 0) {
335 capture_opts->sampling_method = CAPTURE_SAMP_BY_COUNT;
336 capture_opts->sampling_param = get_positive_int(p, "sampling count");
337 } else if (strcmp(arg, "timer") == 0) {
338 capture_opts->sampling_method = CAPTURE_SAMP_BY_TIMER;
339 capture_opts->sampling_param = get_positive_int(p, "sampling timer");
346 #ifdef HAVE_PCAP_REMOTE
348 * Given a string of the form "<username>:<password>", as might appear
349 * as an argument to a "-A" option, parse it and set the arguments in
350 * question. Return an indication of whether it succeeded or failed
354 get_auth_arguments(capture_options *capture_opts, const char *arg)
356 gchar *p = NULL, *colonp;
358 colonp = strchr(arg, ':');
365 while (isspace((guchar)*p))
368 capture_opts->auth_type = CAPTURE_AUTH_PWD;
369 capture_opts->auth_username = g_strdup(arg);
370 capture_opts->auth_password = g_strdup(p);
377 capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str_p)
388 * If the argument is a number, treat it as an index into the list
389 * of adapters, as printed by "tshark -D".
391 * This should be OK on UNIX systems, as interfaces shouldn't have
392 * names that begin with digits. It can be useful on Windows, where
393 * more than one interface can have the same name.
395 adapter_index = strtol(optarg_str_p, &p, 10);
396 if (p != NULL && *p == '\0') {
397 if (adapter_index < 0) {
398 cmdarg_err("The specified adapter index is a negative number");
401 if (adapter_index > INT_MAX) {
402 cmdarg_err("The specified adapter index is too large (greater than %d)",
406 if (adapter_index == 0) {
407 cmdarg_err("There is no interface with that adapter index");
410 if_list = capture_interface_list(&err, &err_str);
411 if (if_list == NULL) {
414 case CANT_GET_INTERFACE_LIST:
415 cmdarg_err("%s", err_str);
419 case NO_INTERFACES_FOUND:
420 cmdarg_err("There are no interfaces on which a capture can be done");
425 if_info = (if_info_t *)g_list_nth_data(if_list, adapter_index - 1);
426 if (if_info == NULL) {
427 cmdarg_err("There is no interface with that adapter index");
430 capture_opts->iface = g_strdup(if_info->name);
431 /* We don't set iface_descr here because doing so requires
432 * capture_ui_utils.c which requires epan/prefs.c which is
433 * probably a bit too much dependency for here...
435 free_interface_list(if_list);
437 capture_opts->iface = g_strdup(optarg_str_p);
444 capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_str_p, gboolean *start_capture)
449 case 'a': /* autostop criteria */
450 if (set_autostop_criterion(capture_opts, optarg_str_p) == FALSE) {
451 cmdarg_err("Invalid or unknown -a flag \"%s\"", optarg_str_p);
455 #ifdef HAVE_PCAP_REMOTE
457 if (get_auth_arguments(capture_opts, optarg_str_p) == FALSE) {
458 cmdarg_err("Invalid or unknown -A arg \"%s\"", optarg_str_p);
463 case 'b': /* Ringbuffer option */
464 capture_opts->multi_files_on = TRUE;
465 if (get_ring_arguments(capture_opts, optarg_str_p) == FALSE) {
466 cmdarg_err("Invalid or unknown -b arg \"%s\"", optarg_str_p);
470 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
471 case 'B': /* Buffer size */
472 capture_opts->buffer_size = get_positive_int(optarg_str_p, "buffer size");
475 case 'c': /* Capture n packets */
476 capture_opts->has_autostop_packets = TRUE;
477 capture_opts->autostop_packets = get_positive_int(optarg_str_p, "packet count");
479 case 'f': /* capture filter */
480 if (capture_opts->has_cfilter) {
481 cmdarg_err("More than one -f argument specified");
484 capture_opts->has_cfilter = TRUE;
485 g_free(capture_opts->cfilter);
486 capture_opts->cfilter = g_strdup(optarg_str_p);
488 case 'H': /* Hide capture info dialog box */
489 capture_opts->show_info = FALSE;
491 case 'i': /* Use interface x */
492 status = capture_opts_add_iface_opt(capture_opts, optarg_str_p);
497 #ifdef HAVE_PCAP_CREATE
498 case 'I': /* Capture in monitor mode */
499 capture_opts->monitor_mode = TRUE;
502 case 'k': /* Start capture immediately */
503 *start_capture = TRUE;
505 /*case 'l':*/ /* Automatic scrolling in live capture mode */
506 #ifdef HAVE_PCAP_SETSAMPLING
508 if (get_sampling_arguments(capture_opts, optarg_str_p) == FALSE) {
509 cmdarg_err("Invalid or unknown -m arg \"%s\"", optarg_str_p);
514 case 'n': /* Use pcapng format */
515 capture_opts->use_pcapng = TRUE;
517 case 'p': /* Don't capture in promiscuous mode */
518 capture_opts->promisc_mode = FALSE;
520 case 'Q': /* Quit after capture (just capture to file) */
521 capture_opts->quit_after_cap = TRUE;
522 *start_capture = TRUE; /*** -Q implies -k !! ***/
524 #ifdef HAVE_PCAP_REMOTE
526 capture_opts->nocap_rpcap = FALSE;
529 case 's': /* Set the snapshot (capture) length */
530 capture_opts->has_snaplen = TRUE;
531 capture_opts->snaplen = get_natural_int(optarg_str_p, "snapshot length");
533 * Make a snapshot length of 0 equivalent to the maximum packet
534 * length, mirroring what tcpdump does.
536 if (capture_opts->snaplen == 0)
537 capture_opts->snaplen = WTAP_MAX_PACKET_SIZE;
539 case 'S': /* "Real-Time" mode: used for following file ala tail -f */
540 capture_opts->real_time_mode = TRUE;
542 #ifdef HAVE_PCAP_REMOTE
544 capture_opts->datatx_udp = TRUE;
547 case 'w': /* Write to capture file x */
548 capture_opts->saving_to_file = TRUE;
549 g_free(capture_opts->save_file);
550 #if defined _WIN32 && GLIB_CHECK_VERSION(2,6,0)
551 /* since GLib 2.6, we need to convert filenames to utf8 for Win32 */
552 capture_opts->save_file = g_locale_to_utf8(optarg_str_p, -1, NULL, NULL, NULL);
554 capture_opts->save_file = g_strdup(optarg_str_p);
556 status = capture_opts_output_to_pipe(capture_opts->save_file, &capture_opts->output_to_pipe);
558 case 'y': /* Set the pcap data link type */
559 capture_opts->linktype = linktype_name_to_val(optarg_str_p);
560 if (capture_opts->linktype == -1) {
561 cmdarg_err("The specified data link type \"%s\" isn't valid",
567 /* the caller is responsible to send us only the right opt's */
568 g_assert_not_reached();
575 * If you change the output format of this function, you MUST update
576 * capture_sync.c:sync_linktype_list_open() accordingly!
579 capture_opts_list_link_layer_types(capture_options *capture_opts, gboolean machine_readable)
582 const gchar *desc_str;
583 GList *lt_list, *lt_entry;
584 data_link_info_t *data_link_info;
586 /* Get the list of link-layer types for the capture device. */
587 lt_list = get_pcap_linktype_list(capture_opts->iface, &err_str);
588 if (lt_list == NULL) {
589 if (err_str != NULL) {
590 cmdarg_err("The list of data link types for the capture device \"%s\" could not be obtained (%s)."
591 "Please check to make sure you have sufficient permissions, and that\n"
592 "you have the proper interface or pipe specified.\n", capture_opts->iface, err_str);
595 cmdarg_err("The capture device \"%s\" has no data link types.", capture_opts->iface);
598 if (machine_readable) { /* tab-separated values to stdout */
599 for (lt_entry = lt_list; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
600 data_link_info = (data_link_info_t *)lt_entry->data;
601 if (data_link_info->description != NULL)
602 desc_str = data_link_info->description;
604 desc_str = "(not supported)";
605 printf("%d\t%s\t%s\n", data_link_info->dlt, data_link_info->name,
609 cmdarg_err_cont("Data link types (use option -y to set):");
610 for (lt_entry = lt_list; lt_entry != NULL;
611 lt_entry = g_list_next(lt_entry)) {
612 data_link_info = (data_link_info_t *)lt_entry->data;
613 cmdarg_err_cont(" %s", data_link_info->name);
614 if (data_link_info->description != NULL)
615 cmdarg_err_cont(" (%s)", data_link_info->description);
617 cmdarg_err_cont(" (not supported)");
621 free_pcap_linktype_list(lt_list);
626 /* Return an ASCII-formatted list of interfaces. */
627 #define ADDRSTRLEN 46 /* Covers IPv4 & IPv6 */
629 capture_opts_list_interfaces(gboolean machine_readable)
639 char addr_str[ADDRSTRLEN];
641 if_list = capture_interface_list(&err, &err_str);
642 if (if_list == NULL) {
644 case CANT_GET_INTERFACE_LIST:
645 cmdarg_err("%s", err_str);
649 case NO_INTERFACES_FOUND:
650 cmdarg_err("There are no interfaces on which a capture can be done");
656 i = 1; /* Interface id number */
657 for (if_entry = g_list_first(if_list); if_entry != NULL;
658 if_entry = g_list_next(if_entry)) {
659 if_info = (if_info_t *)if_entry->data;
660 printf("%d. %s", i++, if_info->name);
662 if (!machine_readable) {
663 /* Add the description if it exists */
664 if (if_info->description != NULL)
665 printf(" (%s)", if_info->description);
668 * Add the contents of the if_entry struct in a parseable format.
669 * Each if_entry element is tab-separated. Addresses are comma-
672 /* XXX - Make sure our description doesn't contain a tab */
673 if (if_info->description != NULL)
674 printf("\t%s\t", if_info->description);
678 for(addr = g_slist_nth(if_info->addrs, 0); addr != NULL;
679 addr = g_slist_next(addr)) {
680 if (addr != g_slist_nth(if_info->addrs, 0))
683 if_addr = (if_addr_t *)addr->data;
684 switch(if_addr->ifat_type) {
686 if (inet_ntop(AF_INET, &if_addr->addr.ip4_addr, addr_str,
688 printf("%s", addr_str);
690 printf("<unknown IPv4>");
694 if (inet_ntop(AF_INET6, &if_addr->addr.ip6_addr,
695 addr_str, ADDRSTRLEN)) {
696 printf("%s", addr_str);
698 printf("<unknown IPv6>");
702 printf("<type unknown %u>", if_addr->ifat_type);
706 if (if_info->loopback)
707 printf("\tloopback");
714 free_interface_list(if_list);
720 void capture_opts_trim_snaplen(capture_options *capture_opts, int snaplen_min)
722 if (capture_opts->snaplen < 1)
723 capture_opts->snaplen = WTAP_MAX_PACKET_SIZE;
724 else if (capture_opts->snaplen < snaplen_min)
725 capture_opts->snaplen = snaplen_min;
729 void capture_opts_trim_ring_num_files(capture_options *capture_opts)
731 /* Check the value range of the ring_num_files parameter */
732 if (capture_opts->ring_num_files > RINGBUFFER_MAX_NUM_FILES)
733 capture_opts->ring_num_files = RINGBUFFER_MAX_NUM_FILES;
734 #if RINGBUFFER_MIN_NUM_FILES > 0
735 else if (capture_opts->ring_num_files < RINGBUFFER_MIN_NUM_FILES)
736 capture_opts->ring_num_files = RINGBUFFER_MIN_NUM_FILES;
741 gboolean capture_opts_trim_iface(capture_options *capture_opts, const char *capture_device)
749 /* Did the user specify an interface to use? */
750 if (capture_opts->iface == NULL) {
751 /* No - is a default specified in the preferences file? */
752 if (capture_device != NULL) {
754 capture_opts->iface = g_strdup(capture_device);
755 /* We don't set iface_descr here because doing so requires
756 * capture_ui_utils.c which requires epan/prefs.c which is
757 * probably a bit too much dependency for here...
760 /* No - pick the first one from the list of interfaces. */
761 if_list = capture_interface_list(&err, &err_str);
762 if (if_list == NULL) {
765 case CANT_GET_INTERFACE_LIST:
766 cmdarg_err("%s", err_str);
770 case NO_INTERFACES_FOUND:
771 cmdarg_err("There are no interfaces on which a capture can be done");
776 if_info = (if_info_t *)if_list->data; /* first interface */
777 capture_opts->iface = g_strdup(if_info->name);
778 /* We don't set iface_descr here because doing so requires
779 * capture_ui_utils.c which requires epan/prefs.c which is
780 * probably a bit too much dependency for here...
782 free_interface_list(if_list);
792 #define S_IFIFO _S_IFIFO
795 #define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
798 /* copied from filesystem.c */
799 static int capture_opts_test_for_fifo(const char *path)
803 if (ws_stat(path, &statb) < 0)
806 if (S_ISFIFO(statb.st_mode))
812 static gboolean capture_opts_output_to_pipe(const char *save_file, gboolean *is_pipe)
818 if (save_file != NULL) {
819 /* We're writing to a capture file. */
820 if (strcmp(save_file, "-") == 0) {
821 /* Writing to stdout. */
822 /* XXX - should we check whether it's a pipe? It's arguably
823 silly to do "-w - >output_file" rather than "-w output_file",
824 but by not checking we might be violating the Principle Of
825 Least Astonishment. */
828 /* not writing to stdout, test for a FIFO (aka named pipe) */
829 err = capture_opts_test_for_fifo(save_file);
832 case ENOENT: /* it doesn't exist, so we'll be creating it,
833 and it won't be a FIFO */
834 case 0: /* found it, but it's not a FIFO */
837 case ESPIPE: /* it is a FIFO */
841 default: /* couldn't stat it */
842 break; /* ignore: later attempt to open */
843 /* will generate a nice msg */
851 #endif /* HAVE_LIBPCAP */