nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* commandline.c |
2 | * Common command line handling between GUIs |
||
3 | * |
||
4 | * Wireshark - Network traffic analyzer |
||
5 | * By Gerald Combs <gerald@wireshark.org> |
||
6 | * Copyright 1998 Gerald Combs |
||
7 | * |
||
8 | * This program is free software; you can redistribute it and/or |
||
9 | * modify it under the terms of the GNU General Public License |
||
10 | * as published by the Free Software Foundation; either version 2 |
||
11 | * of the License, or (at your option) any later version. |
||
12 | * |
||
13 | * This program is distributed in the hope that it will be useful, |
||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
16 | * GNU General Public License for more details. |
||
17 | * |
||
18 | * You should have received a copy of the GNU General Public License |
||
19 | * along with this program; if not, write to the Free Software |
||
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
||
21 | */ |
||
22 | |||
23 | #include "config.h" |
||
24 | |||
25 | #include <glib.h> |
||
26 | |||
27 | #include <string.h> |
||
28 | #include <stdio.h> |
||
29 | #include <stdlib.h> |
||
30 | |||
31 | #ifdef HAVE_GETOPT_H |
||
32 | #include <getopt.h> |
||
33 | #endif |
||
34 | |||
35 | #ifndef HAVE_GETOPT_LONG |
||
36 | #include "wsutil/wsgetopt.h" |
||
37 | #endif |
||
38 | |||
39 | #include <ws_version_info.h> |
||
40 | |||
41 | #include <wsutil/clopts_common.h> |
||
42 | #include <wsutil/cmdarg_err.h> |
||
43 | #include <wsutil/filesystem.h> |
||
44 | |||
45 | #include <epan/ex-opt.h> |
||
46 | #include <epan/addr_resolv.h> |
||
47 | #include <epan/packet.h> |
||
48 | #include <epan/proto.h> |
||
49 | #include <epan/prefs.h> |
||
50 | #include <epan/prefs-int.h> |
||
51 | #include <epan/timestamp.h> |
||
52 | #include <epan/stat_tap_ui.h> |
||
53 | |||
54 | #include "capture_opts.h" |
||
55 | #include "persfilepath_opt.h" |
||
56 | #include "preference_utils.h" |
||
57 | #include "console.h" |
||
58 | #include "recent.h" |
||
59 | #include "decode_as_utils.h" |
||
60 | |||
61 | #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS) |
||
62 | #include <epan/asn1.h> |
||
63 | #include <epan/dissectors/packet-kerberos.h> |
||
64 | #endif |
||
65 | |||
66 | #include "../file.h" |
||
67 | |||
68 | #include "ui/commandline.h" |
||
69 | |||
70 | commandline_param_info_t global_commandline_info; |
||
71 | |||
72 | #if defined(HAVE_LIBPCAP) || defined(HAVE_EXTCAP) |
||
73 | capture_options global_capture_opts; |
||
74 | #endif |
||
75 | |||
76 | void |
||
77 | commandline_print_usage(gboolean for_help_option) { |
||
78 | FILE *output; |
||
79 | |||
80 | #ifdef _WIN32 |
||
81 | create_console(); |
||
82 | #endif |
||
83 | |||
84 | if (for_help_option) { |
||
85 | output = stdout; |
||
86 | fprintf(output, "Wireshark %s\n" |
||
87 | "Interactively dump and analyze network traffic.\n" |
||
88 | "See https://www.wireshark.org for more information.\n", |
||
89 | get_ws_vcs_version_info()); |
||
90 | } else { |
||
91 | output = stderr; |
||
92 | } |
||
93 | fprintf(output, "\n"); |
||
94 | fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n"); |
||
95 | fprintf(output, "\n"); |
||
96 | |||
97 | #ifdef HAVE_LIBPCAP |
||
98 | fprintf(output, "Capture interface:\n"); |
||
99 | fprintf(output, " -i <interface> name or idx of interface (def: first non-loopback)\n"); |
||
100 | fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n"); |
||
101 | fprintf(output, " -s <snaplen> packet snapshot length (def: 65535)\n"); |
||
102 | fprintf(output, " -p don't capture in promiscuous mode\n"); |
||
103 | fprintf(output, " -k start capturing immediately (def: do nothing)\n"); |
||
104 | fprintf(output, " -S update packet display when new packets are captured\n"); |
||
105 | fprintf(output, " -l turn on automatic scrolling while -S is in use\n"); |
||
106 | #ifdef HAVE_PCAP_CREATE |
||
107 | fprintf(output, " -I capture in monitor mode, if available\n"); |
||
108 | #endif |
||
109 | #ifdef CAN_SET_CAPTURE_BUFFER_SIZE |
||
110 | fprintf(output, " -B <buffer size> size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE); |
||
111 | #endif |
||
112 | fprintf(output, " -y <link type> link layer type (def: first appropriate)\n"); |
||
113 | fprintf(output, " -D print list of interfaces and exit\n"); |
||
114 | fprintf(output, " -L print list of link-layer types of iface and exit\n"); |
||
115 | fprintf(output, "\n"); |
||
116 | fprintf(output, "Capture stop conditions:\n"); |
||
117 | fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n"); |
||
118 | fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n"); |
||
119 | fprintf(output, " filesize:NUM - stop this file after NUM KB\n"); |
||
120 | fprintf(output, " files:NUM - stop after NUM files\n"); |
||
121 | /*fprintf(output, "\n");*/ |
||
122 | fprintf(output, "Capture output:\n"); |
||
123 | fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n"); |
||
124 | fprintf(output, " filesize:NUM - switch to next file after NUM KB\n"); |
||
125 | fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n"); |
||
126 | #endif /* HAVE_LIBPCAP */ |
||
127 | #ifdef HAVE_PCAP_REMOTE |
||
128 | fprintf(output, "RPCAP options:\n"); |
||
129 | fprintf(output, " -A <user>:<password> use RPCAP password authentication\n"); |
||
130 | #endif |
||
131 | /*fprintf(output, "\n");*/ |
||
132 | fprintf(output, "Input file:\n"); |
||
133 | fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n"); |
||
134 | |||
135 | fprintf(output, "\n"); |
||
136 | fprintf(output, "Processing:\n"); |
||
137 | fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n"); |
||
138 | fprintf(output, " -n disable all name resolutions (def: all enabled)\n"); |
||
139 | fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mnNtd\"\n"); |
||
140 | fprintf(output, " -d %s ...\n", DECODE_AS_ARG_TEMPLATE); |
||
141 | fprintf(output, " \"Decode As\", see the man page for details\n"); |
||
142 | fprintf(output, " Example: tcp.port==8888,http\n"); |
||
143 | fprintf(output, " --disable-protocol <proto_name>\n"); |
||
144 | fprintf(output, " disable dissection of proto_name\n"); |
||
145 | fprintf(output, " --enable-heuristic <short_name>\n"); |
||
146 | fprintf(output, " enable dissection of heuristic protocol\n"); |
||
147 | fprintf(output, " --disable-heuristic <short_name>\n"); |
||
148 | fprintf(output, " disable dissection of heuristic protocol\n"); |
||
149 | |||
150 | fprintf(output, "\n"); |
||
151 | fprintf(output, "User interface:\n"); |
||
152 | fprintf(output, " -C <config profile> start with specified configuration profile\n"); |
||
153 | fprintf(output, " -Y <display filter> start with the given display filter\n"); |
||
154 | fprintf(output, " -g <packet number> go to specified packet number after \"-r\"\n"); |
||
155 | fprintf(output, " -J <jump filter> jump to the first packet matching the (display)\n"); |
||
156 | fprintf(output, " filter\n"); |
||
157 | fprintf(output, " -j search backwards for a matching packet after \"-J\"\n"); |
||
158 | fprintf(output, " -m <font> set the font name used for most text\n"); |
||
159 | fprintf(output, " -t a|ad|d|dd|e|r|u|ud output format of time stamps (def: r: rel. to first)\n"); |
||
160 | fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n"); |
||
161 | fprintf(output, " -X <key>:<value> eXtension options, see man page for details\n"); |
||
162 | fprintf(output, " -z <statistics> show various statistics, see man page for details\n"); |
||
163 | |||
164 | fprintf(output, "\n"); |
||
165 | fprintf(output, "Output:\n"); |
||
166 | fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n"); |
||
167 | |||
168 | fprintf(output, "\n"); |
||
169 | fprintf(output, "Miscellaneous:\n"); |
||
170 | fprintf(output, " -h display this help and exit\n"); |
||
171 | fprintf(output, " -v display version info and exit\n"); |
||
172 | fprintf(output, " -P <key>:<path> persconf:path - personal configuration files\n"); |
||
173 | fprintf(output, " persdata:path - personal data files\n"); |
||
174 | fprintf(output, " -o <name>:<value> ... override preference or recent setting\n"); |
||
175 | fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n"); |
||
176 | #ifndef _WIN32 |
||
177 | fprintf(output, " --display=DISPLAY X display to use\n"); |
||
178 | #endif |
||
179 | |||
180 | #ifdef _WIN32 |
||
181 | destroy_console(); |
||
182 | #endif |
||
183 | } |
||
184 | |||
185 | #define OPTSTRING OPTSTRING_CAPTURE_COMMON "C:d:g:Hh" "jJ:kK:lm:nN:o:P:r:R:St:u:vw:X:Y:z:" |
||
186 | static const struct option long_options[] = { |
||
187 | {"help", no_argument, NULL, 'h'}, |
||
188 | {"read-file", required_argument, NULL, 'r' }, |
||
189 | {"read-filter", required_argument, NULL, 'R' }, |
||
190 | {"display-filter", required_argument, NULL, 'Y' }, |
||
191 | {"version", no_argument, NULL, 'v'}, |
||
192 | LONGOPT_CAPTURE_COMMON |
||
193 | {0, 0, 0, 0 } |
||
194 | }; |
||
195 | static const char optstring[] = OPTSTRING; |
||
196 | |||
197 | #ifndef HAVE_LIBPCAP |
||
198 | static void print_no_capture_support_error(void) |
||
199 | { |
||
200 | cmdarg_err("This version of Wireshark was not built with support for capturing packets."); |
||
201 | } |
||
202 | #endif |
||
203 | |||
204 | void commandline_early_options(int argc, char *argv[], |
||
205 | GString *comp_info_str, GString *runtime_info_str) |
||
206 | { |
||
207 | int opt; |
||
208 | #ifdef HAVE_LIBPCAP |
||
209 | int err; |
||
210 | GList *if_list; |
||
211 | gchar *err_str; |
||
212 | #else |
||
213 | gboolean capture_option_specified; |
||
214 | #endif |
||
215 | |||
216 | /* |
||
217 | * In order to have the -X opts assigned before the wslua machine starts |
||
218 | * we need to call getopt_long before epan_init() gets called. |
||
219 | * |
||
220 | * In addition, we process "console only" parameters (ones where we |
||
221 | * send output to the console and exit) here, so we don't start GUI |
||
222 | * if we're only showing command-line help or version information. |
||
223 | * |
||
224 | * XXX - this pre-scan is done before we start GUI, so we haven't |
||
225 | * run "GUI init function" on the arguments. That means that GUI-specific |
||
226 | * arguments have not been removed from the argument list; those arguments |
||
227 | * begin with "--", and will be treated as an error by getopt_long(). |
||
228 | * |
||
229 | * We thus ignore errors - *and* set "opterr" to 0 to suppress the |
||
230 | * error messages. |
||
231 | * |
||
232 | * XXX - should we, instead, first call gtk_parse_args(), without |
||
233 | * calling gtk_init(), and then call this? |
||
234 | * |
||
235 | * In order to handle, for example, -o options, we also need to call it |
||
236 | * *after* epan_init() gets called, so that the dissectors have had a |
||
237 | * chance to register their preferences, so we have another getopt_long() |
||
238 | * call later. |
||
239 | * |
||
240 | * XXX - can we do this all with one getopt_long() call, saving the |
||
241 | * arguments we can't handle until after initializing libwireshark, |
||
242 | * and then process them after initializing libwireshark? |
||
243 | * |
||
244 | * Note that we don't want to initialize libwireshark until after the |
||
245 | * GUI is up, as that can take a while, and we want a window of some |
||
246 | * sort up to show progress while that's happening. |
||
247 | */ |
||
248 | opterr = 0; |
||
249 | |||
250 | #ifndef HAVE_LIBPCAP |
||
251 | capture_option_specified = FALSE; |
||
252 | #endif |
||
253 | while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) { |
||
254 | switch (opt) { |
||
255 | case 'C': /* Configuration Profile */ |
||
256 | if (profile_exists (optarg, FALSE)) { |
||
257 | set_profile_name (optarg); |
||
258 | } else { |
||
259 | cmdarg_err("Configuration Profile \"%s\" does not exist", optarg); |
||
260 | exit(1); |
||
261 | } |
||
262 | break; |
||
263 | case 'D': /* Print a list of capture devices and exit */ |
||
264 | #ifdef HAVE_LIBPCAP |
||
265 | if_list = capture_interface_list(&err, &err_str, NULL); |
||
266 | if (if_list == NULL) { |
||
267 | if (err == 0) |
||
268 | cmdarg_err("There are no interfaces on which a capture can be done"); |
||
269 | else { |
||
270 | cmdarg_err("%s", err_str); |
||
271 | g_free(err_str); |
||
272 | } |
||
273 | exit(2); |
||
274 | } |
||
275 | #ifdef _WIN32 |
||
276 | create_console(); |
||
277 | #endif /* _WIN32 */ |
||
278 | capture_opts_print_interfaces(if_list); |
||
279 | free_interface_list(if_list); |
||
280 | #ifdef _WIN32 |
||
281 | destroy_console(); |
||
282 | #endif /* _WIN32 */ |
||
283 | exit(0); |
||
284 | #else /* HAVE_LIBPCAP */ |
||
285 | capture_option_specified = TRUE; |
||
286 | #endif /* HAVE_LIBPCAP */ |
||
287 | break; |
||
288 | case 'h': /* Print help and exit */ |
||
289 | commandline_print_usage(TRUE); |
||
290 | exit(0); |
||
291 | break; |
||
292 | #ifdef _WIN32 |
||
293 | case 'i': |
||
294 | if (strcmp(optarg, "-") == 0) |
||
295 | set_stdin_capture(TRUE); |
||
296 | break; |
||
297 | #endif |
||
298 | case 'P': /* Personal file directory path settings - change these before the Preferences and alike are processed */ |
||
299 | if (!persfilepath_opt(opt, optarg)) { |
||
300 | cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg); |
||
301 | exit(2); |
||
302 | } |
||
303 | break; |
||
304 | case 'v': /* Show version and exit */ |
||
305 | #ifdef _WIN32 |
||
306 | create_console(); |
||
307 | #endif |
||
308 | show_version("Wireshark", comp_info_str, runtime_info_str); |
||
309 | #ifdef _WIN32 |
||
310 | destroy_console(); |
||
311 | #endif |
||
312 | exit(0); |
||
313 | break; |
||
314 | case 'X': |
||
315 | /* |
||
316 | * Extension command line options have to be processed before |
||
317 | * we call epan_init() as they are supposed to be used by dissectors |
||
318 | * or taps very early in the registration process. |
||
319 | */ |
||
320 | ex_opt_add(optarg); |
||
321 | break; |
||
322 | case '?': /* Ignore errors - the "real" scan will catch them. */ |
||
323 | break; |
||
324 | } |
||
325 | } |
||
326 | |||
327 | #ifndef HAVE_LIBPCAP |
||
328 | if (capture_option_specified) { |
||
329 | print_no_capture_support_error(); |
||
330 | commandline_print_usage(FALSE); |
||
331 | exit(1); |
||
332 | } |
||
333 | #endif |
||
334 | } |
||
335 | |||
336 | void commandline_other_options(int argc, char *argv[], gboolean opt_reset) |
||
337 | { |
||
338 | int opt; |
||
339 | gboolean arg_error = FALSE; |
||
340 | #ifdef HAVE_LIBPCAP |
||
341 | int status; |
||
342 | #else |
||
343 | gboolean capture_option_specified; |
||
344 | #endif |
||
345 | char badopt; |
||
346 | |||
347 | /* |
||
348 | * To reset the options parser, set optreset to 1 on platforms that |
||
349 | * have optreset (documented in *BSD and OS X, apparently present but |
||
350 | * not documented in Solaris - the Illumos repository seems to |
||
351 | * suggest that the first Solaris getopt_long(), at least as of 2004, |
||
352 | * was based on the NetBSD one, it had optreset) and set optind to 1, |
||
353 | * and set optind to 0 otherwise (documented as working in the GNU |
||
354 | * getopt_long(). Setting optind to 0 didn't originally work in the |
||
355 | * NetBSD one, but that was added later - we don't want to depend on |
||
356 | * it if we have optreset). |
||
357 | * |
||
358 | * Also reset opterr to 1, so that error messages are printed by |
||
359 | * getopt_long(). |
||
360 | * |
||
361 | * XXX - if we want to control all the command-line option errors, so |
||
362 | * that we can display them where we choose (e.g., in a window), we'd |
||
363 | * want to leave opterr as 0, and produce our own messages using optopt. |
||
364 | * We'd have to check the value of optopt to see if it's a valid option |
||
365 | * letter, in which case *presumably* the error is "this option requires |
||
366 | * an argument but none was specified", or not a valid option letter, |
||
367 | * in which case *presumably* the error is "this option isn't valid". |
||
368 | * Some versions of getopt() let you supply a option string beginning |
||
369 | * with ':', which means that getopt() will return ':' rather than '?' |
||
370 | * for "this option requires an argument but none was specified", but |
||
371 | * not all do. But we're now using getopt_long() - what does it do? |
||
372 | */ |
||
373 | if (opt_reset) { |
||
374 | #ifdef HAVE_OPTRESET |
||
375 | optreset = 1; |
||
376 | optind = 1; |
||
377 | #else |
||
378 | optind = 0; |
||
379 | #endif |
||
380 | opterr = 1; |
||
381 | } |
||
382 | |||
383 | /* Initialize with default values */ |
||
384 | global_commandline_info.jump_backwards = SD_FORWARD; |
||
385 | global_commandline_info.go_to_packet = 0; |
||
386 | global_commandline_info.jfilter = NULL; |
||
387 | global_commandline_info.cf_name = NULL; |
||
388 | global_commandline_info.rfilter = NULL; |
||
389 | global_commandline_info.dfilter = NULL; |
||
390 | global_commandline_info.time_format = TS_NOT_SET; |
||
391 | #ifdef HAVE_LIBPCAP |
||
392 | global_commandline_info.start_capture = FALSE; |
||
393 | global_commandline_info.list_link_layer_types = FALSE; |
||
394 | global_commandline_info.quit_after_cap = getenv("WIRESHARK_QUIT_AFTER_CAPTURE") ? TRUE : FALSE; |
||
395 | #endif |
||
396 | global_commandline_info.disable_protocol_slist = NULL; |
||
397 | global_commandline_info.enable_heur_slist = NULL; |
||
398 | global_commandline_info.disable_heur_slist = NULL; |
||
399 | |||
400 | while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) { |
||
401 | switch (opt) { |
||
402 | /*** capture option specific ***/ |
||
403 | case 'a': /* autostop criteria */ |
||
404 | case 'b': /* Ringbuffer option */ |
||
405 | case 'c': /* Capture xxx packets */ |
||
406 | case 'f': /* capture filter */ |
||
407 | case 'k': /* Start capture immediately */ |
||
408 | case 'H': /* Hide capture info dialog box */ |
||
409 | case 'p': /* Don't capture in promiscuous mode */ |
||
410 | case 'i': /* Use interface x */ |
||
411 | #ifdef HAVE_PCAP_CREATE |
||
412 | case 'I': /* Capture in monitor mode, if available */ |
||
413 | #endif |
||
414 | #ifdef HAVE_PCAP_REMOTE |
||
415 | case 'A': /* Authentication */ |
||
416 | #endif |
||
417 | case 's': /* Set the snapshot (capture) length */ |
||
418 | case 'S': /* "Sync" mode: used for following file ala tail -f */ |
||
419 | case 'w': /* Write to capture file xxx */ |
||
420 | case 'y': /* Set the pcap data link type */ |
||
421 | #ifdef CAN_SET_CAPTURE_BUFFER_SIZE |
||
422 | case 'B': /* Buffer size */ |
||
423 | #endif |
||
424 | #ifdef HAVE_LIBPCAP |
||
425 | status = capture_opts_add_opt(&global_capture_opts, opt, optarg, |
||
426 | &global_commandline_info.start_capture); |
||
427 | if(status != 0) { |
||
428 | exit(status); |
||
429 | } |
||
430 | #else |
||
431 | capture_option_specified = TRUE; |
||
432 | arg_error = TRUE; |
||
433 | #endif |
||
434 | break; |
||
435 | |||
436 | #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS) |
||
437 | case 'K': /* Kerberos keytab file */ |
||
438 | read_keytab_file(optarg); |
||
439 | break; |
||
440 | #endif |
||
441 | |||
442 | /*** all non capture option specific ***/ |
||
443 | case 'C': |
||
444 | /* Configuration profile settings were already processed just ignore them this time*/ |
||
445 | break; |
||
446 | case 'd': /* Decode as rule */ |
||
447 | if (!decode_as_command_option(optarg)) |
||
448 | exit(1); |
||
449 | break; |
||
450 | case 'j': /* Search backwards for a matching packet from filter in option J */ |
||
451 | global_commandline_info.jump_backwards = SD_BACKWARD; |
||
452 | break; |
||
453 | case 'g': /* Go to packet with the given packet number */ |
||
454 | global_commandline_info.go_to_packet = get_positive_int(optarg, "go to packet"); |
||
455 | break; |
||
456 | case 'J': /* Jump to the first packet which matches the filter criteria */ |
||
457 | global_commandline_info.jfilter = optarg; |
||
458 | break; |
||
459 | case 'l': /* Automatic scrolling in live capture mode */ |
||
460 | #ifdef HAVE_LIBPCAP |
||
461 | auto_scroll_live = TRUE; |
||
462 | #else |
||
463 | capture_option_specified = TRUE; |
||
464 | arg_error = TRUE; |
||
465 | #endif |
||
466 | break; |
||
467 | case 'L': /* Print list of link-layer types and exit */ |
||
468 | #ifdef HAVE_LIBPCAP |
||
469 | global_commandline_info.list_link_layer_types = TRUE; |
||
470 | #else |
||
471 | capture_option_specified = TRUE; |
||
472 | arg_error = TRUE; |
||
473 | #endif |
||
474 | break; |
||
475 | case 'm': /* Fixed-width font for the display. GTK+ only. */ |
||
476 | g_free(global_commandline_info.prefs_p->gui_gtk2_font_name); |
||
477 | global_commandline_info.prefs_p->gui_gtk2_font_name = g_strdup(optarg); |
||
478 | break; |
||
479 | case 'n': /* No name resolution */ |
||
480 | disable_name_resolution(); |
||
481 | break; |
||
482 | case 'N': /* Select what types of addresses/port #s to resolve */ |
||
483 | badopt = string_to_name_resolve(optarg, &gbl_resolv_flags); |
||
484 | if (badopt != '\0') { |
||
485 | cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'd', m', 'n', 'N', and 't'", |
||
486 | badopt); |
||
487 | exit(1); |
||
488 | } |
||
489 | break; |
||
490 | case 'o': /* Override preference from command line */ |
||
491 | switch (prefs_set_pref(optarg)) { |
||
492 | case PREFS_SET_OK: |
||
493 | break; |
||
494 | case PREFS_SET_SYNTAX_ERR: |
||
495 | cmdarg_err("Invalid -o flag \"%s\"", optarg); |
||
496 | exit(1); |
||
497 | break; |
||
498 | case PREFS_SET_NO_SUCH_PREF: |
||
499 | /* not a preference, might be a recent setting */ |
||
500 | switch (recent_set_arg(optarg)) { |
||
501 | case PREFS_SET_OK: |
||
502 | break; |
||
503 | case PREFS_SET_SYNTAX_ERR: |
||
504 | /* shouldn't happen, checked already above */ |
||
505 | cmdarg_err("Invalid -o flag \"%s\"", optarg); |
||
506 | exit(1); |
||
507 | break; |
||
508 | case PREFS_SET_NO_SUCH_PREF: |
||
509 | case PREFS_SET_OBSOLETE: |
||
510 | cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value", |
||
511 | optarg); |
||
512 | exit(1); |
||
513 | break; |
||
514 | default: |
||
515 | g_assert_not_reached(); |
||
516 | } |
||
517 | break; |
||
518 | case PREFS_SET_OBSOLETE: |
||
519 | cmdarg_err("-o flag \"%s\" specifies obsolete preference", |
||
520 | optarg); |
||
521 | exit(1); |
||
522 | break; |
||
523 | default: |
||
524 | g_assert_not_reached(); |
||
525 | } |
||
526 | break; |
||
527 | case 'P': |
||
528 | /* Path settings were already processed just ignore them this time*/ |
||
529 | break; |
||
530 | case 'r': /* Read capture file xxx */ |
||
531 | /* We may set "last_open_dir" to "cf_name", and if we change |
||
532 | "last_open_dir" later, we free the old value, so we have to |
||
533 | set "cf_name" to something that's been allocated. */ |
||
534 | global_commandline_info.cf_name = g_strdup(optarg); |
||
535 | break; |
||
536 | case 'R': /* Read file filter */ |
||
537 | global_commandline_info.rfilter = optarg; |
||
538 | break; |
||
539 | case 't': /* Time stamp type */ |
||
540 | if (strcmp(optarg, "r") == 0) |
||
541 | global_commandline_info.time_format = TS_RELATIVE; |
||
542 | else if (strcmp(optarg, "a") == 0) |
||
543 | global_commandline_info.time_format = TS_ABSOLUTE; |
||
544 | else if (strcmp(optarg, "ad") == 0) |
||
545 | global_commandline_info.time_format = TS_ABSOLUTE_WITH_YMD; |
||
546 | else if (strcmp(optarg, "adoy") == 0) |
||
547 | global_commandline_info.time_format = TS_ABSOLUTE_WITH_YDOY; |
||
548 | else if (strcmp(optarg, "d") == 0) |
||
549 | global_commandline_info.time_format = TS_DELTA; |
||
550 | else if (strcmp(optarg, "dd") == 0) |
||
551 | global_commandline_info.time_format = TS_DELTA_DIS; |
||
552 | else if (strcmp(optarg, "e") == 0) |
||
553 | global_commandline_info.time_format = TS_EPOCH; |
||
554 | else if (strcmp(optarg, "u") == 0) |
||
555 | global_commandline_info.time_format = TS_UTC; |
||
556 | else if (strcmp(optarg, "ud") == 0) |
||
557 | global_commandline_info.time_format = TS_UTC_WITH_YMD; |
||
558 | else if (strcmp(optarg, "udoy") == 0) |
||
559 | global_commandline_info.time_format = TS_UTC_WITH_YDOY; |
||
560 | else { |
||
561 | cmdarg_err("Invalid time stamp type \"%s\"", optarg); |
||
562 | cmdarg_err_cont("It must be \"a\" for absolute, \"ad\" for absolute with YYYY-MM-DD date,"); |
||
563 | cmdarg_err_cont("\"adoy\" for absolute with YYYY/DOY date, \"d\" for delta,"); |
||
564 | cmdarg_err_cont("\"dd\" for delta displayed, \"e\" for epoch, \"r\" for relative,"); |
||
565 | cmdarg_err_cont("\"u\" for absolute UTC, \"ud\" for absolute UTC with YYYY-MM-DD date,"); |
||
566 | cmdarg_err_cont("or \"udoy\" for absolute UTC with YYYY/DOY date."); |
||
567 | exit(1); |
||
568 | } |
||
569 | break; |
||
570 | case 'u': /* Seconds type */ |
||
571 | if (strcmp(optarg, "s") == 0) |
||
572 | timestamp_set_seconds_type(TS_SECONDS_DEFAULT); |
||
573 | else if (strcmp(optarg, "hms") == 0) |
||
574 | timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC); |
||
575 | else { |
||
576 | cmdarg_err("Invalid seconds type \"%s\"", optarg); |
||
577 | cmdarg_err_cont("It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds."); |
||
578 | exit(1); |
||
579 | } |
||
580 | break; |
||
581 | case 'X': |
||
582 | /* ext ops were already processed just ignore them this time*/ |
||
583 | break; |
||
584 | case 'Y': |
||
585 | global_commandline_info.dfilter = optarg; |
||
586 | break; |
||
587 | case 'z': |
||
588 | /* We won't call the init function for the stat this soon |
||
589 | as it would disallow MATE's fields (which are registered |
||
590 | by the preferences set callback) from being used as |
||
591 | part of a tap filter. Instead, we just add the argument |
||
592 | to a list of stat arguments. */ |
||
593 | if (strcmp("help", optarg) == 0) { |
||
594 | fprintf(stderr, "wireshark: The available statistics for the \"-z\" option are:\n"); |
||
595 | list_stat_cmd_args(); |
||
596 | exit(0); |
||
597 | } |
||
598 | if (!process_stat_cmd_arg(optarg)) { |
||
599 | cmdarg_err("Invalid -z argument."); |
||
600 | cmdarg_err_cont(" -z argument must be one of :"); |
||
601 | list_stat_cmd_args(); |
||
602 | exit(1); |
||
603 | } |
||
604 | break; |
||
605 | case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */ |
||
606 | global_commandline_info.disable_protocol_slist = g_slist_append(global_commandline_info.disable_protocol_slist, optarg); |
||
607 | break; |
||
608 | case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */ |
||
609 | global_commandline_info.enable_heur_slist = g_slist_append(global_commandline_info.enable_heur_slist, optarg); |
||
610 | break; |
||
611 | case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */ |
||
612 | global_commandline_info.disable_heur_slist = g_slist_append(global_commandline_info.disable_heur_slist, optarg); |
||
613 | break; |
||
614 | default: |
||
615 | case '?': /* Bad flag - print usage message */ |
||
616 | arg_error = TRUE; |
||
617 | break; |
||
618 | } |
||
619 | } |
||
620 | |||
621 | if (!arg_error) { |
||
622 | argc -= optind; |
||
623 | argv += optind; |
||
624 | if (argc >= 1) { |
||
625 | if (global_commandline_info.cf_name != NULL) { |
||
626 | /* |
||
627 | * Input file name specified with "-r" *and* specified as a regular |
||
628 | * command-line argument. |
||
629 | */ |
||
630 | cmdarg_err("File name specified both with -r and regular argument"); |
||
631 | arg_error = TRUE; |
||
632 | } else { |
||
633 | /* |
||
634 | * Input file name not specified with "-r", and a command-line argument |
||
635 | * was specified; treat it as the input file name. |
||
636 | * |
||
637 | * Yes, this is different from tshark, where non-flag command-line |
||
638 | * arguments are a filter, but this works better on GUI desktops |
||
639 | * where a command can be specified to be run to open a particular |
||
640 | * file - yes, you could have "-r" as the last part of the command, |
||
641 | * but that's a bit ugly. |
||
642 | */ |
||
643 | #ifndef HAVE_GTKOSXAPPLICATION |
||
644 | /* |
||
645 | * For GTK+ Mac Integration, file name passed as free argument passed |
||
646 | * through grag-and-drop and opened twice sometimes causing crashes. |
||
647 | * Subject to report to GTK+ MAC. |
||
648 | */ |
||
649 | global_commandline_info.cf_name = g_strdup(argv[0]); |
||
650 | #endif |
||
651 | } |
||
652 | argc--; |
||
653 | argv++; |
||
654 | } |
||
655 | |||
656 | if (argc != 0) { |
||
657 | /* |
||
658 | * Extra command line arguments were specified; complain. |
||
659 | */ |
||
660 | cmdarg_err("Invalid argument: %s", argv[0]); |
||
661 | arg_error = TRUE; |
||
662 | } |
||
663 | } |
||
664 | |||
665 | if (arg_error) { |
||
666 | #ifndef HAVE_LIBPCAP |
||
667 | if (capture_option_specified) { |
||
668 | print_no_capture_support_error(); |
||
669 | } |
||
670 | #endif |
||
671 | commandline_print_usage(FALSE); |
||
672 | exit(1); |
||
673 | } |
||
674 | |||
675 | #ifdef HAVE_LIBPCAP |
||
676 | if (global_commandline_info.start_capture && global_commandline_info.list_link_layer_types) { |
||
677 | /* Specifying *both* is bogus. */ |
||
678 | cmdarg_err("You can't specify both -L and a live capture."); |
||
679 | exit(1); |
||
680 | } |
||
681 | |||
682 | if (global_commandline_info.list_link_layer_types) { |
||
683 | /* We're supposed to list the link-layer types for an interface; |
||
684 | did the user also specify a capture file to be read? */ |
||
685 | if (global_commandline_info.cf_name) { |
||
686 | /* Yes - that's bogus. */ |
||
687 | cmdarg_err("You can't specify -L and a capture file to be read."); |
||
688 | exit(1); |
||
689 | } |
||
690 | /* No - did they specify a ring buffer option? */ |
||
691 | if (global_capture_opts.multi_files_on) { |
||
692 | cmdarg_err("Ring buffer requested, but a capture isn't being done."); |
||
693 | exit(1); |
||
694 | } |
||
695 | } else { |
||
696 | /* We're supposed to do a live capture; did the user also specify |
||
697 | a capture file to be read? */ |
||
698 | if (global_commandline_info.start_capture && global_commandline_info.cf_name) { |
||
699 | /* Yes - that's bogus. */ |
||
700 | cmdarg_err("You can't specify both a live capture and a capture file to be read."); |
||
701 | exit(1); |
||
702 | } |
||
703 | |||
704 | /* No - was the ring buffer option specified and, if so, does it make |
||
705 | sense? */ |
||
706 | if (global_capture_opts.multi_files_on) { |
||
707 | /* Ring buffer works only under certain conditions: |
||
708 | a) ring buffer does not work with temporary files; |
||
709 | b) real_time_mode and multi_files_on are mutually exclusive - |
||
710 | real_time_mode takes precedence; |
||
711 | c) it makes no sense to enable the ring buffer if the maximum |
||
712 | file size is set to "infinite". */ |
||
713 | if (global_capture_opts.save_file == NULL) { |
||
714 | cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file."); |
||
715 | global_capture_opts.multi_files_on = FALSE; |
||
716 | } |
||
717 | if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) { |
||
718 | cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified."); |
||
719 | /* XXX - this must be redesigned as the conditions changed */ |
||
720 | } |
||
721 | } |
||
722 | } |
||
723 | #endif |
||
724 | } |
||
725 | |||
726 | /* |
||
727 | * Editor modelines |
||
728 | * |
||
729 | * Local Variables: |
||
730 | * c-basic-offset: 4 |
||
731 | * tab-width: 8 |
||
732 | * indent-tabs-mode: nil |
||
733 | * End: |
||
734 | * |
||
735 | * ex: set shiftwidth=4 tabstop=8 expandtab: |
||
736 | * :indentSize=4:tabSize=8:noTabs=true: |
||
737 | */ |