* Fix a bug when printing a pointer.
[obnox/wireshark/wip.git] / capture_opts.c
1 /* capture_opts.c
2  * Routines for capture options setting
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #ifdef HAVE_LIBPCAP
30
31 #include <string.h>
32 #include <ctype.h>
33
34 #ifdef HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif
37
38 #include <glib.h>
39
40 #include <epan/packet.h>
41
42 #include "capture_opts.h"
43 #include "ringbuffer.h"
44 #include "clopts_common.h"
45 #include "console_io.h"
46 #include "cmdarg_err.h"
47
48 #include "capture_ifinfo.h"
49 #include "capture-pcap-util.h"
50 #include <wsutil/file_util.h>
51
52 static gboolean capture_opts_output_to_pipe(const char *save_file, gboolean *is_pipe);
53
54
55 void
56 capture_opts_init(capture_options *capture_opts, void *cf)
57 {
58   capture_opts->cf                           = cf;
59   capture_opts->cfilter                      = g_strdup("");     /* No capture filter string specified */
60   capture_opts->iface                        = NULL;             /* Default is "pick the first interface" */
61   capture_opts->iface_descr                  = NULL;
62   capture_opts->ifaces                       = g_array_new(FALSE, FALSE, sizeof(interface_options));
63   capture_opts->default_options.name         = g_strdup("");
64   capture_opts->default_options.descr        = g_strdup("");
65   capture_opts->default_options.cfilter      = g_strdup("");
66   capture_opts->default_options.snaplen      = WTAP_MAX_PACKET_SIZE;
67   capture_opts->default_options.linktype     = -1;
68   capture_opts->default_options.promisc_mode = TRUE;
69 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
70   capture_opts->default_options.buffer_size  = 1;                /* 1 MB */
71 #endif
72   capture_opts->default_options.monitor_mode = FALSE;
73 #ifdef HAVE_PCAP_REMOTE
74   capture_opts->src_type                     = CAPTURE_IFLOCAL;
75   capture_opts->remote_host                  = NULL;
76   capture_opts->remote_port                  = NULL;
77   capture_opts->auth_type                    = CAPTURE_AUTH_NULL;
78   capture_opts->auth_username                = NULL;
79   capture_opts->auth_password                = NULL;
80   capture_opts->datatx_udp                   = FALSE;
81   capture_opts->nocap_rpcap                  = TRUE;
82   capture_opts->nocap_local                  = FALSE;
83 #endif
84 #ifdef HAVE_PCAP_SETSAMPLING
85   capture_opts->sampling_method              = CAPTURE_SAMP_NONE;
86   capture_opts->sampling_param               = 0;
87 #endif
88 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
89   capture_opts->buffer_size                  = 1;                /* 1 MB */
90 #endif
91   capture_opts->has_snaplen                  = FALSE;
92   capture_opts->snaplen                      = WTAP_MAX_PACKET_SIZE; /* snapshot length - default is
93                                                                         infinite, in effect */
94   capture_opts->promisc_mode                 = TRUE;             /* promiscuous mode is the default */
95   capture_opts->monitor_mode                 = FALSE;
96   capture_opts->linktype                     = -1;               /* the default linktype */
97   capture_opts->saving_to_file               = FALSE;
98   capture_opts->save_file                    = NULL;
99   capture_opts->group_read_access            = FALSE;
100   capture_opts->use_pcapng                   = FALSE;            /* the default is pcap */
101   capture_opts->real_time_mode               = TRUE;
102   capture_opts->show_info                    = TRUE;
103   capture_opts->quit_after_cap               = FALSE;
104   capture_opts->restart                      = FALSE;
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_ring_num_files           = FALSE;
110   capture_opts->ring_num_files               = RINGBUFFER_MIN_NUM_FILES;
111
112   capture_opts->has_autostop_files           = FALSE;
113   capture_opts->autostop_files               = 1;
114   capture_opts->has_autostop_packets         = FALSE;
115   capture_opts->autostop_packets             = 0;
116   capture_opts->has_autostop_filesize        = FALSE;
117   capture_opts->autostop_filesize            = 1024;             /* 1 MB */
118   capture_opts->has_autostop_duration        = FALSE;
119   capture_opts->autostop_duration            = 60;               /* 1 min */
120
121
122   capture_opts->fork_child                   = -1;               /* invalid process handle */
123 #ifdef _WIN32
124   capture_opts->signal_pipe_write_fd         = -1;
125 #endif
126   capture_opts->state                        = CAPTURE_STOPPED;
127   capture_opts->output_to_pipe               = FALSE;
128 #ifndef _WIN32
129   capture_opts->owner                        = getuid();
130   capture_opts->group                        = getgid();
131 #endif
132 }
133
134
135 /* log content of capture_opts */
136 void
137 capture_opts_log(const char *log_domain, GLogLevelFlags log_level, capture_options *capture_opts) {
138     guint i;
139
140     g_log(log_domain, log_level, "CAPTURE OPTIONS    :");
141     g_log(log_domain, log_level, "CFile              : %p", capture_opts->cf);
142     g_log(log_domain, log_level, "Filter             : %s", capture_opts->cfilter);
143
144     for (i = 0; i < capture_opts->ifaces->len; i++) {
145         interface_options options;
146         
147         options = g_array_index(capture_opts->ifaces, interface_options, i);
148         g_log(log_domain, log_level, "Interface name[%02d] : %s", i, options.name);
149         g_log(log_domain, log_level, "Interface Descr[%02d]: %s", i, options.descr);
150         g_log(log_domain, log_level, "Capture filter[%02d] : %s", i, options.cfilter);
151         g_log(log_domain, log_level, "Snap length[%02d]    : %d", i, options.snaplen);
152         g_log(log_domain, log_level, "Link Type[%02d]      : %d", i, options.linktype);
153         g_log(log_domain, log_level, "Promiscous Mode[%02d]: %s", i, options.promisc_mode?"TRUE":"FALSE");
154 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
155         g_log(log_domain, log_level, "Buffer size[%02d]    : %d (MB)", i, options.buffer_size);
156 #endif
157         g_log(log_domain, log_level, "Monitor Mode[%02d]   : %s", i, options.monitor_mode?"TRUE":"FALSE");
158     }
159     g_log(log_domain, log_level, "Interface name[df] : %s", capture_opts->default_options.name);
160     g_log(log_domain, log_level, "Capture filter[df] : %s", capture_opts->default_options.cfilter);
161     g_log(log_domain, log_level, "Snap length[df]    : %d", capture_opts->default_options.snaplen);
162     g_log(log_domain, log_level, "Link Type[df]      : %d", capture_opts->default_options.linktype);
163     g_log(log_domain, log_level, "Promiscous Mode[df]: %s", capture_opts->default_options.promisc_mode?"TRUE":"FALSE");
164
165 #ifdef HAVE_PCAP_REMOTE
166     g_log(log_domain, log_level, "Capture source     : %s",
167         capture_opts->src_type == CAPTURE_IFLOCAL ? "Local interface" :
168         capture_opts->src_type == CAPTURE_IFREMOTE ? "Remote interface" :
169         "Unknown");
170     if (capture_opts->src_type == CAPTURE_IFREMOTE) {
171         g_log(log_domain, log_level, "Remote host        : %s", capture_opts->remote_host);
172         g_log(log_domain, log_level, "Remote port        : %s", capture_opts->remote_port);
173     }
174     g_log(log_domain, log_level, "Authentication     : %s",
175         capture_opts->auth_type == CAPTURE_AUTH_NULL ? "Null" :
176         capture_opts->auth_type == CAPTURE_AUTH_PWD ? "By username/password" :
177         "Unknown");
178     if (capture_opts->auth_type == CAPTURE_AUTH_PWD) {
179         g_log(log_domain, log_level, "Auth username      : %s", capture_opts->auth_password);
180         g_log(log_domain, log_level, "Auth password      : <hidden>");
181     }
182     g_log(log_domain, log_level, "UDP data transfer  : %u", capture_opts->datatx_udp);
183     g_log(log_domain, log_level, "No capture RPCAP   : %u", capture_opts->nocap_rpcap);
184     g_log(log_domain, log_level, "No capture local   : %u", capture_opts->nocap_local);
185 #endif
186 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
187     g_log(log_domain, log_level, "BufferSize         : %u (MB)", capture_opts->buffer_size);
188 #endif
189     g_log(log_domain, log_level, "SnapLen         (%u): %u", capture_opts->has_snaplen, capture_opts->snaplen);
190     g_log(log_domain, log_level, "Promisc            : %u", capture_opts->promisc_mode);
191     g_log(log_domain, log_level, "LinkType           : %d", capture_opts->linktype);
192     g_log(log_domain, log_level, "SavingToFile       : %u", capture_opts->saving_to_file);
193     g_log(log_domain, log_level, "SaveFile           : %s", (capture_opts->save_file) ? capture_opts->save_file : "");
194     g_log(log_domain, log_level, "GroupReadAccess    : %u", capture_opts->group_read_access);
195     g_log(log_domain, log_level, "Fileformat         : %s", (capture_opts->use_pcapng) ? "PCAPNG" : "PCAP");
196     g_log(log_domain, log_level, "RealTimeMode       : %u", capture_opts->real_time_mode);
197     g_log(log_domain, log_level, "ShowInfo           : %u", capture_opts->show_info);
198     g_log(log_domain, log_level, "QuitAfterCap       : %u", capture_opts->quit_after_cap);
199
200     g_log(log_domain, log_level, "MultiFilesOn       : %u", capture_opts->multi_files_on);
201     g_log(log_domain, log_level, "FileDuration    (%u): %u", capture_opts->has_file_duration, capture_opts->file_duration);
202     g_log(log_domain, log_level, "RingNumFiles    (%u): %u", capture_opts->has_ring_num_files, capture_opts->ring_num_files);
203
204     g_log(log_domain, log_level, "AutostopFiles   (%u): %u", capture_opts->has_autostop_files, capture_opts->autostop_files);
205     g_log(log_domain, log_level, "AutostopPackets (%u): %u", capture_opts->has_autostop_packets, capture_opts->autostop_packets);
206     g_log(log_domain, log_level, "AutostopFilesize(%u): %u (KB)", capture_opts->has_autostop_filesize, capture_opts->autostop_filesize);
207     g_log(log_domain, log_level, "AutostopDuration(%u): %u", capture_opts->has_autostop_duration, capture_opts->autostop_duration);
208
209     g_log(log_domain, log_level, "ForkChild          : %d", capture_opts->fork_child);
210 #ifdef _WIN32
211     g_log(log_domain, log_level, "SignalPipeWrite    : %d", capture_opts->signal_pipe_write_fd);
212 #endif
213 }
214
215 /*
216  * Given a string of the form "<autostop criterion>:<value>", as might appear
217  * as an argument to a "-a" option, parse it and set the criterion in
218  * question.  Return an indication of whether it succeeded or failed
219  * in some fashion.
220  */
221 static gboolean
222 set_autostop_criterion(capture_options *capture_opts, const char *autostoparg)
223 {
224   gchar *p, *colonp;
225
226   colonp = strchr(autostoparg, ':');
227   if (colonp == NULL)
228     return FALSE;
229
230   p = colonp;
231   *p++ = '\0';
232
233   /*
234    * Skip over any white space (there probably won't be any, but
235    * as we allow it in the preferences file, we might as well
236    * allow it here).
237    */
238   while (isspace((guchar)*p))
239     p++;
240   if (*p == '\0') {
241     /*
242      * Put the colon back, so if our caller uses, in an
243      * error message, the string they passed us, the message
244      * looks correct.
245      */
246     *colonp = ':';
247     return FALSE;
248   }
249   if (strcmp(autostoparg,"duration") == 0) {
250     capture_opts->has_autostop_duration = TRUE;
251     capture_opts->autostop_duration = get_positive_int(p,"autostop duration");
252   } else if (strcmp(autostoparg,"filesize") == 0) {
253     capture_opts->has_autostop_filesize = TRUE;
254     capture_opts->autostop_filesize = get_positive_int(p,"autostop filesize");
255   } else if (strcmp(autostoparg,"files") == 0) {
256     capture_opts->multi_files_on = TRUE;
257     capture_opts->has_autostop_files = TRUE;
258     capture_opts->autostop_files = get_positive_int(p,"autostop files");
259   } else {
260     return FALSE;
261   }
262   *colonp = ':'; /* put the colon back */
263   return TRUE;
264 }
265
266 /*
267  * Given a string of the form "<ring buffer file>:<duration>", as might appear
268  * as an argument to a "-b" option, parse it and set the arguments in
269  * question.  Return an indication of whether it succeeded or failed
270  * in some fashion.
271  */
272 static gboolean
273 get_ring_arguments(capture_options *capture_opts, const char *arg)
274 {
275   gchar *p = NULL, *colonp;
276
277   colonp = strchr(arg, ':');
278   if (colonp == NULL)
279     return FALSE;
280
281   p = colonp;
282   *p++ = '\0';
283
284   /*
285    * Skip over any white space (there probably won't be any, but
286    * as we allow it in the preferences file, we might as well
287    * allow it here).
288    */
289   while (isspace((guchar)*p))
290     p++;
291   if (*p == '\0') {
292     /*
293      * Put the colon back, so if our caller uses, in an
294      * error message, the string they passed us, the message
295      * looks correct.
296      */
297     *colonp = ':';
298     return FALSE;
299   }
300
301   if (strcmp(arg,"files") == 0) {
302     capture_opts->has_ring_num_files = TRUE;
303     capture_opts->ring_num_files = get_positive_int(p, "number of ring buffer files");
304   } else if (strcmp(arg,"filesize") == 0) {
305     capture_opts->has_autostop_filesize = TRUE;
306     capture_opts->autostop_filesize = get_positive_int(p, "ring buffer filesize");
307   } else if (strcmp(arg,"duration") == 0) {
308     capture_opts->has_file_duration = TRUE;
309     capture_opts->file_duration = get_positive_int(p, "ring buffer duration");
310   }
311
312   *colonp = ':';    /* put the colon back */
313   return TRUE;
314 }
315
316 #ifdef HAVE_PCAP_SETSAMPLING
317 /*
318  * Given a string of the form "<sampling type>:<value>", as might appear
319  * as an argument to a "-m" option, parse it and set the arguments in
320  * question.  Return an indication of whether it succeeded or failed
321  * in some fashion.
322  */
323 static gboolean
324 get_sampling_arguments(capture_options *capture_opts, const char *arg)
325 {
326     gchar *p = NULL, *colonp;
327
328     colonp = strchr(arg, ':');
329     if (colonp == NULL)
330         return FALSE;
331
332     p = colonp;
333     *p++ = '\0';
334
335     while (isspace((guchar)*p))
336         p++;
337     if (*p == '\0') {
338         *colonp = ':';
339         return FALSE;
340     }
341
342     if (strcmp(arg, "count") == 0) {
343         capture_opts->sampling_method = CAPTURE_SAMP_BY_COUNT;
344         capture_opts->sampling_param = get_positive_int(p, "sampling count");
345     } else if (strcmp(arg, "timer") == 0) {
346         capture_opts->sampling_method = CAPTURE_SAMP_BY_TIMER;
347         capture_opts->sampling_param = get_positive_int(p, "sampling timer");
348     }
349     *colonp = ':';
350     return TRUE;
351 }
352 #endif
353
354 #ifdef HAVE_PCAP_REMOTE
355 /*
356  * Given a string of the form "<username>:<password>", as might appear
357  * as an argument to a "-A" option, parse it and set the arguments in
358  * question.  Return an indication of whether it succeeded or failed
359  * in some fashion.
360  */
361 static gboolean
362 get_auth_arguments(capture_options *capture_opts, const char *arg)
363 {
364     gchar *p = NULL, *colonp;
365
366     colonp = strchr(arg, ':');
367     if (colonp == NULL)
368         return FALSE;
369
370     p = colonp;
371     *p++ = '\0';
372
373     while (isspace((guchar)*p))
374         p++;
375
376     capture_opts->auth_type = CAPTURE_AUTH_PWD;
377     capture_opts->auth_username = g_strdup(arg);
378     capture_opts->auth_password = g_strdup(p);
379     *colonp = ':';
380     return TRUE;
381 }
382 #endif
383
384 static int
385 capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg_str_p)
386 {
387     long        adapter_index;
388     char        *p;
389     GList       *if_list;
390     if_info_t   *if_info;
391     int         err;
392     gchar       *err_str;
393     interface_options options;
394
395
396     /*
397      * If the argument is a number, treat it as an index into the list
398      * of adapters, as printed by "tshark -D".
399      *
400      * This should be OK on UNIX systems, as interfaces shouldn't have
401      * names that begin with digits.  It can be useful on Windows, where
402      * more than one interface can have the same name.
403      */
404     adapter_index = strtol(optarg_str_p, &p, 10);
405     if (p != NULL && *p == '\0') {
406         if (adapter_index < 0) {
407             cmdarg_err("The specified adapter index is a negative number");
408             return 1;
409         }
410         if (adapter_index > INT_MAX) {
411             cmdarg_err("The specified adapter index is too large (greater than %d)",
412                        INT_MAX);
413             return 1;
414         }
415         if (adapter_index == 0) {
416             cmdarg_err("There is no interface with that adapter index");
417             return 1;
418         }
419         if_list = capture_interface_list(&err, &err_str);
420         if (if_list == NULL) {
421             switch (err) {
422
423             case CANT_GET_INTERFACE_LIST:
424                 cmdarg_err("%s", err_str);
425                 g_free(err_str);
426                 break;
427
428             case NO_INTERFACES_FOUND:
429                 cmdarg_err("There are no interfaces on which a capture can be done");
430                 break;
431             }
432             return 2;
433         }
434         if_info = (if_info_t *)g_list_nth_data(if_list, adapter_index - 1);
435         if (if_info == NULL) {
436             cmdarg_err("There is no interface with that adapter index");
437             return 1;
438         }
439         capture_opts->iface = g_strdup(if_info->name);
440         options.name = g_strdup(if_info->name);
441         /*  We don't set iface_descr here because doing so requires
442          *  capture_ui_utils.c which requires epan/prefs.c which is
443          *  probably a bit too much dependency for here...
444          */
445         free_interface_list(if_list);
446     } else {
447         capture_opts->iface = g_strdup(optarg_str_p);
448         options.name = g_strdup(optarg_str_p);
449     }
450     options.descr = g_strdup(capture_opts->default_options.descr);
451     options.cfilter = g_strdup(capture_opts->default_options.cfilter);
452     options.snaplen = capture_opts->default_options.snaplen;
453     options.linktype = capture_opts->default_options.linktype;
454     options.promisc_mode = capture_opts->default_options.promisc_mode;
455 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
456     options.buffer_size = capture_opts->default_options.buffer_size;
457 #endif
458     options.monitor_mode = capture_opts->default_options.monitor_mode;
459
460     g_array_append_val(capture_opts->ifaces, options);
461
462     return 0;
463 }
464
465 int
466 capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_str_p, gboolean *start_capture)
467 {
468     int status;
469
470     switch(opt) {
471     case 'a':        /* autostop criteria */
472         if (set_autostop_criterion(capture_opts, optarg_str_p) == FALSE) {
473             cmdarg_err("Invalid or unknown -a flag \"%s\"", optarg_str_p);
474             return 1;
475         }
476         break;
477 #ifdef HAVE_PCAP_REMOTE
478     case 'A':
479         if (get_auth_arguments(capture_opts, optarg_str_p) == FALSE) {
480             cmdarg_err("Invalid or unknown -A arg \"%s\"", optarg_str_p);
481             return 1;
482         }
483         break;
484 #endif
485     case 'b':        /* Ringbuffer option */
486         capture_opts->multi_files_on = TRUE;
487         if (get_ring_arguments(capture_opts, optarg_str_p) == FALSE) {
488             cmdarg_err("Invalid or unknown -b arg \"%s\"", optarg_str_p);
489             return 1;
490         }
491         break;
492 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
493     case 'B':        /* Buffer size */
494         capture_opts->buffer_size = get_positive_int(optarg_str_p, "buffer size");
495         if (capture_opts->ifaces->len > 0) {
496             interface_options options;
497
498             options = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
499             capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1);
500             options.buffer_size = get_positive_int(optarg_str_p, "buffer size");
501             g_array_append_val(capture_opts->ifaces, options);
502         } else {
503             capture_opts->default_options.buffer_size = get_positive_int(optarg_str_p, "buffer size");
504         }
505         break;
506 #endif
507     case 'c':        /* Capture n packets */
508         capture_opts->has_autostop_packets = TRUE;
509         capture_opts->autostop_packets = get_positive_int(optarg_str_p, "packet count");
510         break;
511     case 'f':        /* capture filter */
512         if ((!capture_opts->use_pcapng) && (capture_opts->has_cfilter)) {
513             cmdarg_err("More than one -f argument specified");
514             return 1;
515         }
516         capture_opts->has_cfilter = TRUE;
517         g_free(capture_opts->cfilter);
518         capture_opts->cfilter = g_strdup(optarg_str_p);
519         if (capture_opts->ifaces->len > 0) {
520             interface_options options;
521
522             options = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
523             capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1);
524             g_free(options.cfilter);
525             options.cfilter = g_strdup(capture_opts->cfilter);
526             g_array_append_val(capture_opts->ifaces, options);
527         } else {
528             g_free(capture_opts->default_options.cfilter);
529             capture_opts->default_options.cfilter = g_strdup(capture_opts->cfilter);
530         }
531         break;
532     case 'H':        /* Hide capture info dialog box */
533         capture_opts->show_info = FALSE;
534         break;
535     case 'i':        /* Use interface x */
536         status = capture_opts_add_iface_opt(capture_opts, optarg_str_p);
537         if (status != 0) {
538             return status;
539         }
540         break;
541 #ifdef HAVE_PCAP_CREATE
542     case 'I':        /* Capture in monitor mode */
543         capture_opts->monitor_mode = TRUE;
544         if (capture_opts->ifaces->len > 0) {
545             interface_options options;
546
547             options = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
548             capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1);
549             options.monitor_mode = TRUE;
550             g_array_append_val(capture_opts->ifaces, options);
551         } else {
552             capture_opts->default_options.monitor_mode = TRUE;
553         }
554         break;
555 #endif
556     case 'k':        /* Start capture immediately */
557         *start_capture = TRUE;
558         break;
559     /*case 'l':*/    /* Automatic scrolling in live capture mode */
560 #ifdef HAVE_PCAP_SETSAMPLING
561     case 'm':
562         if (get_sampling_arguments(capture_opts, optarg_str_p) == FALSE) {
563             cmdarg_err("Invalid or unknown -m arg \"%s\"", optarg_str_p);
564             return 1;
565         }
566         break;
567 #endif
568     case 'n':        /* Use pcapng format */
569         capture_opts->use_pcapng = TRUE;
570         break;
571     case 'p':        /* Don't capture in promiscuous mode */
572         capture_opts->promisc_mode = FALSE;
573         if (capture_opts->ifaces->len > 0) {
574             interface_options options;
575
576             options = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
577             capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1);
578             options.promisc_mode = FALSE;
579             g_array_append_val(capture_opts->ifaces, options);
580         } else {
581             capture_opts->default_options.promisc_mode = FALSE;
582         }
583         break;
584     case 'Q':        /* Quit after capture (just capture to file) */
585         capture_opts->quit_after_cap  = TRUE;
586         *start_capture   = TRUE;  /*** -Q implies -k !! ***/
587         break;
588 #ifdef HAVE_PCAP_REMOTE
589     case 'r':
590         capture_opts->nocap_rpcap = FALSE;
591         break;
592 #endif
593     case 's':        /* Set the snapshot (capture) length */
594         capture_opts->has_snaplen = TRUE;
595         capture_opts->snaplen = get_natural_int(optarg_str_p, "snapshot length");
596         /*
597          * Make a snapshot length of 0 equivalent to the maximum packet
598          * length, mirroring what tcpdump does.
599          */
600         if (capture_opts->snaplen == 0)
601             capture_opts->snaplen = WTAP_MAX_PACKET_SIZE;
602         if (capture_opts->ifaces->len > 0) {
603             interface_options options;
604
605             options = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
606             capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1);
607             options.snaplen = capture_opts->snaplen;
608             g_array_append_val(capture_opts->ifaces, options);
609         } else {
610             capture_opts->default_options.snaplen = capture_opts->snaplen;
611         }
612         break;
613     case 'S':        /* "Real-Time" mode: used for following file ala tail -f */
614         capture_opts->real_time_mode = TRUE;
615         break;
616 #ifdef HAVE_PCAP_REMOTE
617     case 'u':
618         capture_opts->datatx_udp = TRUE;
619         break;
620 #endif
621     case 'w':        /* Write to capture file x */
622         capture_opts->saving_to_file = TRUE;
623         g_free(capture_opts->save_file);
624 #if defined _WIN32 && GLIB_CHECK_VERSION(2,6,0)
625         /* since GLib 2.6, we need to convert filenames to utf8 for Win32 */
626         capture_opts->save_file = g_locale_to_utf8(optarg_str_p, -1, NULL, NULL, NULL);
627 #else
628         capture_opts->save_file = g_strdup(optarg_str_p);
629 #endif
630         status = capture_opts_output_to_pipe(capture_opts->save_file, &capture_opts->output_to_pipe);
631         return status;
632     case 'g':        /* enable group read access on the capture file(s) */
633         capture_opts->group_read_access = TRUE;
634         break;
635     case 'y':        /* Set the pcap data link type */
636         capture_opts->linktype = linktype_name_to_val(optarg_str_p);
637         if (capture_opts->linktype == -1) {
638             cmdarg_err("The specified data link type \"%s\" isn't valid",
639                        optarg_str_p);
640             return 1;
641         }
642         if (capture_opts->ifaces->len > 0) {
643             interface_options options;
644
645             options = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
646             capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1);
647             options.linktype = linktype_name_to_val(optarg_str_p);
648             g_array_append_val(capture_opts->ifaces, options);
649         } else {
650             capture_opts->default_options.linktype = linktype_name_to_val(optarg_str_p);
651         }
652         break;
653     default:
654         /* the caller is responsible to send us only the right opt's */
655         g_assert_not_reached();
656     }
657
658     return 0;
659 }
660
661 void
662 capture_opts_print_if_capabilities(if_capabilities_t *caps, char *name,
663                                    gboolean monitor_mode)
664 {
665     GList *lt_entry;
666     data_link_info_t *data_link_info;
667
668     if (caps->can_set_rfmon)
669         fprintf_stderr("Data link types of interface %s when %sin monitor mode (use option -y to set):\n",
670                        name, monitor_mode ? "" : "not ");
671     else
672         fprintf_stderr("Data link types of interface %s (use option -y to set):\n", name);
673     for (lt_entry = caps->data_link_types; lt_entry != NULL;
674          lt_entry = g_list_next(lt_entry)) {
675         data_link_info = (data_link_info_t *)lt_entry->data;
676         fprintf_stderr("  %s", data_link_info->name);
677         if (data_link_info->description != NULL)
678             fprintf_stderr(" (%s)", data_link_info->description);
679         else
680             fprintf_stderr(" (not supported)");
681         fprintf_stderr("\n");
682     }
683 }
684
685 /* Print an ASCII-formatted list of interfaces. */
686 void
687 capture_opts_print_interfaces(GList *if_list)
688 {
689     int         i;
690     GList       *if_entry;
691     if_info_t   *if_info;
692
693     i = 1;  /* Interface id number */
694     for (if_entry = g_list_first(if_list); if_entry != NULL;
695          if_entry = g_list_next(if_entry)) {
696         if_info = (if_info_t *)if_entry->data;
697         fprintf_stderr("%d. %s", i++, if_info->name);
698
699         /* Print the description if it exists */
700         if (if_info->description != NULL)
701             fprintf_stderr(" (%s)", if_info->description);
702         fprintf_stderr("\n");
703     }
704 }
705
706
707 void capture_opts_trim_snaplen(capture_options *capture_opts, int snaplen_min)
708 {
709     guint i;
710     interface_options options;
711
712     if (capture_opts->snaplen < 1)
713         capture_opts->snaplen = WTAP_MAX_PACKET_SIZE;
714     else if (capture_opts->snaplen < snaplen_min)
715         capture_opts->snaplen = snaplen_min;
716
717     for (i = 0; i < capture_opts->ifaces->len; i++) {
718         options = g_array_index(capture_opts->ifaces, interface_options, 0);
719         capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, 0);
720         if (options.snaplen < 1)
721             options.snaplen = WTAP_MAX_PACKET_SIZE;
722         else if (options.snaplen < snaplen_min)
723             options.snaplen = snaplen_min;
724         g_array_append_val(capture_opts->ifaces, options);
725     }
726 }
727
728
729 void capture_opts_trim_ring_num_files(capture_options *capture_opts)
730 {
731     /* Check the value range of the ring_num_files parameter */
732     if (capture_opts->ring_num_files > RINGBUFFER_MAX_NUM_FILES) {
733         cmdarg_err("Too many ring buffer files (%u). Reducing to %u.\n", capture_opts->ring_num_files, RINGBUFFER_MAX_NUM_FILES);
734         capture_opts->ring_num_files = RINGBUFFER_MAX_NUM_FILES;
735     } else if (capture_opts->ring_num_files > RINGBUFFER_WARN_NUM_FILES) {
736         cmdarg_err("%u is a lot of ring buffer files.\n", capture_opts->ring_num_files);
737     }
738 #if RINGBUFFER_MIN_NUM_FILES > 0
739     else if (capture_opts->ring_num_files < RINGBUFFER_MIN_NUM_FILES)
740         cmdarg_err("Too few ring buffer files (%u). Increasing to %u.\n", capture_opts->ring_num_files, RINGBUFFER_MIN_NUM_FILES);
741         capture_opts->ring_num_files = RINGBUFFER_MIN_NUM_FILES;
742 #endif
743 }
744
745
746 gboolean capture_opts_trim_iface(capture_options *capture_opts, const char *capture_device)
747 {
748     GList       *if_list;
749     if_info_t   *if_info;
750     int         err;
751     gchar       *err_str;
752     interface_options options;
753
754
755     /* Did the user specify an interface to use? */
756     if (capture_opts->ifaces->len == 0) {
757         /* No - is a default specified in the preferences file? */
758         if (capture_device != NULL) {
759             /* Yes - use it. */
760             capture_opts->iface = g_strdup(capture_device);
761             options.name = g_strdup(capture_device);
762             /*  We don't set iface_descr here because doing so requires
763              *  capture_ui_utils.c which requires epan/prefs.c which is
764              *  probably a bit too much dependency for here...
765              */
766         } else {
767             /* No - pick the first one from the list of interfaces. */
768             if_list = capture_interface_list(&err, &err_str);
769             if (if_list == NULL) {
770                 switch (err) {
771
772                 case CANT_GET_INTERFACE_LIST:
773                     cmdarg_err("%s", err_str);
774                     g_free(err_str);
775                     break;
776
777                 case NO_INTERFACES_FOUND:
778                     cmdarg_err("There are no interfaces on which a capture can be done");
779                     break;
780                 }
781                 return FALSE;
782             }
783             if_info = (if_info_t *)if_list->data;       /* first interface */
784             capture_opts->iface = g_strdup(if_info->name);
785             options.name = g_strdup(if_info->name);
786             /*  We don't set iface_descr here because doing so requires
787              *  capture_ui_utils.c which requires epan/prefs.c which is
788              *  probably a bit too much dependency for here...
789              */
790             free_interface_list(if_list);
791         }
792         options.cfilter = g_strdup(capture_opts->default_options.cfilter);
793         options.snaplen = capture_opts->default_options.snaplen;
794         options.linktype = capture_opts->default_options.linktype;
795         options.promisc_mode = capture_opts->default_options.promisc_mode;
796 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
797         options.buffer_size = capture_opts->default_options.buffer_size;
798 #endif
799         options.monitor_mode = capture_opts->default_options.monitor_mode;
800         g_array_append_val(capture_opts->ifaces, options);
801     }
802
803     return TRUE;
804 }
805
806
807
808 #ifndef S_IFIFO
809 #define S_IFIFO _S_IFIFO
810 #endif
811 #ifndef S_ISFIFO
812 #define S_ISFIFO(mode)  (((mode) & S_IFMT) == S_IFIFO)
813 #endif
814
815 /* copied from filesystem.c */
816 static int capture_opts_test_for_fifo(const char *path)
817 {
818   ws_statb64 statb;
819
820   if (ws_stat64(path, &statb) < 0)
821     return errno;
822
823   if (S_ISFIFO(statb.st_mode))
824     return ESPIPE;
825   else
826     return 0;
827 }
828
829 static gboolean capture_opts_output_to_pipe(const char *save_file, gboolean *is_pipe)
830 {
831   int err;
832
833   *is_pipe = FALSE;
834
835   if (save_file != NULL) {
836     /* We're writing to a capture file. */
837     if (strcmp(save_file, "-") == 0) {
838       /* Writing to stdout. */
839       /* XXX - should we check whether it's a pipe?  It's arguably
840          silly to do "-w - >output_file" rather than "-w output_file",
841          but by not checking we might be violating the Principle Of
842          Least Astonishment. */
843       *is_pipe = TRUE;
844     } else {
845       /* not writing to stdout, test for a FIFO (aka named pipe) */
846       err = capture_opts_test_for_fifo(save_file);
847       switch (err) {
848
849       case ENOENT:      /* it doesn't exist, so we'll be creating it,
850                            and it won't be a FIFO */
851       case 0:           /* found it, but it's not a FIFO */
852         break;
853
854       case ESPIPE:      /* it is a FIFO */
855         *is_pipe = TRUE;
856         break;
857
858       default:          /* couldn't stat it              */
859         break;          /* ignore: later attempt to open */
860                         /*  will generate a nice msg     */
861       }
862     }
863   }
864
865   return 0;
866 }
867
868 #endif /* HAVE_LIBPCAP */