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