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