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