pkinit use kerberos_private_is_kdc_req()
[metze/wireshark/wip.git] / capture_opts.c
1 /* capture_opts.c
2  * Routines for capture options setting
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 1998 Gerald Combs
7  *
8  * SPDX-License-Identifier: GPL-2.0-or-later
9  */
10
11 #include <config.h>
12
13 #include <stdio.h>
14 #include <stdlib.h>
15
16 #ifdef HAVE_LIBPCAP
17
18 #include <string.h>
19
20 #include <errno.h>
21
22 #include <glib.h>
23
24 #include "capture_opts.h"
25 #include "ringbuffer.h"
26
27 #include <ui/clopts_common.h>
28 #include <ui/cmdarg_err.h>
29 #include <wsutil/file_util.h>
30 #include <wsutil/ws_pipe.h>
31
32 #include "caputils/capture_ifinfo.h"
33 #include "caputils/capture-pcap-util.h"
34
35 #include "ui/filter_files.h"
36
37 static gboolean capture_opts_output_to_pipe(const char *save_file, gboolean *is_pipe);
38
39
40 void
41 capture_opts_init(capture_options *capture_opts)
42 {
43     capture_opts->ifaces                          = g_array_new(FALSE, FALSE, sizeof(interface_options));
44     capture_opts->all_ifaces                      = g_array_new(FALSE, FALSE, sizeof(interface_t));
45     capture_opts->num_selected                    = 0;
46     capture_opts->default_options.name            = NULL;
47     capture_opts->default_options.descr           = NULL;
48     capture_opts->default_options.cfilter         = NULL;
49     capture_opts->default_options.has_snaplen     = FALSE;
50     capture_opts->default_options.snaplen         = WTAP_MAX_PACKET_SIZE_STANDARD;
51     capture_opts->default_options.linktype        = -1; /* use interface default */
52     capture_opts->default_options.promisc_mode    = TRUE;
53     capture_opts->default_options.if_type         = IF_WIRED;
54     capture_opts->default_options.extcap          = NULL;
55     capture_opts->default_options.extcap_fifo     = NULL;
56     capture_opts->default_options.extcap_args     = NULL;
57     capture_opts->default_options.extcap_pipedata = NULL;
58     capture_opts->default_options.extcap_pid      = WS_INVALID_PID;
59 #ifdef _WIN32
60     capture_opts->default_options.extcap_pipe_h   = INVALID_HANDLE_VALUE;
61     capture_opts->default_options.extcap_control_in_h  = INVALID_HANDLE_VALUE;
62     capture_opts->default_options.extcap_control_out_h = INVALID_HANDLE_VALUE;
63 #endif
64     capture_opts->default_options.extcap_control_in  = NULL;
65     capture_opts->default_options.extcap_control_out = NULL;
66 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
67     capture_opts->default_options.buffer_size     = DEFAULT_CAPTURE_BUFFER_SIZE;
68 #endif
69     capture_opts->default_options.monitor_mode    = FALSE;
70 #ifdef HAVE_PCAP_REMOTE
71     capture_opts->default_options.src_type        = CAPTURE_IFLOCAL;
72     capture_opts->default_options.remote_host     = NULL;
73     capture_opts->default_options.remote_port     = NULL;
74     capture_opts->default_options.auth_type       = CAPTURE_AUTH_NULL;
75     capture_opts->default_options.auth_username   = NULL;
76     capture_opts->default_options.auth_password   = NULL;
77     capture_opts->default_options.datatx_udp      = FALSE;
78     capture_opts->default_options.nocap_rpcap     = TRUE;
79     capture_opts->default_options.nocap_local     = FALSE;
80 #endif
81 #ifdef HAVE_PCAP_SETSAMPLING
82     capture_opts->default_options.sampling_method = CAPTURE_SAMP_NONE;
83     capture_opts->default_options.sampling_param  = 0;
84 #endif
85     capture_opts->default_options.timestamp_type  = NULL;
86     capture_opts->saving_to_file                  = FALSE;
87     capture_opts->save_file                       = NULL;
88     capture_opts->group_read_access               = FALSE;
89 #ifdef PCAP_NG_DEFAULT
90     capture_opts->use_pcapng                      = TRUE;             /* Save as pcapng by default */
91 #else
92     capture_opts->use_pcapng                      = FALSE;            /* Save as pcap by default */
93 #endif
94     capture_opts->real_time_mode                  = TRUE;
95     capture_opts->show_info                       = TRUE;
96     capture_opts->restart                         = FALSE;
97     capture_opts->orig_save_file                  = NULL;
98
99     capture_opts->multi_files_on                  = FALSE;
100     capture_opts->has_file_duration               = FALSE;
101     capture_opts->file_duration                   = 60.0;             /* 1 min */
102     capture_opts->has_file_interval               = FALSE;
103     capture_opts->file_interval                   = 60;               /* 1 min */
104     capture_opts->has_file_packets                = FALSE;
105     capture_opts->file_packets                    = 0;
106     capture_opts->has_ring_num_files              = FALSE;
107     capture_opts->ring_num_files                  = RINGBUFFER_MIN_NUM_FILES;
108
109     capture_opts->has_autostop_files              = FALSE;
110     capture_opts->autostop_files                  = 1;
111     capture_opts->has_autostop_packets            = FALSE;
112     capture_opts->autostop_packets                = 0;
113     capture_opts->has_autostop_filesize           = FALSE;
114     capture_opts->autostop_filesize               = 1000;             /* 1 MB */
115     capture_opts->has_autostop_duration           = FALSE;
116     capture_opts->autostop_duration               = 60.0;             /* 1 min */
117     capture_opts->capture_comment                 = NULL;
118
119     capture_opts->output_to_pipe                  = FALSE;
120     capture_opts->capture_child                   = FALSE;
121 }
122
123 void
124 capture_opts_cleanup(capture_options *capture_opts)
125 {
126     if (!capture_opts)
127         return;
128
129     if (capture_opts->ifaces) {
130         while (capture_opts->ifaces->len > 0) {
131             capture_opts_del_iface(capture_opts, 0);
132         }
133         g_array_free(capture_opts->ifaces, TRUE);
134         capture_opts->ifaces = NULL;
135     }
136     if (capture_opts->all_ifaces) {
137         while (capture_opts->all_ifaces->len > 0) {
138             interface_t *device = &g_array_index(capture_opts->all_ifaces, interface_t, 0);
139             capture_opts_free_interface_t(device);
140             capture_opts->all_ifaces = g_array_remove_index(capture_opts->all_ifaces, 0);
141         }
142         g_array_free(capture_opts->all_ifaces, TRUE);
143         capture_opts->all_ifaces = NULL;
144     }
145     g_free(capture_opts->save_file);
146 }
147
148 /* log content of capture_opts */
149 void
150 capture_opts_log(const char *log_domain, GLogLevelFlags log_level, capture_options *capture_opts) {
151     guint i;
152
153     g_log(log_domain, log_level, "CAPTURE OPTIONS     :");
154
155     for (i = 0; i < capture_opts->ifaces->len; i++) {
156         interface_options *interface_opts;
157
158         interface_opts = &g_array_index(capture_opts->ifaces, interface_options, i);
159         g_log(log_domain, log_level, "Interface name[%02d]  : %s", i, interface_opts->name ? interface_opts->name : "(unspecified)");
160         g_log(log_domain, log_level, "Interface description[%02d] : %s", i, interface_opts->descr ? interface_opts->descr : "(unspecified)");
161         g_log(log_domain, log_level, "Display name[%02d]: %s", i, interface_opts->display_name ? interface_opts->display_name : "(unspecified)");
162         g_log(log_domain, log_level, "Capture filter[%02d]  : %s", i, interface_opts->cfilter ? interface_opts->cfilter : "(unspecified)");
163         g_log(log_domain, log_level, "Snap length[%02d] (%u) : %d", i, interface_opts->has_snaplen, interface_opts->snaplen);
164         g_log(log_domain, log_level, "Link Type[%02d]       : %d", i, interface_opts->linktype);
165         g_log(log_domain, log_level, "Promiscuous Mode[%02d]: %s", i, interface_opts->promisc_mode?"TRUE":"FALSE");
166         g_log(log_domain, log_level, "Extcap[%02d]          : %s", i, interface_opts->extcap ? interface_opts->extcap : "(unspecified)");
167         g_log(log_domain, log_level, "Extcap FIFO[%02d]     : %s", i, interface_opts->extcap_fifo ? interface_opts->extcap_fifo : "(unspecified)");
168         g_log(log_domain, log_level, "Extcap PID[%02d]      : %d", i, interface_opts->extcap_pid);
169 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
170         g_log(log_domain, log_level, "Buffer size[%02d]     : %d (MB)", i, interface_opts->buffer_size);
171 #endif
172         g_log(log_domain, log_level, "Monitor Mode[%02d]    : %s", i, interface_opts->monitor_mode?"TRUE":"FALSE");
173 #ifdef HAVE_PCAP_REMOTE
174         g_log(log_domain, log_level, "Capture source[%02d]  : %s", i,
175             interface_opts->src_type == CAPTURE_IFLOCAL ? "Local interface" :
176             interface_opts->src_type == CAPTURE_IFREMOTE ? "Remote interface" :
177             "Unknown");
178         if (interface_opts->src_type == CAPTURE_IFREMOTE) {
179             g_log(log_domain, log_level, "Remote host[%02d]     : %s", i, interface_opts->remote_host ? interface_opts->remote_host : "(unspecified)");
180             g_log(log_domain, log_level, "Remote port[%02d]     : %s", i, interface_opts->remote_port ? interface_opts->remote_port : "(unspecified)");
181         }
182         g_log(log_domain, log_level, "Authentication[%02d]  : %s", i,
183             interface_opts->auth_type == CAPTURE_AUTH_NULL ? "Null" :
184             interface_opts->auth_type == CAPTURE_AUTH_PWD ? "By username/password" :
185             "Unknown");
186         if (interface_opts->auth_type == CAPTURE_AUTH_PWD) {
187             g_log(log_domain, log_level, "Auth username[%02d]   : %s", i, interface_opts->auth_username ? interface_opts->auth_username : "(unspecified)");
188             g_log(log_domain, log_level, "Auth password[%02d]   : <hidden>", i);
189         }
190         g_log(log_domain, log_level, "UDP data tfer[%02d]   : %u", i, interface_opts->datatx_udp);
191         g_log(log_domain, log_level, "No cap. RPCAP[%02d]   : %u", i, interface_opts->nocap_rpcap);
192         g_log(log_domain, log_level, "No cap. local[%02d]   : %u", i, interface_opts->nocap_local);
193 #endif
194 #ifdef HAVE_PCAP_SETSAMPLING
195         g_log(log_domain, log_level, "Sampling meth.[%02d]  : %d", i, interface_opts->sampling_method);
196         g_log(log_domain, log_level, "Sampling param.[%02d] : %d", i, interface_opts->sampling_param);
197 #endif
198         g_log(log_domain, log_level, "Timestamp type [%02d] : %s", i, interface_opts->timestamp_type);
199     }
200     g_log(log_domain, log_level, "Interface name[df]  : %s", capture_opts->default_options.name ? capture_opts->default_options.name : "(unspecified)");
201     g_log(log_domain, log_level, "Interface Descr[df] : %s", capture_opts->default_options.descr ? capture_opts->default_options.descr : "(unspecified)");
202     g_log(log_domain, log_level, "Capture filter[df]  : %s", capture_opts->default_options.cfilter ? capture_opts->default_options.cfilter : "(unspecified)");
203     g_log(log_domain, log_level, "Snap length[df] (%u) : %d", capture_opts->default_options.has_snaplen, capture_opts->default_options.snaplen);
204     g_log(log_domain, log_level, "Link Type[df]       : %d", capture_opts->default_options.linktype);
205     g_log(log_domain, log_level, "Promiscuous Mode[df]: %s", capture_opts->default_options.promisc_mode?"TRUE":"FALSE");
206     g_log(log_domain, log_level, "Extcap[df]          : %s", capture_opts->default_options.extcap ? capture_opts->default_options.extcap : "(unspecified)");
207     g_log(log_domain, log_level, "Extcap FIFO[df]     : %s", capture_opts->default_options.extcap_fifo ? capture_opts->default_options.extcap_fifo : "(unspecified)");
208 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
209     g_log(log_domain, log_level, "Buffer size[df]     : %d (MB)", capture_opts->default_options.buffer_size);
210 #endif
211     g_log(log_domain, log_level, "Monitor Mode[df]    : %s", capture_opts->default_options.monitor_mode?"TRUE":"FALSE");
212 #ifdef HAVE_PCAP_REMOTE
213     g_log(log_domain, log_level, "Capture source[df]  : %s",
214         capture_opts->default_options.src_type == CAPTURE_IFLOCAL ? "Local interface" :
215         capture_opts->default_options.src_type == CAPTURE_IFREMOTE ? "Remote interface" :
216         "Unknown");
217     if (capture_opts->default_options.src_type == CAPTURE_IFREMOTE) {
218         g_log(log_domain, log_level, "Remote host[df]     : %s", capture_opts->default_options.remote_host ? capture_opts->default_options.remote_host : "(unspecified)");
219         g_log(log_domain, log_level, "Remote port[df]     : %s", capture_opts->default_options.remote_port ? capture_opts->default_options.remote_port : "(unspecified)");
220     }
221     g_log(log_domain, log_level, "Authentication[df]  : %s",
222         capture_opts->default_options.auth_type == CAPTURE_AUTH_NULL ? "Null" :
223         capture_opts->default_options.auth_type == CAPTURE_AUTH_PWD ? "By username/password" :
224         "Unknown");
225     if (capture_opts->default_options.auth_type == CAPTURE_AUTH_PWD) {
226         g_log(log_domain, log_level, "Auth username[df]   : %s", capture_opts->default_options.auth_username ? capture_opts->default_options.auth_username : "(unspecified)");
227         g_log(log_domain, log_level, "Auth password[df]   : <hidden>");
228     }
229     g_log(log_domain, log_level, "UDP data tfer[df]   : %u", capture_opts->default_options.datatx_udp);
230     g_log(log_domain, log_level, "No cap. RPCAP[df]   : %u", capture_opts->default_options.nocap_rpcap);
231     g_log(log_domain, log_level, "No cap. local[df]   : %u", capture_opts->default_options.nocap_local);
232 #endif
233 #ifdef HAVE_PCAP_SETSAMPLING
234     g_log(log_domain, log_level, "Sampling meth. [df] : %d", capture_opts->default_options.sampling_method);
235     g_log(log_domain, log_level, "Sampling param.[df] : %d", capture_opts->default_options.sampling_param);
236 #endif
237     g_log(log_domain, log_level, "Timestamp type [df] : %s", capture_opts->default_options.timestamp_type ? capture_opts->default_options.timestamp_type : "(unspecified)");
238     g_log(log_domain, log_level, "SavingToFile        : %u", capture_opts->saving_to_file);
239     g_log(log_domain, log_level, "SaveFile            : %s", (capture_opts->save_file) ? capture_opts->save_file : "");
240     g_log(log_domain, log_level, "GroupReadAccess     : %u", capture_opts->group_read_access);
241     g_log(log_domain, log_level, "Fileformat          : %s", (capture_opts->use_pcapng) ? "PCAPNG" : "PCAP");
242     g_log(log_domain, log_level, "RealTimeMode        : %u", capture_opts->real_time_mode);
243     g_log(log_domain, log_level, "ShowInfo            : %u", capture_opts->show_info);
244
245     g_log(log_domain, log_level, "MultiFilesOn        : %u", capture_opts->multi_files_on);
246     g_log(log_domain, log_level, "FileDuration    (%u) : %.3f", capture_opts->has_file_duration, capture_opts->file_duration);
247     g_log(log_domain, log_level, "FileInterval    (%u) : %u", capture_opts->has_file_interval, capture_opts->file_interval);
248     g_log(log_domain, log_level, "FilePackets     (%u) : %u", capture_opts->has_file_packets, capture_opts->file_packets);
249     g_log(log_domain, log_level, "RingNumFiles    (%u) : %u", capture_opts->has_ring_num_files, capture_opts->ring_num_files);
250
251     g_log(log_domain, log_level, "AutostopFiles   (%u) : %u", capture_opts->has_autostop_files, capture_opts->autostop_files);
252     g_log(log_domain, log_level, "AutostopPackets (%u) : %u", capture_opts->has_autostop_packets, capture_opts->autostop_packets);
253     g_log(log_domain, log_level, "AutostopFilesize(%u) : %u (KB)", capture_opts->has_autostop_filesize, capture_opts->autostop_filesize);
254     g_log(log_domain, log_level, "AutostopDuration(%u) : %.3f", capture_opts->has_autostop_duration, capture_opts->autostop_duration);
255 }
256
257 /*
258  * Given a string of the form "<autostop criterion>:<value>", as might appear
259  * as an argument to a "-a" option, parse it and set the criterion in
260  * question.  Return an indication of whether it succeeded or failed
261  * in some fashion.
262  */
263 static gboolean
264 set_autostop_criterion(capture_options *capture_opts, const char *autostoparg)
265 {
266     gchar *p, *colonp;
267
268     colonp = strchr(autostoparg, ':');
269     if (colonp == NULL)
270         return FALSE;
271
272     p = colonp;
273     *p++ = '\0';
274
275     /*
276      * Skip over any white space (there probably won't be any, but
277      * as we allow it in the preferences file, we might as well
278      * allow it here).
279      */
280     while (g_ascii_isspace(*p))
281         p++;
282     if (*p == '\0') {
283         /*
284          * Put the colon back, so if our caller uses, in an
285          * error message, the string they passed us, the message
286          * looks correct.
287          */
288         *colonp = ':';
289         return FALSE;
290     }
291     if (strcmp(autostoparg,"duration") == 0) {
292         capture_opts->has_autostop_duration = TRUE;
293         capture_opts->autostop_duration = get_positive_double(p,"autostop duration");
294     } else if (strcmp(autostoparg,"filesize") == 0) {
295         capture_opts->has_autostop_filesize = TRUE;
296         capture_opts->autostop_filesize = get_nonzero_guint32(p,"autostop filesize");
297     } else if (strcmp(autostoparg,"files") == 0) {
298         capture_opts->multi_files_on = TRUE;
299         capture_opts->has_autostop_files = TRUE;
300         capture_opts->autostop_files = get_positive_int(p,"autostop files");
301     } else if (strcmp(autostoparg,"packets") == 0) {
302         capture_opts->has_autostop_packets = TRUE;
303         capture_opts->autostop_packets = get_positive_int(p,"packet count");
304     } else {
305         return FALSE;
306     }
307     *colonp = ':'; /* put the colon back */
308     return TRUE;
309 }
310
311 static gboolean get_filter_arguments(capture_options* capture_opts, const char* arg)
312 {
313     char* colonp;
314     char* val;
315     char* filter_exp = NULL;
316
317     colonp = strchr(arg, ':');
318     if (colonp) {
319         val = colonp;
320         *val = '\0';
321         val++;
322         if (strcmp(arg, "predef") == 0) {
323             GList* filterItem;
324
325             filterItem = get_filter_list_first(CFILTER_LIST);
326             while (filterItem != NULL) {
327                 filter_def *filterDef;
328
329                 filterDef = (filter_def*)filterItem->data;
330                 if (strcmp(val, filterDef->name) == 0) {
331                     filter_exp = g_strdup(filterDef->strval);
332                     break;
333                 }
334                 filterItem = filterItem->next;
335             }
336         }
337     }
338
339     if (filter_exp == NULL) {
340         /* No filter expression found yet; fallback to previous implemention
341            and assume the arg contains a filter expression */
342         if (colonp) {
343             *colonp = ':';      /* restore colon */
344         }
345         filter_exp = g_strdup(arg);
346     }
347
348     if (capture_opts->ifaces->len > 0) {
349         interface_options *interface_opts;
350
351         interface_opts = &g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
352         g_free(interface_opts->cfilter);
353         interface_opts->cfilter = filter_exp;
354         return TRUE;
355     }
356     else {
357         g_free(capture_opts->default_options.cfilter);
358         capture_opts->default_options.cfilter = filter_exp;
359         return TRUE;
360     }
361 }
362
363 /*
364  * Given a string of the form "<ring buffer file>:<duration>", as might appear
365  * as an argument to a "-b" option, parse it and set the arguments in
366  * question.  Return an indication of whether it succeeded or failed
367  * in some fashion.
368  */
369 static gboolean
370 get_ring_arguments(capture_options *capture_opts, const char *arg)
371 {
372     gchar *p = NULL, *colonp;
373
374     colonp = strchr(arg, ':');
375     if (colonp == NULL)
376         return FALSE;
377
378     p = colonp;
379     *p++ = '\0';
380
381     /*
382      * Skip over any white space (there probably won't be any, but
383      * as we allow it in the preferences file, we might as well
384      * allow it here).
385      */
386     while (g_ascii_isspace(*p))
387         p++;
388     if (*p == '\0') {
389         /*
390          * Put the colon back, so if our caller uses, in an
391          * error message, the string they passed us, the message
392          * looks correct.
393          */
394         *colonp = ':';
395         return FALSE;
396     }
397
398     if (strcmp(arg,"files") == 0) {
399         capture_opts->has_ring_num_files = TRUE;
400         capture_opts->ring_num_files = get_nonzero_guint32(p, "number of ring buffer files");
401     } else if (strcmp(arg,"filesize") == 0) {
402         capture_opts->has_autostop_filesize = TRUE;
403         capture_opts->autostop_filesize = get_nonzero_guint32(p, "ring buffer filesize");
404     } else if (strcmp(arg,"duration") == 0) {
405         capture_opts->has_file_duration = TRUE;
406         capture_opts->file_duration = get_positive_double(p, "ring buffer duration");
407     } else if (strcmp(arg,"interval") == 0) {
408         capture_opts->has_file_interval = TRUE;
409         capture_opts->file_interval = get_positive_int(p, "ring buffer interval");
410     } else if (strcmp(arg,"packets") == 0) {
411         capture_opts->has_file_packets = TRUE;
412         capture_opts->file_packets = get_positive_int(p, "ring buffer packet count");
413     }
414
415     *colonp = ':';    /* put the colon back */
416     return TRUE;
417 }
418
419 #ifdef HAVE_PCAP_SETSAMPLING
420 /*
421  * Given a string of the form "<sampling type>:<value>", as might appear
422  * as an argument to a "-m" option, parse it and set the arguments in
423  * question.  Return an indication of whether it succeeded or failed
424  * in some fashion.
425  */
426 static gboolean
427 get_sampling_arguments(capture_options *capture_opts, const char *arg)
428 {
429     gchar *p = NULL, *colonp;
430
431     colonp = strchr(arg, ':');
432     if (colonp == NULL)
433         return FALSE;
434
435     p = colonp;
436     *p++ = '\0';
437
438     while (g_ascii_isspace(*p))
439         p++;
440     if (*p == '\0') {
441         *colonp = ':';
442         return FALSE;
443     }
444
445     if (strcmp(arg, "count") == 0) {
446         if (capture_opts->ifaces->len > 0) {
447             interface_options *interface_opts;
448
449             interface_opts = &g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
450             interface_opts->sampling_method = CAPTURE_SAMP_BY_COUNT;
451             interface_opts->sampling_param = get_positive_int(p, "sampling count");
452         } else {
453             capture_opts->default_options.sampling_method = CAPTURE_SAMP_BY_COUNT;
454             capture_opts->default_options.sampling_param = get_positive_int(p, "sampling count");
455         }
456     } else if (strcmp(arg, "timer") == 0) {
457         if (capture_opts->ifaces->len > 0) {
458             interface_options *interface_opts;
459
460             interface_opts = &g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
461             interface_opts->sampling_method = CAPTURE_SAMP_BY_TIMER;
462             interface_opts->sampling_param = get_positive_int(p, "sampling timer");
463         } else {
464             capture_opts->default_options.sampling_method = CAPTURE_SAMP_BY_TIMER;
465             capture_opts->default_options.sampling_param = get_positive_int(p, "sampling timer");
466         }
467     }
468     *colonp = ':';
469     return TRUE;
470 }
471 #endif
472
473 #ifdef HAVE_PCAP_REMOTE
474 /*
475  * Given a string of the form "<username>:<password>", as might appear
476  * as an argument to a "-A" option, parse it and set the arguments in
477  * question.  Return an indication of whether it succeeded or failed
478  * in some fashion.
479  */
480 static gboolean
481 get_auth_arguments(capture_options *capture_opts, const char *arg)
482 {
483     gchar *p = NULL, *colonp;
484
485     colonp = strchr(arg, ':');
486     if (colonp == NULL)
487         return FALSE;
488
489     p = colonp;
490     *p++ = '\0';
491
492     while (g_ascii_isspace(*p))
493         p++;
494
495     if (capture_opts->ifaces->len > 0) {
496         interface_options *interface_opts;
497
498         interface_opts = &g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
499         interface_opts->auth_type = CAPTURE_AUTH_PWD;
500         interface_opts->auth_username = g_strdup(arg);
501         interface_opts->auth_password = g_strdup(p);
502     } else {
503         capture_opts->default_options.auth_type = CAPTURE_AUTH_PWD;
504         capture_opts->default_options.auth_username = g_strdup(arg);
505         capture_opts->default_options.auth_password = g_strdup(p);
506     }
507     *colonp = ':';
508     return TRUE;
509 }
510 #endif
511
512 #ifdef _WIN32
513 static char *
514 capture_opts_generate_display_name(const char *friendly_name,
515                                    const char *name _U_)
516 {
517     /*
518      * Display the friendly name rather than the not-so-friendly
519      * GUID-based interface name.
520      */
521     return g_strdup(friendly_name);
522 }
523 #else
524 static char *
525 capture_opts_generate_display_name(const char *friendly_name,
526                                    const char *name)
527 {
528     /*
529      * On UN*X, however, users are more used to interface names,
530      * and may find it helpful to see them.
531      */
532     return g_strdup_printf("%s: %s", friendly_name, name);
533 }
534 #endif
535
536 static void
537 fill_in_interface_opts_from_ifinfo(interface_options *interface_opts,
538                                    const if_info_t *if_info)
539 {
540     interface_opts->name = g_strdup(if_info->name);
541
542     if (if_info->friendly_name != NULL) {
543         /*
544          * We have a friendly name; remember it as the
545          * description...
546          */
547         interface_opts->descr = g_strdup(if_info->friendly_name);
548         /*
549          * ...and use it in the console display name.
550          */
551         interface_opts->display_name = capture_opts_generate_display_name(if_info->friendly_name, if_info->name);
552     } else {
553         /* fallback to the interface name */
554         interface_opts->descr = NULL;
555         interface_opts->display_name = g_strdup(if_info->name);
556     }
557     interface_opts->if_type = if_info->type;
558     interface_opts->extcap = g_strdup(if_info->extcap);
559 }
560
561 static gboolean
562 fill_in_interface_opts_from_ifinfo_by_name(interface_options *interface_opts,
563                                            const char *name)
564 {
565     gboolean    matched;
566     GList       *if_list;
567     int         err;
568     GList       *if_entry;
569     if_info_t   *if_info;
570     size_t      prefix_length;
571
572     matched = FALSE;
573     if_list = capture_interface_list(&err, NULL, NULL);
574     if (if_list != NULL) {
575         /*
576          * Try and do an exact match (case insensitive) on  the
577          * interface name, the interface description, and the
578          * hardware description.
579          */
580         for (if_entry = g_list_first(if_list); if_entry != NULL;
581              if_entry = g_list_next(if_entry))
582         {
583             if_info = (if_info_t *)if_entry->data;
584
585             /*
586              * Does the specified name match the interface name
587              * with a case-insensitive match?
588              */
589             if (g_ascii_strcasecmp(if_info->name, name) == 0) {
590                 /*
591                  * Yes.
592                  */
593                 matched = TRUE;
594                 break;
595             }
596
597             /*
598              * Does this interface have a friendly name and, if so,
599              * does the specified name match the friendly name with
600              * a case-insensitive match?
601              */
602             if (if_info->friendly_name != NULL &&
603                 g_ascii_strcasecmp(if_info->friendly_name, name) == 0) {
604                 /*
605                  * Yes.
606                  */
607                 matched = TRUE;
608                 break;
609             }
610         }
611
612         if (!matched) {
613             /*
614              * We didn't find it; attempt a case-insensitive prefix match
615              * of the friendly name.
616              */
617             prefix_length = strlen(name);
618             for (if_entry = g_list_first(if_list); if_entry != NULL;
619                  if_entry = g_list_next(if_entry))
620             {
621                 if_info = (if_info_t *)if_entry->data;
622
623                 if (if_info->friendly_name != NULL &&
624                     g_ascii_strncasecmp(if_info->friendly_name, name, prefix_length) == 0) {
625                     /*
626                      * We found an interface whose friendly name matches
627                      * with a case-insensitive prefix match.
628                      */
629                     matched = TRUE;
630                     break;
631                 }
632             }
633         }
634     }
635
636     if (matched) {
637         /*
638          * We found an interface that matches.
639          */
640         fill_in_interface_opts_from_ifinfo(interface_opts, if_info);
641     }
642     free_interface_list(if_list);
643     return matched;
644 }
645
646 static int
647 capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str_p)
648 {
649     long        adapter_index;
650     char        *p;
651     GList       *if_list;
652     if_info_t   *if_info;
653     int         err;
654     gchar       *err_str;
655     interface_options interface_opts;
656
657     /*
658      * If the argument is a number, treat it as an index into the list
659      * of adapters, as printed by "tshark -D".
660      *
661      * This should be OK on UNIX systems, as interfaces shouldn't have
662      * names that begin with digits.  It can be useful on Windows, where
663      * more than one interface can have the same name.
664      */
665     adapter_index = strtol(optarg_str_p, &p, 10);
666     if (p != NULL && *p == '\0') {
667         if (adapter_index < 0) {
668             cmdarg_err("The specified adapter index is a negative number");
669             return 1;
670         }
671         if (adapter_index > INT_MAX) {
672             cmdarg_err("The specified adapter index is too large (greater than %d)",
673                        INT_MAX);
674             return 1;
675         }
676         if (adapter_index == 0) {
677             cmdarg_err("There is no interface with that adapter index");
678             return 1;
679         }
680         if_list = capture_interface_list(&err, &err_str, NULL);
681         if (if_list == NULL) {
682             if (err == 0)
683                 cmdarg_err("There are no interfaces on which a capture can be done");
684             else {
685                 cmdarg_err("%s", err_str);
686                 g_free(err_str);
687             }
688             return 2;
689         }
690         if_info = (if_info_t *)g_list_nth_data(if_list, (int)(adapter_index - 1));
691         if (if_info == NULL) {
692             cmdarg_err("There is no interface with that adapter index");
693             return 1;
694         }
695         fill_in_interface_opts_from_ifinfo(&interface_opts, if_info);
696         free_interface_list(if_list);
697     } else if (capture_opts->capture_child) {
698         /*
699          * In Wireshark capture child mode, so the exact interface name
700          * is supplied, and we don't need to look it up.
701          */
702         if_info = if_info_get(optarg_str_p);
703         fill_in_interface_opts_from_ifinfo(&interface_opts, if_info);
704         if_info_free(if_info);
705     } else {
706         /*
707          * Search for that name in the interface list and, if we found
708          * it, fill in fields in the interface_opts structure.
709          */
710         if (!fill_in_interface_opts_from_ifinfo_by_name(&interface_opts,
711                                                         optarg_str_p)) {
712             /*
713              * We didn't find the interface in the list; just use
714              * the specified name, so that, for example, if an
715              * interface doesn't show up in the list for some
716              * reason, the user can try specifying it explicitly
717              * for testing purposes.
718              */
719             interface_opts.name = g_strdup(optarg_str_p);
720             interface_opts.descr = NULL;
721             interface_opts.display_name = g_strdup(optarg_str_p);
722             interface_opts.if_type = capture_opts->default_options.if_type;
723             interface_opts.extcap = g_strdup(capture_opts->default_options.extcap);
724         }
725     }
726
727     interface_opts.cfilter = g_strdup(capture_opts->default_options.cfilter);
728     interface_opts.snaplen = capture_opts->default_options.snaplen;
729     interface_opts.has_snaplen = capture_opts->default_options.has_snaplen;
730     interface_opts.linktype = capture_opts->default_options.linktype;
731     interface_opts.promisc_mode = capture_opts->default_options.promisc_mode;
732     interface_opts.extcap_fifo = g_strdup(capture_opts->default_options.extcap_fifo);
733     interface_opts.extcap_args = NULL;
734     interface_opts.extcap_pid = WS_INVALID_PID;
735     interface_opts.extcap_pipedata = NULL;
736 #ifdef _WIN32
737     interface_opts.extcap_pipe_h = INVALID_HANDLE_VALUE;
738     interface_opts.extcap_control_in_h = INVALID_HANDLE_VALUE;
739     interface_opts.extcap_control_out_h = INVALID_HANDLE_VALUE;
740 #endif
741     interface_opts.extcap_control_in = g_strdup(capture_opts->default_options.extcap_control_in);
742     interface_opts.extcap_control_out = g_strdup(capture_opts->default_options.extcap_control_out);
743 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
744     interface_opts.buffer_size = capture_opts->default_options.buffer_size;
745 #endif
746     interface_opts.monitor_mode = capture_opts->default_options.monitor_mode;
747 #ifdef HAVE_PCAP_REMOTE
748     interface_opts.src_type = capture_opts->default_options.src_type;
749     interface_opts.remote_host = g_strdup(capture_opts->default_options.remote_host);
750     interface_opts.remote_port = g_strdup(capture_opts->default_options.remote_port);
751     interface_opts.auth_type = capture_opts->default_options.auth_type;
752     interface_opts.auth_username = g_strdup(capture_opts->default_options.auth_username);
753     interface_opts.auth_password = g_strdup(capture_opts->default_options.auth_password);
754     interface_opts.datatx_udp = capture_opts->default_options.datatx_udp;
755     interface_opts.nocap_rpcap = capture_opts->default_options.nocap_rpcap;
756     interface_opts.nocap_local = capture_opts->default_options.nocap_local;
757 #endif
758 #ifdef HAVE_PCAP_SETSAMPLING
759     interface_opts.sampling_method = capture_opts->default_options.sampling_method;
760     interface_opts.sampling_param  = capture_opts->default_options.sampling_param;
761 #endif
762     interface_opts.timestamp_type  = capture_opts->default_options.timestamp_type;
763
764     g_array_append_val(capture_opts->ifaces, interface_opts);
765
766     return 0;
767 }
768
769
770 int
771 capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_str_p, gboolean *start_capture)
772 {
773     int status, snaplen;
774
775     switch(opt) {
776     case LONGOPT_NUM_CAP_COMMENT:  /* capture comment */
777         if (capture_opts->capture_comment) {
778             cmdarg_err("--capture-comment can be set only once per file");
779             return 1;
780         }
781         capture_opts->capture_comment = g_strdup(optarg_str_p);
782         break;
783     case 'a':        /* autostop criteria */
784         if (set_autostop_criterion(capture_opts, optarg_str_p) == FALSE) {
785             cmdarg_err("Invalid or unknown -a flag \"%s\"", optarg_str_p);
786             return 1;
787         }
788         break;
789 #ifdef HAVE_PCAP_REMOTE
790     case 'A':
791         if (get_auth_arguments(capture_opts, optarg_str_p) == FALSE) {
792             cmdarg_err("Invalid or unknown -A arg \"%s\"", optarg_str_p);
793             return 1;
794         }
795         break;
796 #endif
797     case 'b':        /* Ringbuffer option */
798         capture_opts->multi_files_on = TRUE;
799         if (get_ring_arguments(capture_opts, optarg_str_p) == FALSE) {
800             cmdarg_err("Invalid or unknown -b arg \"%s\"", optarg_str_p);
801             return 1;
802         }
803         break;
804 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
805     case 'B':        /* Buffer size */
806         if (capture_opts->ifaces->len > 0) {
807             interface_options *interface_opts;
808
809             interface_opts = &g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
810             interface_opts->buffer_size = get_positive_int(optarg_str_p, "buffer size");
811         } else {
812             capture_opts->default_options.buffer_size = get_positive_int(optarg_str_p, "buffer size");
813         }
814         break;
815 #endif
816     case 'c':        /* Capture n packets */
817         /* XXX Use set_autostop_criterion instead? */
818         capture_opts->has_autostop_packets = TRUE;
819         capture_opts->autostop_packets = get_positive_int(optarg_str_p, "packet count");
820         break;
821     case 'f':        /* capture filter */
822         get_filter_arguments(capture_opts, optarg_str_p);
823         break;
824     case 'g':        /* enable group read access on the capture file(s) */
825         capture_opts->group_read_access = TRUE;
826         break;
827     case 'H':        /* Hide capture info dialog box */
828         capture_opts->show_info = FALSE;
829         break;
830     case LONGOPT_SET_TSTAMP_TYPE:        /* Set capture time stamp type */
831         if (capture_opts->ifaces->len > 0) {
832             interface_options *interface_opts;
833
834             interface_opts = &g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
835             g_free(interface_opts->timestamp_type);
836             interface_opts->timestamp_type = g_strdup(optarg_str_p);
837         } else {
838             g_free(capture_opts->default_options.timestamp_type);
839             capture_opts->default_options.timestamp_type = g_strdup(optarg_str_p);
840         }
841         break;
842     case 'i':        /* Use interface x */
843         status = capture_opts_add_iface_opt(capture_opts, optarg_str_p);
844         if (status != 0) {
845             return status;
846         }
847         break;
848 #ifdef HAVE_PCAP_CREATE
849     case 'I':        /* Capture in monitor mode */
850         if (capture_opts->ifaces->len > 0) {
851             interface_options *interface_opts;
852
853             interface_opts = &g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
854             interface_opts->monitor_mode = TRUE;
855         } else {
856             capture_opts->default_options.monitor_mode = TRUE;
857         }
858         break;
859 #endif
860     case 'k':        /* Start capture immediately */
861         *start_capture = TRUE;
862         break;
863     /*case 'l':*/    /* Automatic scrolling in live capture mode */
864 #ifdef HAVE_PCAP_SETSAMPLING
865     case 'm':
866         if (get_sampling_arguments(capture_opts, optarg_str_p) == FALSE) {
867             cmdarg_err("Invalid or unknown -m arg \"%s\"", optarg_str_p);
868             return 1;
869         }
870         break;
871 #endif
872     case 'n':        /* Use pcapng format */
873         capture_opts->use_pcapng = TRUE;
874         break;
875     case 'p':        /* Don't capture in promiscuous mode */
876         if (capture_opts->ifaces->len > 0) {
877             interface_options *interface_opts;
878
879             interface_opts = &g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
880             interface_opts->promisc_mode = FALSE;
881         } else {
882             capture_opts->default_options.promisc_mode = FALSE;
883         }
884         break;
885     case 'P':        /* Use pcap format */
886         capture_opts->use_pcapng = FALSE;
887         break;
888 #ifdef HAVE_PCAP_REMOTE
889     case 'r':
890         if (capture_opts->ifaces->len > 0) {
891             interface_options *interface_opts;
892
893             interface_opts = &g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
894             interface_opts->nocap_rpcap = FALSE;
895         } else {
896             capture_opts->default_options.nocap_rpcap = FALSE;
897         }
898         break;
899 #endif
900     case 's':        /* Set the snapshot (capture) length */
901         snaplen = get_natural_int(optarg_str_p, "snapshot length");
902         /*
903          * Make a snapshot length of 0 equivalent to the maximum packet
904          * length, mirroring what tcpdump does.
905          */
906         if (snaplen == 0)
907             snaplen = WTAP_MAX_PACKET_SIZE_STANDARD;
908         if (capture_opts->ifaces->len > 0) {
909             interface_options *interface_opts;
910
911             interface_opts = &g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
912             interface_opts->has_snaplen = TRUE;
913             interface_opts->snaplen = snaplen;
914         } else {
915             capture_opts->default_options.snaplen = snaplen;
916             capture_opts->default_options.has_snaplen = TRUE;
917         }
918         break;
919     case 'S':        /* "Real-Time" mode: used for following file ala tail -f */
920         capture_opts->real_time_mode = TRUE;
921         break;
922 #ifdef HAVE_PCAP_REMOTE
923     case 'u':
924         if (capture_opts->ifaces->len > 0) {
925             interface_options *interface_opts;
926
927             interface_opts = &g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
928             interface_opts->datatx_udp = TRUE;
929         } else {
930             capture_opts->default_options.datatx_udp = TRUE;
931         }
932         break;
933 #endif
934     case 'w':        /* Write to capture file x */
935         capture_opts->saving_to_file = TRUE;
936         g_free(capture_opts->save_file);
937         capture_opts->save_file = g_strdup(optarg_str_p);
938         status = capture_opts_output_to_pipe(capture_opts->save_file, &capture_opts->output_to_pipe);
939         return status;
940     case 'y':        /* Set the pcap data link type */
941         if (capture_opts->ifaces->len > 0) {
942             interface_options *interface_opts;
943
944             interface_opts = &g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
945             interface_opts->linktype = linktype_name_to_val(optarg_str_p);
946             if (interface_opts->linktype == -1) {
947                 cmdarg_err("The specified data link type \"%s\" isn't valid",
948                            optarg_str_p);
949                 return 1;
950             }
951         } else {
952             capture_opts->default_options.linktype = linktype_name_to_val(optarg_str_p);
953             if (capture_opts->default_options.linktype == -1) {
954                 cmdarg_err("The specified data link type \"%s\" isn't valid",
955                            optarg_str_p);
956                 return 1;
957             }
958         }
959         break;
960     default:
961         /* the caller is responsible to send us only the right opt's */
962         g_assert_not_reached();
963     }
964
965     return 0;
966 }
967
968 void
969 capture_opts_print_if_capabilities(if_capabilities_t *caps, char *name, int queries)
970 {
971     GList *lt_entry, *ts_entry;
972
973     if (queries & CAPS_QUERY_LINK_TYPES) {
974         if (caps->can_set_rfmon)
975             printf("Data link types of interface %s when %sin monitor mode (use option -y to set):\n",
976                    name, queries & CAPS_MONITOR_MODE ? "" : "not ");
977         else
978             printf("Data link types of interface %s (use option -y to set):\n", name);
979         for (lt_entry = caps->data_link_types; lt_entry != NULL;
980              lt_entry = g_list_next(lt_entry)) {
981             data_link_info_t *data_link_info = (data_link_info_t *)lt_entry->data;
982             printf("  %s", data_link_info->name);
983             if (data_link_info->description != NULL)
984                 printf(" (%s)", data_link_info->description);
985             else
986                 printf(" (not supported)");
987             printf("\n");
988         }
989     }
990
991     if (queries & CAPS_QUERY_TIMESTAMP_TYPES) {
992         printf("Timestamp types of the interface (use option --time-stamp-type to set):\n");
993         for (ts_entry = caps->timestamp_types; ts_entry != NULL;
994              ts_entry = g_list_next(ts_entry)) {
995             timestamp_info_t *timestamp = (timestamp_info_t *)ts_entry->data;
996             printf("  %s", timestamp->name);
997             if (timestamp->description != NULL)
998                 printf(" (%s)", timestamp->description);
999             else
1000                 printf(" (none)");
1001             printf("\n");
1002         }
1003     }
1004 }
1005
1006 /* Print an ASCII-formatted list of interfaces. */
1007 void
1008 capture_opts_print_interfaces(GList *if_list)
1009 {
1010     int         i;
1011     GList       *if_entry;
1012     if_info_t   *if_info;
1013
1014     i = 1;  /* Interface id number */
1015     for (if_entry = g_list_first(if_list); if_entry != NULL;
1016          if_entry = g_list_next(if_entry)) {
1017         if_info = (if_info_t *)if_entry->data;
1018         printf("%d. %s", i++, if_info->name);
1019
1020         /* Print the interface friendly name, if it exists;
1021           if not, fall back to the vendor description, if it exists. */
1022         if (if_info->friendly_name != NULL){
1023             printf(" (%s)", if_info->friendly_name);
1024         } else {
1025             if (if_info->vendor_description != NULL)
1026                 printf(" (%s)", if_info->vendor_description);
1027         }
1028         printf("\n");
1029     }
1030 }
1031
1032
1033 void
1034 capture_opts_trim_snaplen(capture_options *capture_opts, int snaplen_min)
1035 {
1036     guint i;
1037     interface_options *interface_opts;
1038
1039     if (capture_opts->ifaces->len > 0) {
1040         for (i = 0; i < capture_opts->ifaces->len; i++) {
1041             interface_opts = &g_array_index(capture_opts->ifaces, interface_options, 0);
1042             if (interface_opts->snaplen < 1)
1043                 interface_opts->snaplen = WTAP_MAX_PACKET_SIZE_STANDARD;
1044             else if (interface_opts->snaplen < snaplen_min)
1045                 interface_opts->snaplen = snaplen_min;
1046         }
1047     } else {
1048         if (capture_opts->default_options.snaplen < 1)
1049             capture_opts->default_options.snaplen = WTAP_MAX_PACKET_SIZE_STANDARD;
1050         else if (capture_opts->default_options.snaplen < snaplen_min)
1051             capture_opts->default_options.snaplen = snaplen_min;
1052     }
1053 }
1054
1055
1056 void
1057 capture_opts_trim_ring_num_files(capture_options *capture_opts)
1058 {
1059     /* Check the value range of the ring_num_files parameter */
1060     if (capture_opts->ring_num_files > RINGBUFFER_MAX_NUM_FILES) {
1061         cmdarg_err("Too many ring buffer files (%u). Reducing to %u.\n", capture_opts->ring_num_files, RINGBUFFER_MAX_NUM_FILES);
1062         capture_opts->ring_num_files = RINGBUFFER_MAX_NUM_FILES;
1063     } else if (capture_opts->ring_num_files > RINGBUFFER_WARN_NUM_FILES) {
1064         cmdarg_err("%u is a lot of ring buffer files.\n", capture_opts->ring_num_files);
1065     }
1066 #if RINGBUFFER_MIN_NUM_FILES > 0
1067     else if (capture_opts->ring_num_files < RINGBUFFER_MIN_NUM_FILES)
1068         cmdarg_err("Too few ring buffer files (%u). Increasing to %u.\n", capture_opts->ring_num_files, RINGBUFFER_MIN_NUM_FILES);
1069         capture_opts->ring_num_files = RINGBUFFER_MIN_NUM_FILES;
1070 #endif
1071 }
1072
1073 /*
1074  * If no interface was specified explicitly, pick a default.
1075  */
1076 int
1077 capture_opts_default_iface_if_necessary(capture_options *capture_opts,
1078                                         const char *capture_device)
1079 {
1080     int status;
1081
1082     /* Did the user specify an interface to use? */
1083     if (capture_opts->num_selected != 0 || capture_opts->ifaces->len != 0) {
1084         /* yes they did, return immediately - nothing further to do here */
1085         return 0;
1086     }
1087
1088     /* No - is a default specified in the preferences file? */
1089     if (capture_device != NULL) {
1090         /* Yes - use it. */
1091         status = capture_opts_add_iface_opt(capture_opts, capture_device);
1092         return status;
1093     }
1094     /* No default in preferences file, just pick the first interface from the list of interfaces. */
1095     return capture_opts_add_iface_opt(capture_opts, "1");
1096 }
1097
1098 #ifndef S_IFIFO
1099 #define S_IFIFO _S_IFIFO
1100 #endif
1101 #ifndef S_ISFIFO
1102 #define S_ISFIFO(mode)  (((mode) & S_IFMT) == S_IFIFO)
1103 #endif
1104
1105 /* copied from filesystem.c */
1106 static int
1107 capture_opts_test_for_fifo(const char *path)
1108 {
1109     ws_statb64 statb;
1110
1111     if (ws_stat64(path, &statb) < 0)
1112         return errno;
1113
1114     if (S_ISFIFO(statb.st_mode))
1115         return ESPIPE;
1116     else
1117         return 0;
1118 }
1119
1120 static gboolean
1121 capture_opts_output_to_pipe(const char *save_file, gboolean *is_pipe)
1122 {
1123     int err;
1124
1125     *is_pipe = FALSE;
1126
1127     if (save_file != NULL) {
1128         /* We're writing to a capture file. */
1129         if (strcmp(save_file, "-") == 0) {
1130             /* Writing to stdout. */
1131             /* XXX - should we check whether it's a pipe?  It's arguably
1132                silly to do "-w - >output_file" rather than "-w output_file",
1133                but by not checking we might be violating the Principle Of
1134                Least Astonishment. */
1135             *is_pipe = TRUE;
1136         } else {
1137             /* not writing to stdout, test for a FIFO (aka named pipe) */
1138             err = capture_opts_test_for_fifo(save_file);
1139             switch (err) {
1140
1141             case ENOENT:      /* it doesn't exist, so we'll be creating it,
1142                                  and it won't be a FIFO */
1143             case 0:           /* found it, but it's not a FIFO */
1144                 break;
1145
1146             case ESPIPE:      /* it is a FIFO */
1147                 *is_pipe = TRUE;
1148                 break;
1149
1150             default:          /* couldn't stat it              */
1151                 break;          /* ignore: later attempt to open */
1152                 /*  will generate a nice msg     */
1153             }
1154         }
1155     }
1156
1157     return 0;
1158 }
1159
1160 void
1161 capture_opts_del_iface(capture_options *capture_opts, guint if_index)
1162 {
1163     interface_options *interface_opts;
1164
1165     interface_opts = &g_array_index(capture_opts->ifaces, interface_options, if_index);
1166     /* XXX - check if found? */
1167
1168     g_free(interface_opts->name);
1169     g_free(interface_opts->descr);
1170     g_free(interface_opts->display_name);
1171     g_free(interface_opts->cfilter);
1172     g_free(interface_opts->timestamp_type);
1173     g_free(interface_opts->extcap);
1174     g_free(interface_opts->extcap_fifo);
1175     if (interface_opts->extcap_args)
1176         g_hash_table_unref(interface_opts->extcap_args);
1177     if (interface_opts->extcap_pid != WS_INVALID_PID)
1178         ws_pipe_close((ws_pipe_t *) interface_opts->extcap_pipedata);
1179     g_free(interface_opts->extcap_pipedata);
1180     g_free(interface_opts->extcap_control_in);
1181     g_free(interface_opts->extcap_control_out);
1182 #ifdef HAVE_PCAP_REMOTE
1183     if (interface_opts->src_type == CAPTURE_IFREMOTE) {
1184         g_free(interface_opts->remote_host);
1185         g_free(interface_opts->remote_port);
1186         g_free(interface_opts->auth_username);
1187         g_free(interface_opts->auth_password);
1188     }
1189 #endif
1190     capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, if_index);
1191 }
1192
1193
1194
1195 /*
1196  * Add all non-hidden selected interfaces in the "all interfaces" list
1197  * to the list of interfaces for the capture.
1198  */
1199 void
1200 collect_ifaces(capture_options *capture_opts)
1201 {
1202     guint i;
1203     interface_t *device;
1204     interface_options interface_opts;
1205
1206     /* Empty out the existing list of interfaces. */
1207     for (i = capture_opts->ifaces->len; i != 0; i--)
1208         capture_opts_del_iface(capture_opts, i-1);
1209
1210     /* Now fill the list up again. */
1211     for (i = 0; i < capture_opts->all_ifaces->len; i++) {
1212         device = &g_array_index(capture_opts->all_ifaces, interface_t, i);
1213         if (!device->hidden && device->selected) {
1214             interface_opts.name = g_strdup(device->name);
1215             interface_opts.descr = g_strdup(device->friendly_name);
1216             interface_opts.display_name = g_strdup(device->display_name);
1217             interface_opts.linktype = device->active_dlt;
1218             interface_opts.cfilter = g_strdup(device->cfilter);
1219             interface_opts.timestamp_type = g_strdup(device->timestamp_type);
1220             interface_opts.snaplen = device->snaplen;
1221             interface_opts.has_snaplen = device->has_snaplen;
1222             interface_opts.promisc_mode = device->pmode;
1223             interface_opts.if_type = device->if_info.type;
1224             interface_opts.extcap = g_strdup(device->if_info.extcap);
1225             interface_opts.extcap_fifo = NULL;
1226             interface_opts.extcap_pipedata = NULL;
1227             interface_opts.extcap_args = device->external_cap_args_settings;
1228             interface_opts.extcap_pid = WS_INVALID_PID;
1229             if (interface_opts.extcap_args)
1230                 g_hash_table_ref(interface_opts.extcap_args);
1231             interface_opts.extcap_pipedata = NULL;
1232 #ifdef _WIN32
1233             interface_opts.extcap_pipe_h = INVALID_HANDLE_VALUE;
1234             interface_opts.extcap_control_in_h = INVALID_HANDLE_VALUE;
1235             interface_opts.extcap_control_out_h = INVALID_HANDLE_VALUE;
1236 #endif
1237             interface_opts.extcap_control_in = NULL;
1238             interface_opts.extcap_control_out = NULL;
1239 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
1240             interface_opts.buffer_size =  device->buffer;
1241 #endif
1242 #ifdef HAVE_PCAP_CREATE
1243             interface_opts.monitor_mode = device->monitor_mode_enabled;
1244 #endif
1245 #ifdef HAVE_PCAP_REMOTE
1246             interface_opts.src_type = CAPTURE_IFREMOTE;
1247             interface_opts.remote_host = g_strdup(device->remote_opts.remote_host_opts.remote_host);
1248             interface_opts.remote_port = g_strdup(device->remote_opts.remote_host_opts.remote_port);
1249             interface_opts.auth_type = device->remote_opts.remote_host_opts.auth_type;
1250             interface_opts.auth_username = g_strdup(device->remote_opts.remote_host_opts.auth_username);
1251             interface_opts.auth_password = g_strdup(device->remote_opts.remote_host_opts.auth_password);
1252             interface_opts.datatx_udp = device->remote_opts.remote_host_opts.datatx_udp;
1253             interface_opts.nocap_rpcap = device->remote_opts.remote_host_opts.nocap_rpcap;
1254             interface_opts.nocap_local = device->remote_opts.remote_host_opts.nocap_local;
1255 #endif
1256 #ifdef HAVE_PCAP_SETSAMPLING
1257             interface_opts.sampling_method = device->remote_opts.sampling_method;
1258             interface_opts.sampling_param  = device->remote_opts.sampling_param;
1259 #endif
1260             g_array_append_val(capture_opts->ifaces, interface_opts);
1261         } else {
1262             continue;
1263         }
1264     }
1265 }
1266
1267 static void
1268 capture_opts_free_interface_t_links(gpointer elem, gpointer unused _U_)
1269 {
1270     link_row* e = (link_row*)elem;
1271     if (e != NULL)
1272         g_free(e->name);
1273     g_free(elem);
1274 }
1275
1276 void
1277 capture_opts_free_interface_t(interface_t *device)
1278 {
1279     if (device != NULL) {
1280         g_free(device->name);
1281         g_free(device->display_name);
1282         g_free(device->friendly_name);
1283         g_free(device->addresses);
1284         g_free(device->cfilter);
1285         g_free(device->timestamp_type);
1286         g_list_foreach(device->links,
1287                        capture_opts_free_interface_t_links, NULL);
1288         g_list_free(device->links);
1289 #ifdef HAVE_PCAP_REMOTE
1290         g_free(device->remote_opts.remote_host_opts.remote_host);
1291         g_free(device->remote_opts.remote_host_opts.remote_port);
1292         g_free(device->remote_opts.remote_host_opts.auth_username);
1293         g_free(device->remote_opts.remote_host_opts.auth_password);
1294 #endif
1295         g_free(device->if_info.name);
1296         g_free(device->if_info.friendly_name);
1297         g_free(device->if_info.vendor_description);
1298         g_slist_free_full(device->if_info.addrs, g_free);
1299         g_free(device->if_info.extcap);
1300     }
1301 }
1302
1303 #endif /* HAVE_LIBPCAP */
1304
1305 /*
1306  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
1307  *
1308  * Local variables:
1309  * c-basic-offset: 4
1310  * tab-width: 8
1311  * indent-tabs-mode: nil
1312  * End:
1313  *
1314  * vi: set shiftwidth=4 tabstop=8 expandtab:
1315  * :indentSize=4:tabSize=8:noTabs=true:
1316  */