Note that variadic macros *can* be sued.
[metze/wireshark/wip.git] / wireshark-qt.cpp
1 /* wireshark-qt.cpp
2  *
3  * Wireshark - Network traffic analyzer
4  * By Gerald Combs <gerald@wireshark.org>
5  * Copyright 1998 Gerald Combs
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21
22 #include <config.h>
23
24 #include <glib.h>
25
26 #ifdef Q_OS_UNIX
27 #include <signal.h>
28 #endif
29
30 #ifdef HAVE_LIBZ
31 #include <zlib.h>       /* to get the libz version number */
32 #endif
33
34 #ifdef HAVE_GETOPT_H
35 #include <getopt.h>
36 #endif
37
38 #ifndef HAVE_GETOPT_LONG
39 #include "wsutil/wsgetopt.h"
40 #endif
41
42 #include <wsutil/clopts_common.h>
43 #include <wsutil/cmdarg_err.h>
44 #include <wsutil/crash_info.h>
45 #include <wsutil/filesystem.h>
46 #include <wsutil/privileges.h>
47 #ifdef HAVE_PLUGINS
48 #include <wsutil/plugins.h>
49 #endif
50 #include <wsutil/report_err.h>
51 #include <wsutil/u3.h>
52 #include <wsutil/unicode-utils.h>
53 #include <wsutil/ws_diag_control.h>
54 #include <wsutil/ws_version_info.h>
55
56 #include <epan/addr_resolv.h>
57 #include <epan/ex-opt.h>
58 #include <epan/tap.h>
59 #include <epan/stat_tap_ui.h>
60 #include <epan/column.h>
61 #include <epan/disabled_protos.h>
62
63 #ifdef HAVE_KERBEROS
64 #include <epan/packet.h>
65 #include <epan/asn1.h>
66 #include <epan/dissectors/packet-kerberos.h>
67 #endif
68
69 #ifdef HAVE_PLUGINS
70 #include <codecs/codecs.h>
71 #endif
72
73 /* general (not Qt specific) */
74 #include "file.h"
75 #include "epan/color_filters.h"
76 #include "log.h"
77
78 #include "epan/rtd_table.h"
79 #include "epan/srt_table.h"
80
81 #include "ui/alert_box.h"
82 #include "ui/console.h"
83 #include "ui/iface_lists.h"
84 #include "ui/language.h"
85 #include "ui/persfilepath_opt.h"
86 #include "ui/recent.h"
87 #include "ui/simple_dialog.h"
88 #include "ui/util.h"
89
90 #include "ui/qt/conversation_dialog.h"
91 #include "ui/qt/color_utils.h"
92 #include "ui/qt/coloring_rules_dialog.h"
93 #include "ui/qt/endpoint_dialog.h"
94 #include "ui/qt/main_window.h"
95 #include "ui/qt/response_time_delay_dialog.h"
96 #include "ui/qt/service_response_time_dialog.h"
97 #include "ui/qt/simple_dialog.h"
98 #include "ui/qt/simple_statistics_dialog.h"
99 #include "ui/qt/splash_overlay.h"
100 #include "ui/qt/wireshark_application.h"
101
102 #include "caputils/capture-pcap-util.h"
103
104 #ifdef _WIN32
105 #  include "caputils/capture-wpcap.h"
106 #  include "caputils/capture_wpcap_packet.h"
107 #  include <tchar.h> /* Needed for Unicode */
108 #  include <wsutil/file_util.h>
109 #  include <wsutil/os_version_info.h>
110 #endif /* _WIN32 */
111
112 #ifdef HAVE_AIRPCAP
113 #  include <caputils/airpcap.h>
114 #  include <caputils/airpcap_loader.h>
115 //#  include "airpcap_dlg.h"
116 //#  include "airpcap_gui_utils.h"
117 #endif
118
119 #include "epan/crypt/airpdcap_ws.h"
120
121 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
122 #include <QTextCodec>
123 #endif
124
125 #if defined(HAVE_LIBPCAP) || defined(HAVE_EXTCAP)
126 capture_options global_capture_opts;
127 #endif
128
129 GString *comp_info_str, *runtime_info_str;
130
131 /* update the main window */
132 void main_window_update(void)
133 {
134     WiresharkApplication::processEvents();
135 }
136
137 #ifdef HAVE_LIBPCAP
138
139 /* quit a nested main window */
140 void main_window_nested_quit(void)
141 {
142 //    if (gtk_main_level() > 0)
143     wsApp->quit();
144 }
145
146 /* quit the main window */
147 void main_window_quit(void)
148 {
149     wsApp->quit();
150 }
151
152 #endif /* HAVE_LIBPCAP */
153
154
155 // xxx copied from ../gtk/main.c
156 static void
157 print_usage(gboolean for_help_option) {
158     FILE *output;
159
160 #ifdef _WIN32
161     create_console();
162 #endif
163
164     if (for_help_option) {
165         output = stdout;
166         fprintf(output, "Wireshark %s\n"
167                 "Interactively dump and analyze network traffic.\n"
168                 "See https://www.wireshark.org for more information.\n",
169                 get_ws_vcs_version_info());
170     } else {
171         output = stderr;
172     }
173     fprintf(output, "\n");
174     fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
175     fprintf(output, "\n");
176
177 #ifdef HAVE_LIBPCAP
178     fprintf(output, "Capture interface:\n");
179     fprintf(output, "  -i <interface>           name or idx of interface (def: first non-loopback)\n");
180     fprintf(output, "  -f <capture filter>      packet filter in libpcap filter syntax\n");
181     fprintf(output, "  -s <snaplen>             packet snapshot length (def: 65535)\n");
182     fprintf(output, "  -p                       don't capture in promiscuous mode\n");
183     fprintf(output, "  -k                       start capturing immediately (def: do nothing)\n");
184     fprintf(output, "  -S                       update packet display when new packets are captured\n");
185     fprintf(output, "  -l                       turn on automatic scrolling while -S is in use\n");
186 #ifdef HAVE_PCAP_CREATE
187     fprintf(output, "  -I                       capture in monitor mode, if available\n");
188 #endif
189 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
190     fprintf(output, "  -B <buffer size>         size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
191 #endif
192     fprintf(output, "  -y <link type>           link layer type (def: first appropriate)\n");
193     fprintf(output, "  -D                       print list of interfaces and exit\n");
194     fprintf(output, "  -L                       print list of link-layer types of iface and exit\n");
195     fprintf(output, "\n");
196     fprintf(output, "Capture stop conditions:\n");
197     fprintf(output, "  -c <packet count>        stop after n packets (def: infinite)\n");
198     fprintf(output, "  -a <autostop cond.> ...  duration:NUM - stop after NUM seconds\n");
199     fprintf(output, "                           filesize:NUM - stop this file after NUM KB\n");
200     fprintf(output, "                              files:NUM - stop after NUM files\n");
201     /*fprintf(output, "\n");*/
202     fprintf(output, "Capture output:\n");
203     fprintf(output, "  -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
204     fprintf(output, "                           filesize:NUM - switch to next file after NUM KB\n");
205     fprintf(output, "                              files:NUM - ringbuffer: replace after NUM files\n");
206 #endif  /* HAVE_LIBPCAP */
207 #ifdef HAVE_PCAP_REMOTE
208     fprintf(output, "RPCAP options:\n");
209     fprintf(output, "  -A <user>:<password>     use RPCAP password authentication\n");
210 #endif
211     /*fprintf(output, "\n");*/
212     fprintf(output, "Input file:\n");
213     fprintf(output, "  -r <infile>              set the filename to read from (no pipes or stdin!)\n");
214
215     fprintf(output, "\n");
216     fprintf(output, "Processing:\n");
217     fprintf(output, "  -R <read filter>         packet filter in Wireshark display filter syntax\n");
218     fprintf(output, "  -n                       disable all name resolutions (def: all enabled)\n");
219     fprintf(output, "  -N <name resolve flags>  enable specific name resolution(s): \"mnNtCd\"\n");
220     fprintf(output, "  --disable-protocol <proto_name>\n");
221     fprintf(output, "                           disable dissection of proto_name\n");
222     fprintf(output, "  --enable-heuristic <short_name>\n");
223     fprintf(output, "                           enable dissection of heuristic protocol\n");
224     fprintf(output, "  --disable-heuristic <short_name>\n");
225     fprintf(output, "                           disable dissection of heuristic protocol\n");
226
227     fprintf(output, "\n");
228     fprintf(output, "User interface:\n");
229     fprintf(output, "  -C <config profile>      start with specified configuration profile\n");
230     fprintf(output, "  -Y <display filter>      start with the given display filter\n");
231     fprintf(output, "  -g <packet number>       go to specified packet number after \"-r\"\n");
232     fprintf(output, "  -J <jump filter>         jump to the first packet matching the (display)\n");
233     fprintf(output, "                           filter\n");
234     fprintf(output, "  -j                       search backwards for a matching packet after \"-J\"\n");
235     fprintf(output, "  -m <font>                set the font name used for most text\n");
236     fprintf(output, "  -t a|ad|d|dd|e|r|u|ud    output format of time stamps (def: r: rel. to first)\n");
237     fprintf(output, "  -u s|hms                 output format of seconds (def: s: seconds)\n");
238     fprintf(output, "  -X <key>:<value>         eXtension options, see man page for details\n");
239     fprintf(output, "  -z <statistics>          show various statistics, see man page for details\n");
240
241     fprintf(output, "\n");
242     fprintf(output, "Output:\n");
243     fprintf(output, "  -w <outfile|->           set the output filename (or '-' for stdout)\n");
244
245     fprintf(output, "\n");
246     fprintf(output, "Miscellaneous:\n");
247     fprintf(output, "  -h                       display this help and exit\n");
248     fprintf(output, "  -v                       display version info and exit\n");
249     fprintf(output, "  -P <key>:<path>          persconf:path - personal configuration files\n");
250     fprintf(output, "                           persdata:path - personal data files\n");
251     fprintf(output, "  -o <name>:<value> ...    override preference or recent setting\n");
252     fprintf(output, "  -K <keytab>              keytab file to use for kerberos decryption\n");
253 #ifndef _WIN32
254     fprintf(output, "  --display=DISPLAY        X display to use\n");
255 #endif
256     fprintf(output, "\nNOTE: Not all options are implemented in the Qt port.\n");
257
258 #ifdef _WIN32
259     destroy_console();
260 #endif
261 }
262
263 /*
264  * Report an error in command-line arguments.
265  * Creates a console on Windows.
266  */
267 // xxx copied from ../gtk/main.c
268 static void
269 wireshark_cmdarg_err(const char *fmt, va_list ap)
270 {
271 #ifdef _WIN32
272     create_console();
273 #endif
274     fprintf(stderr, "wireshark: ");
275     vfprintf(stderr, fmt, ap);
276     fprintf(stderr, "\n");
277 }
278
279 /*
280  * Report additional information for an error in command-line arguments.
281  * Creates a console on Windows.
282  * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
283  * terminal isn't the standard error?
284  */
285 // xxx copied from ../gtk/main.c
286 static void
287 wireshark_cmdarg_err_cont(const char *fmt, va_list ap)
288 {
289 #ifdef _WIN32
290     create_console();
291 #endif
292     vfprintf(stderr, fmt, ap);
293     fprintf(stderr, "\n");
294 }
295
296 // xxx based from ../gtk/main.c:get_gtk_compiled_info
297 static void
298 get_wireshark_qt_compiled_info(GString *str)
299 {
300     g_string_append(str, "with ");
301     g_string_append_printf(str,
302 #ifdef QT_VERSION
303                     "Qt %s", QT_VERSION_STR);
304 #else
305                     "Qt (version unknown)");
306 #endif
307
308     /* Capture libraries */
309     g_string_append(str, ", ");
310     get_compiled_caplibs_version(str);
311
312     /* LIBZ */
313     g_string_append(str, ", ");
314 #ifdef HAVE_LIBZ
315     g_string_append(str, "with libz ");
316 #ifdef ZLIB_VERSION
317     g_string_append(str, ZLIB_VERSION);
318 #else /* ZLIB_VERSION */
319     g_string_append(str, "(version unknown)");
320 #endif /* ZLIB_VERSION */
321 #else /* HAVE_LIBZ */
322     g_string_append(str, "without libz");
323 #endif /* HAVE_LIBZ */
324 }
325
326 // xxx copied from ../gtk/main.c
327 static void
328 get_gui_compiled_info(GString *str)
329 {
330     epan_get_compiled_version_info(str);
331
332     g_string_append(str, ", ");
333 #ifdef QT_MULTIMEDIA_LIB
334     g_string_append(str, "with QtMultimedia");
335 #else
336     g_string_append(str, "without QtMultimedia");
337 #endif
338
339     g_string_append(str, ", ");
340 #ifdef HAVE_AIRPCAP
341     get_compiled_airpcap_version(str);
342 #else
343     g_string_append(str, "without AirPcap");
344 #endif
345 }
346
347 // xxx copied from ../gtk/main.c
348 static void
349 get_wireshark_runtime_info(GString *str)
350 {
351 #ifdef HAVE_LIBPCAP
352     /* Capture libraries */
353     g_string_append(str, ", ");
354     get_runtime_caplibs_version(str);
355 #endif
356
357     /* zlib */
358 #if defined(HAVE_LIBZ) && !defined(_WIN32)
359     g_string_append_printf(str, ", with libz %s", zlibVersion());
360 #endif
361
362     /* stuff used by libwireshark */
363     epan_get_runtime_version_info(str);
364
365 #ifdef HAVE_AIRPCAP
366     g_string_append(str, ", ");
367     get_runtime_airpcap_version(str);
368 #endif
369
370     if(u3_active()) {
371         g_string_append(str, ", ");
372         u3_runtime_info(str);
373     }
374 }
375
376 #ifdef HAVE_LIBPCAP
377 /*  Check if there's something important to tell the user during startup.
378  *  We want to do this *after* showing the main window so that any windows
379  *  we pop up will be above the main window.
380  */
381 static void
382 check_and_warn_user_startup(const QString &cf_name)
383 {
384 #ifndef _WIN32
385     Q_UNUSED(cf_name)
386 #endif
387     gchar               *cur_user, *cur_group;
388
389     /* Tell the user not to run as root. */
390     if (running_with_special_privs() && recent.privs_warn_if_elevated) {
391         cur_user = get_cur_username();
392         cur_group = get_cur_groupname();
393         simple_message_box(ESD_TYPE_WARN, &recent.privs_warn_if_elevated,
394         "Running as user \"%s\" and group \"%s\".\n"
395         "This could be dangerous.\n\n"
396         "If you're running Wireshark this way in order to perform live capture, "
397         "you may want to be aware that there is a better way documented at\n"
398         "https://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
399         g_free(cur_user);
400         g_free(cur_group);
401     }
402
403 #ifdef _WIN32
404     /* Warn the user if npf.sys isn't loaded. */
405     if (!get_stdin_capture() && cf_name.isEmpty() && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_windows_major_version() >= 6) {
406         simple_message_box(ESD_TYPE_WARN, &recent.privs_warn_if_no_npf, "%s",
407         "The NPF driver isn't running. You may have trouble\n"
408         "capturing or listing interfaces.");
409     }
410 #endif
411
412 }
413 #endif
414
415 #ifdef _WIN32
416 // Try to avoid library search path collisions. QCoreApplication will
417 // search QT_INSTALL_PREFIX/plugins for platform DLLs before searching
418 // the application directory. If
419 //
420 // - You have Qt version 5.x.y installed in the default location
421 //   (C:\Qt\5.x) on your machine.
422 //
423 // and
424 //
425 // - You install Wireshark that was built on a machine with Qt version
426 //   5.x.z installed in the default location.
427 //
428 // Qt5Core.dll will load qwindows.dll from your local C:\Qt\5.x\...\plugins
429 // directory. This may not be compatible with qwindows.dll from that
430 // same path on the build machine. At any rate, loading DLLs from paths
431 // you don't control is ill-advised. We work around this by removing every
432 // path except our application directory.
433
434 static inline void
435 reset_library_path(void)
436 {
437     QString app_path = QDir(get_progfile_dir()).path();
438     foreach (QString path, QCoreApplication::libraryPaths()) {
439         QCoreApplication::removeLibraryPath(path);
440     }
441     QCoreApplication::addLibraryPath(app_path);
442 }
443 #endif
444
445 /* And now our feature presentation... [ fade to music ] */
446 int main(int argc, char *argv[])
447 {
448     MainWindow *main_w;
449
450     int                  opt;
451     gboolean             arg_error = FALSE;
452     char               **ws_argv = argv;
453
454 #ifdef _WIN32
455     WSADATA              wsaData;
456 #endif  /* _WIN32 */
457
458     char                *rf_path;
459     int                  rf_open_errno;
460     char                *gdp_path, *dp_path;
461 #ifdef HAVE_LIBPCAP
462     int                  err;
463     gboolean             start_capture = FALSE;
464     gboolean             list_link_layer_types = FALSE;
465     GList               *if_list;
466     gchar               *err_str;
467     int                  status;
468 #else
469     gboolean             capture_option_specified = FALSE;
470 #ifdef _WIN32
471 #ifdef HAVE_AIRPCAP
472     gchar               *err_str;
473 #endif
474 #endif
475 #endif
476     e_prefs             *prefs_p;
477     char                 badopt;
478     guint                go_to_packet = 0;
479
480     QString              dfilter, read_filter;
481     GSList              *disable_protocol_slist = NULL;
482     GSList              *enable_heur_slist = NULL;
483     GSList              *disable_heur_slist = NULL;
484
485     cmdarg_err_init(wireshark_cmdarg_err, wireshark_cmdarg_err_cont);
486
487     // In Qt 5, C strings are treated always as UTF-8 when converted to
488     // QStrings; in Qt 4, the codec must be set to make that happen
489 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
490     // Hopefully we won't have to use QString::fromUtf8() in as many places.
491     QTextCodec *utf8codec = QTextCodec::codecForName("UTF-8");
492     QTextCodec::setCodecForCStrings(utf8codec);
493     // XXX - QObject doesn't *have* a tr method in 5.0, as far as I can see...
494     QTextCodec::setCodecForTr(utf8codec);
495 #endif
496
497     /* Set the C-language locale to the native environment. */
498     // The GTK+ UI calls this. Should we as well?
499     //setlocale(LC_ALL, "");
500 #ifdef _WIN32
501     // QCoreApplication clobbers argv. Let's have a local copy.
502     ws_argv = (char **) g_malloc(sizeof(char *) * argc);
503     for (opt = 0; opt < argc; opt++) {
504         ws_argv[opt] = argv[opt];
505     }
506     arg_list_utf_16to8(argc, ws_argv);
507     create_app_running_mutex();
508 #endif /* _WIN32 */
509
510     /*
511      * Get credential information for later use, and drop privileges
512      * before doing anything else.
513      * Let the user know if anything happened.
514      */
515     init_process_policies();
516     relinquish_special_privs_perm();
517
518     /*
519      * Attempt to get the pathname of the executable file.
520      */
521     /* init_progfile_dir_error = */ init_progfile_dir(ws_argv[0],
522         (int (*)(int, char **)) get_gui_compiled_info);
523     g_log(NULL, G_LOG_LEVEL_DEBUG, "progfile_dir: %s", get_progfile_dir());
524
525 #ifdef _WIN32
526     /* Load wpcap if possible. Do this before collecting the run-time version information */
527     load_wpcap();
528
529     /* ... and also load the packet.dll from wpcap */
530     wpcap_packet_load();
531
532 #ifdef HAVE_AIRPCAP
533     /* Load the airpcap.dll.  This must also be done before collecting
534      * run-time version information. */
535     load_airpcap();
536 #if 0
537     airpcap_dll_ret_val = load_airpcap();
538
539     switch (airpcap_dll_ret_val) {
540     case AIRPCAP_DLL_OK:
541         /* load the airpcap interfaces */
542         g_airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
543
544         if (g_airpcap_if_list == NULL || g_list_length(g_airpcap_if_list) == 0){
545             if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
546                 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
547                 g_free(err_str);
548             }
549             airpcap_if_active = NULL;
550
551         } else {
552
553             /* select the first ad default (THIS SHOULD BE CHANGED) */
554             airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
555         }
556         break;
557     /*
558      * XXX - Maybe we need to warn the user if one of the following happens???
559      */
560     case AIRPCAP_DLL_OLD:
561         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
562         break;
563
564     case AIRPCAP_DLL_ERROR:
565         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
566         break;
567
568     case AIRPCAP_DLL_NOT_FOUND:
569         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
570         break;
571     }
572 #endif
573 #endif /* HAVE_AIRPCAP */
574 #endif /* _WIN32 */
575
576     /* Get the compile-time version information string */
577     // XXX qtshark
578     comp_info_str = get_compiled_version_info(get_wireshark_qt_compiled_info,
579                                               get_gui_compiled_info);
580
581     /* Assemble the run-time version information string */
582     // xxx qtshark
583     runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
584
585     /*
586      * In order to have the -X opts assigned before the wslua machine starts
587      * we need to call getopt_long before epan_init() gets called.
588      *
589      * In addition, we process "console only" parameters (ones where we
590      * send output to the console and exit) here, so we don't start Qt
591      * if we're only showing command-line help or version information.
592      *
593      * XXX - this pre-scan is done before we start Qt, so we haven't
594      * run WiresharkApplication's constructor on the arguments.  That
595      * means that Qt arguments have not been removed from the argument
596      * list; those arguments begin with "-", and may be treated as
597      * errors by getopt_long().
598      *
599      * We thus ignore errors - *and* set "opterr" to 0 to suppress the
600      * error messages.
601      *
602      * XXX - is there some way to parse and remove Qt arguments without
603      * starting up the GUI, which we can call before calling this?
604      *
605      * In order to handle, for example, -o options, we also need to call it
606      * *after* epan_init() gets called, so that the dissectors have had a
607      * chance to register their preferences, so we have another getopt_long()
608      * call later.
609      *
610      * XXX - can we do this all with one getopt_long() call, saving the
611      * arguments we can't handle until after initializing libwireshark,
612      * and then process them after initializing libwireshark?
613      *
614      * Note that we don't want to initialize libwireshark until after the
615      * GUI is up, as that can take a while, and we want a window of some
616      * sort up to show progress while that's happening.
617      */
618     // XXX Should the remaining code be in WiresharkApplcation::WiresharkApplication?
619 #define OPTSTRING OPTSTRING_CAPTURE_COMMON "C:g:Hh" "jJ:kK:lm:nN:o:P:r:R:St:u:vw:X:Y:z:"
620     static const struct option long_options[] = {
621         {"help", no_argument, NULL, 'h'},
622         {"read-file", required_argument, NULL, 'r' },
623         {"read-filter", required_argument, NULL, 'R' },
624         {"display-filter", required_argument, NULL, 'Y' },
625         {"version", no_argument, NULL, 'v'},
626         LONGOPT_CAPTURE_COMMON
627         {0, 0, 0, 0 }
628     };
629     static const char optstring[] = OPTSTRING;
630
631     opterr = 0;
632
633     while ((opt = getopt_long(argc, ws_argv, optstring, long_options, NULL)) != -1) {
634         switch (opt) {
635             case 'C':        /* Configuration Profile */
636                 if (profile_exists (optarg, FALSE)) {
637                     set_profile_name (optarg);
638                 } else {
639                     cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
640                     exit(1);
641                 }
642                 break;
643             case 'D':        /* Print a list of capture devices and exit */
644 #ifdef HAVE_LIBPCAP
645                 if_list = capture_interface_list(&err, &err_str, NULL);
646                 if (if_list == NULL) {
647                     if (err == 0)
648                         cmdarg_err("There are no interfaces on which a capture can be done");
649                     else {
650                         cmdarg_err("%s", err_str);
651                         g_free(err_str);
652                     }
653                     exit(2);
654                 }
655 #ifdef _WIN32
656                 create_console();
657 #endif /* _WIN32 */
658                 capture_opts_print_interfaces(if_list);
659                 free_interface_list(if_list);
660 #ifdef _WIN32
661                 destroy_console();
662 #endif /* _WIN32 */
663                 exit(0);
664 #else /* HAVE_LIBPCAP */
665                 capture_option_specified = TRUE;
666                 arg_error = TRUE;
667 #endif /* HAVE_LIBPCAP */
668                 break;
669             case 'h':        /* Print help and exit */
670                 print_usage(TRUE);
671                 exit(0);
672                 break;
673 #ifdef _WIN32
674             case 'i':
675                 if (strcmp(optarg, "-") == 0)
676                     set_stdin_capture(TRUE);
677                 break;
678 #endif
679             case 'P':        /* Personal file directory path settings - change these before the Preferences and alike are processed */
680                 if (!persfilepath_opt(opt, optarg)) {
681                     cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
682                     exit(2);
683                 }
684                 break;
685             case 'v':        /* Show version and exit */
686 #ifdef _WIN32
687                 create_console();
688 #endif
689                 show_version("Wireshark", comp_info_str, runtime_info_str);
690 #ifdef _WIN32
691                 destroy_console();
692 #endif
693                 exit(0);
694                 break;
695             case 'X':
696                 /*
697                  *  Extension command line options have to be processed before
698                  *  we call epan_init() as they are supposed to be used by dissectors
699                  *  or taps very early in the registration process.
700                  */
701                 ex_opt_add(optarg);
702                 break;
703             case '?':        /* Ignore errors - the "real" scan will catch them. */
704                 break;
705         }
706     }
707
708 #ifdef _WIN32
709     reset_library_path();
710 #endif
711
712     /* Create The Wireshark app */
713     WiresharkApplication ws_app(argc, argv);
714
715     /* initialize the funnel mini-api */
716     // xxx qtshark
717     //initialize_funnel_ops();
718
719     AirPDcapInitContext(&airpdcap_ctx);
720
721     QString locale;
722     QString cf_name;
723     unsigned int in_file_type = WTAP_TYPE_AUTO;
724
725     /* Add it to the information to be reported on a crash. */
726     ws_add_crash_info("Wireshark %s\n"
727            "\n"
728            "%s"
729            "\n"
730            "%s",
731         get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
732
733 #ifdef _WIN32
734     /* Start windows sockets */
735     WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
736 #endif  /* _WIN32 */
737
738     profile_store_persconffiles(TRUE);
739
740     /* Read the profile independent recent file.  We have to do this here so we can */
741     /* set the profile before it can be set from the command line parameter */
742     if (!recent_read_static(&rf_path, &rf_open_errno)) {
743         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
744                       "Could not open common recent file\n\"%s\": %s.",
745                       rf_path, strerror(rf_open_errno));
746         g_free(rf_path);
747     }
748
749     /* Read the profile dependent (static part) of the recent file. */
750     /* Only the static part of it will be read, as we don't have the gui now to fill the */
751     /* recent lists which is done in the dynamic part. */
752     /* We have to do this already here, so command line parameters can overwrite these values. */
753     if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
754         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
755                       "Could not open recent file\n\"%s\": %s.",
756                       rf_path, g_strerror(rf_open_errno));
757         g_free(rf_path);
758     }
759     wsApp->applyCustomColorsFromRecent();
760
761     // Initialize our language
762     read_language_prefs();
763     locale = QString(language);
764     wsApp->loadLanguage(locale);
765
766     g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Translator %s", locale.toStdString().c_str());
767
768     // Init the main window (and splash)
769     main_w = new(MainWindow);
770     main_w->show();
771     // We may not need a queued connection here but it would seem to make sense
772     // to force the issue.
773     main_w->connect(&ws_app, SIGNAL(openCaptureFile(QString,QString,unsigned int)),
774             main_w, SLOT(openCaptureFile(QString,QString,unsigned int)));
775
776     /* Init the "Open file" dialog directory */
777     /* (do this after the path settings are processed) */
778     if (recent.gui_fileopen_remembered_dir &&
779         test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
780       wsApp->setLastOpenDir(recent.gui_fileopen_remembered_dir);
781     } else {
782       wsApp->setLastOpenDir(get_persdatafile_dir());
783     }
784
785 #ifdef Q_OS_UNIX
786     // Replicates behavior in gtk_init();
787     signal(SIGPIPE, SIG_IGN);
788 #endif
789
790     set_console_log_handler();
791
792 #ifdef HAVE_LIBPCAP
793     /* Set the initial values in the capture options. This might be overwritten
794        by preference settings and then again by the command line parameters. */
795     capture_opts_init(&global_capture_opts);
796 #endif
797
798     init_report_err(failure_alert_box, open_failure_alert_box,
799                     read_failure_alert_box, write_failure_alert_box);
800
801     init_open_routines();
802
803 #ifdef HAVE_PLUGINS
804     /* Register all the plugin types we have. */
805     epan_register_plugin_types(); /* Types known to libwireshark */
806     wtap_register_plugin_types(); /* Types known to libwiretap */
807     codec_register_plugin_types(); /* Types known to libwscodecs */
808
809     /* Scan for plugins.  This does *not* call their registration routines;
810        that's done later. */
811     scan_plugins();
812
813     /* Register all libwiretap plugin modules. */
814     register_all_wiretap_modules();
815
816     /* Register all audio codec plugins. */
817     register_all_codecs();
818 #endif
819
820     /* Register all dissectors; we must do this before checking for the
821        "-G" flag, as the "-G" flag dumps information registered by the
822        dissectors, and we must do it before we read the preferences, in
823        case any dissectors register preferences. */
824     if (!epan_init(register_all_protocols,register_all_protocol_handoffs,
825                    splash_update, NULL)) {
826         SimpleDialog::displayQueuedMessages(main_w);
827         return 2;
828     }
829
830     splash_update(RA_LISTENERS, NULL, NULL);
831
832     /* Register all tap listeners; we do this before we parse the arguments,
833        as the "-z" argument can specify a registered tap. */
834
835     /* we register the plugin taps before the other taps because
836             stats_tree taps plugins will be registered as tap listeners
837             by stats_tree_stat.c and need to registered before that */
838 #ifdef HAVE_PLUGINS
839     register_all_plugin_tap_listeners();
840 #endif
841
842     register_all_tap_listeners();
843     conversation_table_set_gui_info(init_conversation_table);
844     hostlist_table_set_gui_info(init_endpoint_table);
845     srt_table_iterate_tables(register_service_response_tables, NULL);
846     rtd_table_iterate_tables(register_response_time_delay_tables, NULL);
847     new_stat_tap_iterate_tables(register_simple_stat_tables, NULL);
848
849     if (ex_opt_count("read_format") > 0) {
850         in_file_type = open_info_name_to_type(ex_opt_get_next("read_format"));
851     }
852
853     splash_update(RA_PREFERENCES, NULL, NULL);
854
855     prefs_p = ws_app.readConfigurationFiles(&gdp_path, &dp_path, false);
856
857     /*
858      * To reset the options parser, set optreset to 1 on platforms that
859      * have optreset (documented in *BSD and OS X, apparently present but
860      * not documented in Solaris - the Illumos repository seems to
861      * suggest that the first Solaris getopt_long(), at least as of 2004,
862      * was based on the NetBSD one, it had optreset) and set optind to 1,
863      * and set optind to 0 otherwise (documented as working in the GNU
864      * getopt_long().  Setting optind to 0 didn't originally work in the
865      * NetBSD one, but that was added later - we don't want to depend on
866      * it if we have optreset).
867      *
868      * Also reset opterr to 1, so that error messages are printed by
869      * getopt_long().
870      *
871      * XXX - if we want to control all the command-line option errors, so
872      * that we can display them where we choose (e.g., in a window), we'd
873      * want to leave opterr as 0, and produce our own messages using optopt.
874      * We'd have to check the value of optopt to see if it's a valid option
875      * letter, in which case *presumably* the error is "this option requires
876      * an argument but none was specified", or not a valid option letter,
877      * in which case *presumably* the error is "this option isn't valid".
878      * Some versions of getopt() let you supply a option string beginning
879      * with ':', which means that getopt() will return ':' rather than '?'
880      * for "this option requires an argument but none was specified", but
881      * not all do.  But we're now using getopt_long() - what does it do?
882      */
883 #ifdef HAVE_OPTRESET
884     optreset = 1;
885     optind = 1;
886 #else
887     optind = 0;
888 #endif
889     opterr = 1;
890
891     /* Now get our args */
892     while ((opt = getopt_long(argc, ws_argv, optstring, long_options, NULL)) != -1) {
893         switch (opt) {
894         /*** capture option specific ***/
895         case 'a':        /* autostop criteria */
896         case 'b':        /* Ringbuffer option */
897         case 'c':        /* Capture xxx packets */
898         case 'f':        /* capture filter */
899         case 'k':        /* Start capture immediately */
900         case 'H':        /* Hide capture info dialog box */
901         case 'p':        /* Don't capture in promiscuous mode */
902         case 'i':        /* Use interface x */
903 #ifdef HAVE_PCAP_CREATE
904         case 'I':        /* Capture in monitor mode, if available */
905 #endif
906 #ifdef HAVE_PCAP_REMOTE
907         case 'A':        /* Authentication */
908 #endif
909         case 's':        /* Set the snapshot (capture) length */
910         case 'S':        /* "Sync" mode: used for following file ala tail -f */
911         case 'w':        /* Write to capture file xxx */
912         case 'y':        /* Set the pcap data link type */
913 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
914         case 'B':        /* Buffer size */
915 #endif
916 #ifdef HAVE_LIBPCAP
917             status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
918                                           &start_capture);
919             if(status != 0) {
920                 exit(status);
921             }
922 #else
923             capture_option_specified = TRUE;
924             arg_error = TRUE;
925 #endif
926             break;
927 #ifdef HAVE_KERBEROS
928         case 'K':        /* Kerberos keytab file */
929             read_keytab_file(optarg);
930             break;
931 #endif
932
933         /*** all non capture option specific ***/
934         case 'C':
935             /* Configuration profile settings were already processed just ignore them this time*/
936             break;
937         case 'j':        /* Search backwards for a matching packet from filter in option J */
938             /* Not supported yet */
939             break;
940         case 'g':        /* Go to packet with the given packet number */
941             go_to_packet = get_positive_int(optarg, "go to packet");
942             break;
943         case 'J':        /* Jump to the first packet which matches the filter criteria */
944             /* Not supported yet */
945             break;
946         case 'l':        /* Automatic scrolling in live capture mode */
947 #ifdef HAVE_LIBPCAP
948             /* Not supported yet */
949 #else
950             capture_option_specified = TRUE;
951             arg_error = TRUE;
952 #endif
953             break;
954         case 'L':        /* Print list of link-layer types and exit */
955 #ifdef HAVE_LIBPCAP
956                 list_link_layer_types = TRUE;
957 #else
958                 capture_option_specified = TRUE;
959                 arg_error = TRUE;
960 #endif
961             break;
962         case 'm':        /* Fixed-width font for the display */
963             /* Not supported yet */
964             break;
965         case 'n':        /* No name resolution */
966             disable_name_resolution();
967             break;
968         case 'N':        /* Select what types of addresses/port #s to resolve */
969             badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
970             if (badopt != '\0') {
971                 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'C', 'd', m', 'n', 'N', and 't'",
972                            badopt);
973                 exit(1);
974             }
975             break;
976         case 'o':        /* Override preference from command line */
977             switch (prefs_set_pref(optarg)) {
978                 case PREFS_SET_OK:
979                     break;
980                 case PREFS_SET_SYNTAX_ERR:
981                     cmdarg_err("Invalid -o flag \"%s\"", optarg);
982                     exit(1);
983                     break;
984                 case PREFS_SET_NO_SUCH_PREF:
985                 /* not a preference, might be a recent setting */
986                     switch (recent_set_arg(optarg)) {
987                         case PREFS_SET_OK:
988                             break;
989                         case PREFS_SET_SYNTAX_ERR:
990                             /* shouldn't happen, checked already above */
991                             cmdarg_err("Invalid -o flag \"%s\"", optarg);
992                             exit(1);
993                             break;
994                         case PREFS_SET_NO_SUCH_PREF:
995                         case PREFS_SET_OBSOLETE:
996                             cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
997                                        optarg);
998                             exit(1);
999                             break;
1000                         default:
1001                             g_assert_not_reached();
1002                     }
1003                     break;
1004                 case PREFS_SET_OBSOLETE:
1005                     cmdarg_err("-o flag \"%s\" specifies obsolete preference",
1006                                optarg);
1007                     exit(1);
1008                     break;
1009                 default:
1010                     g_assert_not_reached();
1011             }
1012             break;
1013         case 'P':
1014             /* Path settings were already processed just ignore them this time*/
1015             break;
1016         case 'r':
1017             cf_name = optarg;
1018             break;
1019         case 'R':        /* Read file filter */
1020             read_filter = QString(optarg);
1021             break;
1022         case 't':        /* Time stamp type */
1023             if (strcmp(optarg, "r") == 0)
1024                 timestamp_set_type(TS_RELATIVE);
1025             else if (strcmp(optarg, "a") == 0)
1026                 timestamp_set_type(TS_ABSOLUTE);
1027             else if (strcmp(optarg, "ad") == 0)
1028                 timestamp_set_type(TS_ABSOLUTE_WITH_YMD);
1029             else if (strcmp(optarg, "adoy") == 0)
1030                 timestamp_set_type(TS_ABSOLUTE_WITH_YDOY);
1031             else if (strcmp(optarg, "d") == 0)
1032                 timestamp_set_type(TS_DELTA);
1033             else if (strcmp(optarg, "dd") == 0)
1034                 timestamp_set_type(TS_DELTA_DIS);
1035             else if (strcmp(optarg, "e") == 0)
1036                 timestamp_set_type(TS_EPOCH);
1037             else if (strcmp(optarg, "u") == 0)
1038                 timestamp_set_type(TS_UTC);
1039             else if (strcmp(optarg, "ud") == 0)
1040                 timestamp_set_type(TS_UTC_WITH_YMD);
1041             else if (strcmp(optarg, "udoy") == 0)
1042                 timestamp_set_type(TS_UTC_WITH_YDOY);
1043             else {
1044                 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
1045                 cmdarg_err_cont(
1046 "It must be \"a\" for absolute, \"ad\" for absolute with YYYY-MM-DD date,");
1047                 cmdarg_err_cont(
1048 "\"adoy\" for absolute with YYYY/DOY date, \"d\" for delta,");
1049                 cmdarg_err_cont(
1050 "\"dd\" for delta displayed, \"e\" for epoch, \"r\" for relative,");
1051                 cmdarg_err_cont(
1052 "\"u\" for absolute UTC, \"ud\" for absolute UTC with YYYY-MM-DD date,");
1053                 cmdarg_err_cont(
1054 "or \"udoy\" for absolute UTC with YYYY/DOY date.");
1055                 exit(1);
1056             }
1057             break;
1058         case 'u':        /* Seconds type */
1059             if (strcmp(optarg, "s") == 0)
1060                 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
1061             else if (strcmp(optarg, "hms") == 0)
1062                 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
1063             else {
1064                 cmdarg_err("Invalid seconds type \"%s\"", optarg);
1065                 cmdarg_err_cont(
1066 "It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
1067                 exit(1);
1068             }
1069             break;
1070         case 'X':
1071             /* ext ops were already processed just ignore them this time*/
1072             break;
1073         case 'Y':
1074             dfilter = QString(optarg);
1075             break;
1076         case 'z':
1077             /* We won't call the init function for the stat this soon
1078              as it would disallow MATE's fields (which are registered
1079              by the preferences set callback) from being used as
1080              part of a tap filter.  Instead, we just add the argument
1081              to a list of stat arguments. */
1082             if (strcmp("help", optarg) == 0) {
1083               fprintf(stderr, "wireshark: The available statistics for the \"-z\" option are:\n");
1084               list_stat_cmd_args();
1085               exit(0);
1086             }
1087             if (!process_stat_cmd_arg(optarg)) {
1088                 cmdarg_err("Invalid -z argument.");
1089                 cmdarg_err_cont("  -z argument must be one of :");
1090                 list_stat_cmd_args();
1091                 exit(1);
1092             }
1093             break;
1094         case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
1095             disable_protocol_slist = g_slist_append(disable_protocol_slist, optarg);
1096             break;
1097         case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
1098             enable_heur_slist = g_slist_append(enable_heur_slist, optarg);
1099             break;
1100         case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
1101             disable_heur_slist = g_slist_append(disable_heur_slist, optarg);
1102             break;
1103
1104         default:
1105         case '?':        /* Bad flag - print usage message */
1106             print_usage(FALSE);
1107             exit(0);
1108             break;
1109         }
1110     }
1111
1112     if (!arg_error) {
1113         argc -= optind;
1114         ws_argv += optind;
1115         if (argc >= 1) {
1116             if (!cf_name.isEmpty()) {
1117                 /*
1118                  * Input file name specified with "-r" *and* specified as a regular
1119                  * command-line argument.
1120                  */
1121                 cmdarg_err("File name specified both with -r and regular argument");
1122                 arg_error = TRUE;
1123             } else {
1124                 /*
1125                  * Input file name not specified with "-r", and a command-line argument
1126                  * was specified; treat it as the input file name.
1127                  *
1128                  * Yes, this is different from tshark, where non-flag command-line
1129                  * arguments are a filter, but this works better on GUI desktops
1130                  * where a command can be specified to be run to open a particular
1131                  * file - yes, you could have "-r" as the last part of the command,
1132                  * but that's a bit ugly.
1133                  */
1134                 cf_name = ws_argv[0];
1135
1136             }
1137             argc--;
1138             ws_argv++;
1139         }
1140
1141         if (argc != 0) {
1142             /*
1143              * Extra command line arguments were specified; complain.
1144              */
1145             cmdarg_err("Invalid argument: %s", ws_argv[0]);
1146             arg_error = TRUE;
1147         }
1148     }
1149     if (arg_error) {
1150 #ifndef HAVE_LIBPCAP
1151         if (capture_option_specified) {
1152             cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
1153         }
1154 #endif
1155         print_usage(FALSE);
1156         exit(1);
1157     }
1158
1159     /* Removed thread code:
1160      * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
1161      */
1162
1163     // XXX Is there a better place to set the timestamp format & precision?
1164     timestamp_set_type(recent.gui_time_format);
1165     timestamp_set_precision(recent.gui_time_precision);
1166     timestamp_set_seconds_type (recent.gui_seconds_format);
1167
1168 #ifdef HAVE_LIBPCAP
1169     fill_in_local_interfaces(main_window_update);
1170
1171     if (start_capture && list_link_layer_types) {
1172         /* Specifying *both* is bogus. */
1173         cmdarg_err("You can't specify both -L and a live capture.");
1174         exit(1);
1175     }
1176
1177     if (list_link_layer_types) {
1178         /* We're supposed to list the link-layer types for an interface;
1179            did the user also specify a capture file to be read? */
1180         if (!cf_name.isEmpty()) {
1181             /* Yes - that's bogus. */
1182             cmdarg_err("You can't specify -L and a capture file to be read.");
1183         exit(1);
1184         }
1185         /* No - did they specify a ring buffer option? */
1186         if (global_capture_opts.multi_files_on) {
1187             cmdarg_err("Ring buffer requested, but a capture isn't being done.");
1188             exit(1);
1189         }
1190     } else {
1191         /* We're supposed to do a live capture; did the user also specify
1192            a capture file to be read? */
1193         if (start_capture && !cf_name.isEmpty()) {
1194             /* Yes - that's bogus. */
1195             cmdarg_err("You can't specify both a live capture and a capture file to be read.");
1196             exit(1);
1197         }
1198
1199         /* No - was the ring buffer option specified and, if so, does it make
1200            sense? */
1201         if (global_capture_opts.multi_files_on) {
1202             /* Ring buffer works only under certain conditions:
1203              a) ring buffer does not work with temporary files;
1204              b) real_time_mode and multi_files_on are mutually exclusive -
1205              real_time_mode takes precedence;
1206              c) it makes no sense to enable the ring buffer if the maximum
1207              file size is set to "infinite". */
1208             if (global_capture_opts.save_file == NULL) {
1209                 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
1210                 global_capture_opts.multi_files_on = FALSE;
1211             }
1212             if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
1213                 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
1214                 /* XXX - this must be redesigned as the conditions changed */
1215             }
1216         }
1217     }
1218
1219     if (start_capture || list_link_layer_types) {
1220         /* We're supposed to do a live capture or get a list of link-layer
1221            types for a live capture device; if the user didn't specify an
1222            interface to use, pick a default. */
1223         status = capture_opts_default_iface_if_necessary(&global_capture_opts,
1224         ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
1225         if (status != 0) {
1226             exit(status);
1227         }
1228     }
1229
1230     if (list_link_layer_types) {
1231         /* Get the list of link-layer types for the capture devices. */
1232         if_capabilities_t *caps;
1233         guint i;
1234         interface_t device;
1235         for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
1236
1237             device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
1238             if (device.selected) {
1239 #if defined(HAVE_PCAP_CREATE)
1240                 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, NULL, &err_str, main_window_update);
1241 #else
1242                 caps = capture_get_if_capabilities(device.name, FALSE, NULL, &err_str,main_window_update);
1243 #endif
1244                 if (caps == NULL) {
1245                     cmdarg_err("%s", err_str);
1246                     g_free(err_str);
1247                     exit(2);
1248                 }
1249             if (caps->data_link_types == NULL) {
1250                 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
1251                 exit(2);
1252             }
1253 #ifdef _WIN32
1254             create_console();
1255 #endif /* _WIN32 */
1256 #if defined(HAVE_PCAP_CREATE)
1257             capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
1258 #else
1259             capture_opts_print_if_capabilities(caps, device.name, FALSE);
1260 #endif
1261 #ifdef _WIN32
1262             destroy_console();
1263 #endif /* _WIN32 */
1264             free_if_capabilities(caps);
1265             }
1266         }
1267         exit(0);
1268     }
1269
1270     capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
1271     capture_opts_trim_ring_num_files(&global_capture_opts);
1272 #endif /* HAVE_LIBPCAP */
1273
1274     /* Notify all registered modules that have had any of their preferences
1275        changed either from one of the preferences file or from the command
1276        line that their preferences have changed. */
1277     prefs_apply_all();
1278     wsApp->emitAppSignal(WiresharkApplication::PreferencesChanged);
1279
1280 #ifdef HAVE_LIBPCAP
1281     if ((global_capture_opts.num_selected == 0) &&
1282             (prefs.capture_device != NULL)) {
1283         guint i;
1284         interface_t device;
1285         for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
1286             device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
1287             if (!device.hidden && strcmp(device.display_name, prefs.capture_device) == 0) {
1288                 device.selected = TRUE;
1289                 global_capture_opts.num_selected++;
1290                 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
1291                 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
1292                 break;
1293             }
1294         }
1295     }
1296 #endif
1297
1298     /* disabled protocols as per configuration file */
1299     if (gdp_path == NULL && dp_path == NULL) {
1300         set_disabled_protos_list();
1301         set_disabled_heur_dissector_list();
1302     }
1303
1304     if(disable_protocol_slist) {
1305         GSList *proto_disable;
1306         for (proto_disable = disable_protocol_slist; proto_disable != NULL; proto_disable = g_slist_next(proto_disable))
1307         {
1308             proto_disable_proto_by_name((char*)proto_disable->data);
1309         }
1310     }
1311
1312     if(enable_heur_slist) {
1313         GSList *heur_enable;
1314         for (heur_enable = enable_heur_slist; heur_enable != NULL; heur_enable = g_slist_next(heur_enable))
1315         {
1316             proto_enable_heuristic_by_name((char*)heur_enable->data, TRUE);
1317         }
1318     }
1319
1320     if(disable_heur_slist) {
1321         GSList *heur_disable;
1322         for (heur_disable = disable_heur_slist; heur_disable != NULL; heur_disable = g_slist_next(heur_disable))
1323         {
1324             proto_enable_heuristic_by_name((char*)heur_disable->data, FALSE);
1325         }
1326     }
1327
1328     build_column_format_array(&CaptureFile::globalCapFile()->cinfo, prefs_p->num_cols, TRUE);
1329     wsApp->emitAppSignal(WiresharkApplication::ColumnsChanged); // We read "recent" widths above.
1330     wsApp->emitAppSignal(WiresharkApplication::RecentFilesRead); // Must be emitted after PreferencesChanged.
1331
1332     wsApp->setMonospaceFont(prefs.gui_qt_font_name);
1333
1334     /* For update of WindowTitle (When use gui.window_title preference) */
1335     main_w->setWSWindowTitle();
1336 ////////
1337
1338     /* Read the dynamic part of the recent file, as we have the gui now ready for
1339        it. */
1340     if (!recent_read_dynamic(&rf_path, &rf_open_errno)) {
1341         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1342                       "Could not open recent file\n\"%s\": %s.",
1343                       rf_path, g_strerror(rf_open_errno));
1344         g_free(rf_path);
1345     }
1346
1347     packet_list_enable_color(recent.packet_list_colorize);
1348
1349     g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: fetch recent color settings");
1350     packet_list_enable_color(TRUE);
1351
1352 ////////
1353
1354
1355 ////////
1356     gchar* err_msg = NULL;
1357     if (!color_filters_init(&err_msg, color_filter_add_cb)) {
1358         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
1359         g_free(err_msg);
1360     }
1361
1362 ////////
1363
1364 #ifdef HAVE_LIBPCAP
1365     /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
1366     if (!start_capture && !global_capture_opts.default_options.cfilter) {
1367         global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
1368     }
1369 #else /* HAVE_LIBPCAP */
1370     ////////
1371 #endif /* HAVE_LIBPCAP */
1372
1373     wsApp->allSystemsGo();
1374     g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
1375     SimpleDialog::displayQueuedMessages(main_w);
1376
1377     /* User could specify filename, or display filter, or both */
1378     if (!dfilter.isEmpty())
1379         main_w->filterPackets(dfilter, false);
1380     if (!cf_name.isEmpty()) {
1381         if (main_w->openCaptureFile(cf_name, read_filter, in_file_type)) {
1382
1383             /* Open stat windows; we do so after creating the main window,
1384                to avoid Qt warnings, and after successfully opening the
1385                capture file, so we know we have something to compute stats
1386                on, and after registering all dissectors, so that MATE will
1387                have registered its field array and we can have a tap filter
1388                with one of MATE's late-registered fields as part of the
1389                filter. */
1390             start_requested_stats();
1391
1392             if(go_to_packet != 0) {
1393                 /* Jump to the specified frame number, kept for backward
1394                    compatibility. */
1395                 cf_goto_frame(CaptureFile::globalCapFile(), go_to_packet);
1396             }
1397         }
1398     }
1399 #ifdef HAVE_LIBPCAP
1400     else {
1401         if (start_capture) {
1402             if (global_capture_opts.save_file != NULL) {
1403                 /* Save the directory name for future file dialogs. */
1404                 /* (get_dirname overwrites filename) */
1405                 gchar *s = get_dirname(g_strdup(global_capture_opts.save_file));
1406                 set_last_open_dir(s);
1407                 g_free(s);
1408             }
1409             /* "-k" was specified; start a capture. */
1410 //            show_main_window(FALSE);
1411             check_and_warn_user_startup(cf_name);
1412
1413             /* If no user interfaces were specified on the command line,
1414                copy the list of selected interfaces to the set of interfaces
1415                to use for this capture. */
1416             if (global_capture_opts.ifaces->len == 0)
1417                 collect_ifaces(&global_capture_opts);
1418             CaptureFile::globalCapFile()->window = main_w;
1419             if (capture_start(&global_capture_opts, main_w->captureSession(), main_w->captureInfoData(), main_window_update)) {
1420                 /* The capture started.  Open stat windows; we do so after creating
1421                    the main window, to avoid GTK warnings, and after successfully
1422                    opening the capture file, so we know we have something to compute
1423                    stats on, and after registering all dissectors, so that MATE will
1424                    have registered its field array and we can have a tap filter with
1425                    one of MATE's late-registered fields as part of the filter. */
1426                 start_requested_stats();
1427             }
1428         }
1429     /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
1430         if (!start_capture && !global_capture_opts.default_options.cfilter) {
1431             global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
1432         }
1433     }
1434 #endif /* HAVE_LIBPCAP */
1435
1436     return wsApp->exec();
1437 }
1438
1439 /*
1440  * Editor modelines
1441  *
1442  * Local Variables:
1443  * c-basic-offset: 4
1444  * tab-width: 8
1445  * indent-tabs-mode: nil
1446  * End:
1447  *
1448  * ex: set shiftwidth=4 tabstop=8 expandtab:
1449  * :indentSize=4:tabSize=8:noTabs=true:
1450  */