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