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