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