From Ivan Lawrow: Added IEEE 802.15.4-2003 AES-CCM security modes
[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                 cmdarg_err("%s", err_str);
475                 g_free(err_str);
476                 break;
477
478             case NO_INTERFACES_FOUND:
479                 cmdarg_err("There are no interfaces on which a capture can be done");
480                 break;
481             }
482             return 2;
483         }
484         if_info = (if_info_t *)g_list_nth_data(if_list, adapter_index - 1);
485         if (if_info == NULL) {
486             cmdarg_err("There is no interface with that adapter index");
487             return 1;
488         }
489         interface_opts.name = g_strdup(if_info->name);
490         /*  We don't set iface_descr here because doing so requires
491          *  capture_ui_utils.c which requires epan/prefs.c which is
492          *  probably a bit too much dependency for here...
493          */
494         free_interface_list(if_list);
495     } else {
496         interface_opts.name = g_strdup(optarg_str_p);
497     }
498     interface_opts.descr = g_strdup(capture_opts->default_options.descr);
499     interface_opts.cfilter = g_strdup(capture_opts->default_options.cfilter);
500     interface_opts.snaplen = capture_opts->default_options.snaplen;
501     interface_opts.has_snaplen = capture_opts->default_options.has_snaplen;
502     interface_opts.linktype = capture_opts->default_options.linktype;
503     interface_opts.promisc_mode = capture_opts->default_options.promisc_mode;
504 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
505     interface_opts.buffer_size = capture_opts->default_options.buffer_size;
506 #endif
507     interface_opts.monitor_mode = capture_opts->default_options.monitor_mode;
508 #ifdef HAVE_PCAP_REMOTE
509     interface_opts.src_type = capture_opts->default_options.src_type;
510     interface_opts.remote_host = g_strdup(capture_opts->default_options.remote_host);
511     interface_opts.remote_port = g_strdup(capture_opts->default_options.remote_port);
512     interface_opts.auth_type = capture_opts->default_options.auth_type;
513     interface_opts.auth_username = g_strdup(capture_opts->default_options.auth_username);
514     interface_opts.auth_password = g_strdup(capture_opts->default_options.auth_password);
515     interface_opts.datatx_udp = capture_opts->default_options.datatx_udp;
516     interface_opts.nocap_rpcap = capture_opts->default_options.nocap_rpcap;
517     interface_opts.nocap_local = capture_opts->default_options.nocap_local;
518 #endif
519 #ifdef HAVE_PCAP_SETSAMPLING
520     interface_opts.sampling_method = capture_opts->default_options.sampling_method;
521     interface_opts.sampling_param  = capture_opts->default_options.sampling_param;
522 #endif
523
524     g_array_append_val(capture_opts->ifaces, interface_opts);
525
526     return 0;
527 }
528
529 int
530 capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_str_p, gboolean *start_capture)
531 {
532     int status, snaplen;
533
534     switch(opt) {
535     case 'a':        /* autostop criteria */
536         if (set_autostop_criterion(capture_opts, optarg_str_p) == FALSE) {
537             cmdarg_err("Invalid or unknown -a flag \"%s\"", optarg_str_p);
538             return 1;
539         }
540         break;
541 #ifdef HAVE_PCAP_REMOTE
542     case 'A':
543         if (get_auth_arguments(capture_opts, optarg_str_p) == FALSE) {
544             cmdarg_err("Invalid or unknown -A arg \"%s\"", optarg_str_p);
545             return 1;
546         }
547         break;
548 #endif
549     case 'b':        /* Ringbuffer option */
550         capture_opts->multi_files_on = TRUE;
551         if (get_ring_arguments(capture_opts, optarg_str_p) == FALSE) {
552             cmdarg_err("Invalid or unknown -b arg \"%s\"", optarg_str_p);
553             return 1;
554         }
555         break;
556 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
557     case 'B':        /* Buffer size */
558         if (capture_opts->ifaces->len > 0) {
559             interface_options interface_opts;
560
561             interface_opts = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
562             capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1);
563             interface_opts.buffer_size = get_positive_int(optarg_str_p, "buffer size");
564             g_array_append_val(capture_opts->ifaces, interface_opts);
565         } else {
566             capture_opts->default_options.buffer_size = get_positive_int(optarg_str_p, "buffer size");
567         }
568         break;
569 #endif
570     case 'c':        /* Capture n packets */
571         capture_opts->has_autostop_packets = TRUE;
572         capture_opts->autostop_packets = get_positive_int(optarg_str_p, "packet count");
573         break;
574     case 'f':        /* capture filter */
575         if (capture_opts->ifaces->len > 0) {
576             interface_options interface_opts;
577
578             interface_opts = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
579             capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1);
580             g_free(interface_opts.cfilter);
581             interface_opts.cfilter = g_strdup(optarg_str_p);
582             g_array_append_val(capture_opts->ifaces, interface_opts);
583         } else {
584             g_free(capture_opts->default_options.cfilter);
585             capture_opts->default_options.cfilter = g_strdup(optarg_str_p);
586         }
587         break;
588     case 'H':        /* Hide capture info dialog box */
589         capture_opts->show_info = FALSE;
590         break;
591     case 'i':        /* Use interface x */
592         status = capture_opts_add_iface_opt(capture_opts, optarg_str_p);
593         if (status != 0) {
594             return status;
595         }
596         break;
597 #ifdef HAVE_PCAP_CREATE
598     case 'I':        /* Capture in monitor mode */
599         if (capture_opts->ifaces->len > 0) {
600             interface_options interface_opts;
601
602             interface_opts = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
603             capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1);
604             interface_opts.monitor_mode = TRUE;
605             g_array_append_val(capture_opts->ifaces, interface_opts);
606         } else {
607             capture_opts->default_options.monitor_mode = TRUE;
608         }
609         break;
610 #endif
611     case 'k':        /* Start capture immediately */
612         *start_capture = TRUE;
613         break;
614     /*case 'l':*/    /* Automatic scrolling in live capture mode */
615 #ifdef HAVE_PCAP_SETSAMPLING
616     case 'm':
617         if (get_sampling_arguments(capture_opts, optarg_str_p) == FALSE) {
618             cmdarg_err("Invalid or unknown -m arg \"%s\"", optarg_str_p);
619             return 1;
620         }
621         break;
622 #endif
623     case 'n':        /* Use pcapng format */
624         capture_opts->use_pcapng = TRUE;
625         break;
626     case 'p':        /* Don't capture in promiscuous mode */
627         if (capture_opts->ifaces->len > 0) {
628             interface_options interface_opts;
629
630             interface_opts = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
631             capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1);
632             interface_opts.promisc_mode = FALSE;
633             g_array_append_val(capture_opts->ifaces, interface_opts);
634         } else {
635             capture_opts->default_options.promisc_mode = FALSE;
636         }
637         break;
638     case 'P':        /* Use pcap format */
639         capture_opts->use_pcapng = FALSE;
640         break;
641 #ifdef HAVE_PCAP_REMOTE
642     case 'r':
643         if (capture_opts->ifaces->len > 0) {
644             interface_options interface_opts;
645
646             interface_opts = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
647             capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1);
648             interface_opts.nocap_rpcap = FALSE;
649             g_array_append_val(capture_opts->ifaces, interface_opts);
650         } else {
651             capture_opts->default_options.nocap_rpcap = FALSE;
652         }
653         break;
654 #endif
655     case 's':        /* Set the snapshot (capture) length */
656         snaplen = get_natural_int(optarg_str_p, "snapshot length");
657         /*
658          * Make a snapshot length of 0 equivalent to the maximum packet
659          * length, mirroring what tcpdump does.
660          */
661         if (snaplen == 0)
662             snaplen = WTAP_MAX_PACKET_SIZE;
663         if (capture_opts->ifaces->len > 0) {
664             interface_options interface_opts;
665
666             interface_opts = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
667             capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1);
668             interface_opts.has_snaplen = TRUE;
669             interface_opts.snaplen = snaplen;
670             g_array_append_val(capture_opts->ifaces, interface_opts);
671         } else {
672             capture_opts->default_options.snaplen = snaplen;
673             capture_opts->default_options.has_snaplen = TRUE;
674         }
675         break;
676     case 'S':        /* "Real-Time" mode: used for following file ala tail -f */
677         capture_opts->real_time_mode = TRUE;
678         break;
679 #ifdef HAVE_PCAP_REMOTE
680     case 'u':
681         if (capture_opts->ifaces->len > 0) {
682             interface_options interface_opts;
683
684             interface_opts = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
685             capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1);
686             interface_opts.datatx_udp = TRUE;
687             g_array_append_val(capture_opts->ifaces, interface_opts);
688         } else {
689             capture_opts->default_options.datatx_udp = TRUE;
690         }
691         break;
692 #endif
693     case 'w':        /* Write to capture file x */
694         capture_opts->saving_to_file = TRUE;
695         g_free(capture_opts->save_file);
696         capture_opts->save_file = g_strdup(optarg_str_p);
697         status = capture_opts_output_to_pipe(capture_opts->save_file, &capture_opts->output_to_pipe);
698         return status;
699     case 'g':        /* enable group read access on the capture file(s) */
700         capture_opts->group_read_access = TRUE;
701         break;
702     case 'y':        /* Set the pcap data link type */
703         if (capture_opts->ifaces->len > 0) {
704             interface_options interface_opts;
705
706             interface_opts = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1);
707             capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1);
708             interface_opts.linktype = linktype_name_to_val(optarg_str_p);
709             if (interface_opts.linktype == -1) {
710                 cmdarg_err("The specified data link type \"%s\" isn't valid",
711                            optarg_str_p);
712                 return 1;
713             }
714             g_array_append_val(capture_opts->ifaces, interface_opts);
715         } else {
716             capture_opts->default_options.linktype = linktype_name_to_val(optarg_str_p);
717             if (capture_opts->default_options.linktype == -1) {
718                 cmdarg_err("The specified data link type \"%s\" isn't valid",
719                            optarg_str_p);
720                 return 1;
721             }
722         }
723         break;
724     default:
725         /* the caller is responsible to send us only the right opt's */
726         g_assert_not_reached();
727     }
728
729     return 0;
730 }
731
732 void
733 capture_opts_print_if_capabilities(if_capabilities_t *caps, char *name,
734                                    gboolean monitor_mode)
735 {
736     GList *lt_entry;
737     data_link_info_t *data_link_info;
738
739     if (caps->can_set_rfmon)
740         fprintf_stderr("Data link types of interface %s when %sin monitor mode (use option -y to set):\n",
741                        name, monitor_mode ? "" : "not ");
742     else
743         fprintf_stderr("Data link types of interface %s (use option -y to set):\n", name);
744     for (lt_entry = caps->data_link_types; lt_entry != NULL;
745          lt_entry = g_list_next(lt_entry)) {
746         data_link_info = (data_link_info_t *)lt_entry->data;
747         fprintf_stderr("  %s", data_link_info->name);
748         if (data_link_info->description != NULL)
749             fprintf_stderr(" (%s)", data_link_info->description);
750         else
751             fprintf_stderr(" (not supported)");
752         fprintf_stderr("\n");
753     }
754 }
755
756 /* Print an ASCII-formatted list of interfaces. */
757 void
758 capture_opts_print_interfaces(GList *if_list)
759 {
760     int         i;
761     GList       *if_entry;
762     if_info_t   *if_info;
763
764     i = 1;  /* Interface id number */
765     for (if_entry = g_list_first(if_list); if_entry != NULL;
766          if_entry = g_list_next(if_entry)) {
767         if_info = (if_info_t *)if_entry->data;
768         fprintf_stderr("%d. %s", i++, if_info->name);
769
770         /* Print the description if it exists */
771         if (if_info->description != NULL)
772             fprintf_stderr(" (%s)", if_info->description);
773         fprintf_stderr("\n");
774     }
775 }
776
777
778 void capture_opts_trim_snaplen(capture_options *capture_opts, int snaplen_min)
779 {
780     guint i;
781     interface_options interface_opts;
782
783     if (capture_opts->ifaces->len > 0) {
784         for (i = 0; i < capture_opts->ifaces->len; i++) {
785             interface_opts = g_array_index(capture_opts->ifaces, interface_options, 0);
786             capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, 0);
787             if (interface_opts.snaplen < 1)
788                 interface_opts.snaplen = WTAP_MAX_PACKET_SIZE;
789             else if (interface_opts.snaplen < snaplen_min)
790                 interface_opts.snaplen = snaplen_min;
791             g_array_append_val(capture_opts->ifaces, interface_opts);
792         }
793     } else {
794         if (capture_opts->default_options.snaplen < 1)
795             capture_opts->default_options.snaplen = WTAP_MAX_PACKET_SIZE;
796         else if (capture_opts->default_options.snaplen < snaplen_min)
797             capture_opts->default_options.snaplen = snaplen_min;
798     }
799 }
800
801
802 void capture_opts_trim_ring_num_files(capture_options *capture_opts)
803 {
804     /* Check the value range of the ring_num_files parameter */
805     if (capture_opts->ring_num_files > RINGBUFFER_MAX_NUM_FILES) {
806         cmdarg_err("Too many ring buffer files (%u). Reducing to %u.\n", capture_opts->ring_num_files, RINGBUFFER_MAX_NUM_FILES);
807         capture_opts->ring_num_files = RINGBUFFER_MAX_NUM_FILES;
808     } else if (capture_opts->ring_num_files > RINGBUFFER_WARN_NUM_FILES) {
809         cmdarg_err("%u is a lot of ring buffer files.\n", capture_opts->ring_num_files);
810     }
811 #if RINGBUFFER_MIN_NUM_FILES > 0
812     else if (capture_opts->ring_num_files < RINGBUFFER_MIN_NUM_FILES)
813         cmdarg_err("Too few ring buffer files (%u). Increasing to %u.\n", capture_opts->ring_num_files, RINGBUFFER_MIN_NUM_FILES);
814         capture_opts->ring_num_files = RINGBUFFER_MIN_NUM_FILES;
815 #endif
816 }
817
818
819 gboolean capture_opts_trim_iface(capture_options *capture_opts, const char *capture_device)
820 {
821     GList       *if_list;
822     if_info_t   *if_info;
823     int         err;
824     gchar       *err_str;
825     interface_options interface_opts;
826
827
828     /* Did the user specify an interface to use? */
829     if (capture_opts->ifaces->len == 0) {
830         /* No - is a default specified in the preferences file? */
831         if (capture_device != NULL) {
832             /* Yes - use it. */
833             interface_opts.name = g_strdup(capture_device);
834             /*  We don't set iface_descr here because doing so requires
835              *  capture_ui_utils.c which requires epan/prefs.c which is
836              *  probably a bit too much dependency for here...
837              */
838         } else {
839             /* No - pick the first one from the list of interfaces. */
840             if_list = capture_interface_list(&err, &err_str);
841             if (if_list == NULL) {
842                 switch (err) {
843
844                 case CANT_GET_INTERFACE_LIST:
845                     cmdarg_err("%s", err_str);
846                     g_free(err_str);
847                     break;
848
849                 case NO_INTERFACES_FOUND:
850                     cmdarg_err("There are no interfaces on which a capture can be done");
851                     break;
852                 }
853                 return FALSE;
854             }
855             if_info = (if_info_t *)if_list->data;       /* first interface */
856             interface_opts.name = g_strdup(if_info->name);
857             /*  We don't set iface_descr here because doing so requires
858              *  capture_ui_utils.c which requires epan/prefs.c which is
859              *  probably a bit too much dependency for here...
860              */
861             free_interface_list(if_list);
862         }
863         if (capture_opts->default_options.descr) {
864             interface_opts.descr = g_strdup(capture_opts->default_options.descr);
865         } else {
866             interface_opts.descr = NULL;
867         }
868         interface_opts.cfilter = g_strdup(capture_opts->default_options.cfilter);
869         interface_opts.snaplen = capture_opts->default_options.snaplen;
870         interface_opts.has_snaplen = capture_opts->default_options.has_snaplen;
871         interface_opts.linktype = capture_opts->default_options.linktype;
872         interface_opts.promisc_mode = capture_opts->default_options.promisc_mode;
873 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
874         interface_opts.buffer_size = capture_opts->default_options.buffer_size;
875 #endif
876         interface_opts.monitor_mode = capture_opts->default_options.monitor_mode;
877 #ifdef HAVE_PCAP_REMOTE
878         interface_opts.src_type = capture_opts->default_options.src_type;
879         interface_opts.remote_host = g_strdup(capture_opts->default_options.remote_host);
880         interface_opts.remote_port = g_strdup(capture_opts->default_options.remote_port);
881         interface_opts.auth_type = capture_opts->default_options.auth_type;
882         interface_opts.auth_username = g_strdup(capture_opts->default_options.auth_username);
883         interface_opts.auth_password = g_strdup(capture_opts->default_options.auth_password);
884         interface_opts.datatx_udp = capture_opts->default_options.datatx_udp;
885         interface_opts.nocap_rpcap = capture_opts->default_options.nocap_rpcap;
886         interface_opts.nocap_local = capture_opts->default_options.nocap_local;
887 #endif
888 #ifdef HAVE_PCAP_SETSAMPLING
889         interface_opts.sampling_method = capture_opts->default_options.sampling_method;
890         interface_opts.sampling_param  = capture_opts->default_options.sampling_param;
891 #endif
892         g_array_append_val(capture_opts->ifaces, interface_opts);
893     }
894
895     return TRUE;
896 }
897
898
899
900 #ifndef S_IFIFO
901 #define S_IFIFO _S_IFIFO
902 #endif
903 #ifndef S_ISFIFO
904 #define S_ISFIFO(mode)  (((mode) & S_IFMT) == S_IFIFO)
905 #endif
906
907 /* copied from filesystem.c */
908 static int capture_opts_test_for_fifo(const char *path)
909 {
910   ws_statb64 statb;
911
912   if (ws_stat64(path, &statb) < 0)
913     return errno;
914
915   if (S_ISFIFO(statb.st_mode))
916     return ESPIPE;
917   else
918     return 0;
919 }
920
921 static gboolean capture_opts_output_to_pipe(const char *save_file, gboolean *is_pipe)
922 {
923   int err;
924
925   *is_pipe = FALSE;
926
927   if (save_file != NULL) {
928     /* We're writing to a capture file. */
929     if (strcmp(save_file, "-") == 0) {
930       /* Writing to stdout. */
931       /* XXX - should we check whether it's a pipe?  It's arguably
932          silly to do "-w - >output_file" rather than "-w output_file",
933          but by not checking we might be violating the Principle Of
934          Least Astonishment. */
935       *is_pipe = TRUE;
936     } else {
937       /* not writing to stdout, test for a FIFO (aka named pipe) */
938       err = capture_opts_test_for_fifo(save_file);
939       switch (err) {
940
941       case ENOENT:      /* it doesn't exist, so we'll be creating it,
942                            and it won't be a FIFO */
943       case 0:           /* found it, but it's not a FIFO */
944         break;
945
946       case ESPIPE:      /* it is a FIFO */
947         *is_pipe = TRUE;
948         break;
949
950       default:          /* couldn't stat it              */
951         break;          /* ignore: later attempt to open */
952                         /*  will generate a nice msg     */
953       }
954     }
955   }
956
957   return 0;
958 }
959
960 #endif /* HAVE_LIBPCAP */