/* etwdump.c * etwdump is an extcap tool used to dump etw to pcapng * * Copyright 2020, Odysseus Yang * * Wireshark - Network traffic analyzer * By Gerald Combs * Copyright 1998 Gerald Combs * * SPDX-License-Identifier: GPL-2.0-or-later */ #include "config.h" #include "extcap-base.h" #include #include #include #include #include #include #include "etl.h" /* extcap-interface has to be unique, or it may use wrong option output by a different extcapbin */ #define ETW_EXTCAP_INTERFACE "etwdump" #define ETWDUMP_VERSION_MAJOR "1" #define ETWDUMP_VERSION_MINOR "0" #define ETWDUMP_VERSION_RELEASE "0" enum { EXTCAP_BASE_OPTIONS_ENUM, OPT_HELP, OPT_VERSION, OPT_INCLUDE_UNDECIDABLE_EVENT, OPT_ETLFILE }; static struct option longopts[] = { EXTCAP_BASE_OPTIONS, { "help", no_argument, NULL, OPT_HELP}, { "version", no_argument, NULL, OPT_VERSION}, { "iue", optional_argument, NULL, OPT_INCLUDE_UNDECIDABLE_EVENT}, { "etlfile", required_argument, NULL, OPT_ETLFILE}, { 0, 0, 0, 0 } }; int g_include_undecidable_event = FALSE; static void help(extcap_parameters* extcap_conf) { extcap_help_print(extcap_conf); } static int list_config(char* interface) { unsigned inc = 0; if (!interface) { g_warning("No interface specified."); return EXIT_FAILURE; } if (g_strcmp0(interface, ETW_EXTCAP_INTERFACE)) { g_warning("Interface must be %s", ETW_EXTCAP_INTERFACE); return EXIT_FAILURE; } /* Saved for later live capture support */ #if 0 printf("arg {number=%u}{call=--type}{display=Capture type}" "{type=selector}{tooltip=Choose the type of capture}{group=Capture}\n", inc); printf("value {arg=%u}{value=etl}{display=From a etl file}\n", inc); printf("value {arg=%u}{value=live}{display=From a live session}\n", inc); inc++; #endif /* * The undecidable events are those that either don't have sub-dissector or don't have anthing meaningful to display except for the EVENT_HEADER. */ printf("arg {number=%u}{call=--iue}{display=Should undecidable events be included}" "{type=boolflag}{default=false}{tooltip=Choose if the undecidable event is included}{group=Capture}\n", inc++); printf("arg {number=%u}{call=--etlfile}{display=etl file}" "{type=fileselect}{tooltip=Select etl file to display in Wireshark}{required=true}{group=Capture}\n", inc++); /* Saved for later live capture support */ #if 0 printf("arg {number=%u}{call=--session-params}{display=Live session parameters}" "{type=string}{tooltip=providers, keyword and level}{group=Capture}\n", inc++); #endif extcap_config_debug(&inc); return EXIT_SUCCESS; } int main(int argc, char* argv[]) { char* err_msg; int option_idx = 0; int result; int ret = EXIT_FAILURE; char* etlfile = NULL; extcap_parameters* extcap_conf = g_new0(extcap_parameters, 1); char* help_url; char* help_header = NULL; /* * Get credential information for later use. */ init_process_policies(); /* * Attempt to get the pathname of the directory containing the * executable file. */ err_msg = init_progfile_dir(argv[0]); if (err_msg != NULL) { g_warning("Can't get pathname of directory containing the captype program: %s.", err_msg); g_free(err_msg); } help_url = data_file_url("etwdump.html"); extcap_base_set_util_info(extcap_conf, argv[0], ETWDUMP_VERSION_MAJOR, ETWDUMP_VERSION_MINOR, ETWDUMP_VERSION_RELEASE, help_url); g_free(help_url); extcap_base_register_interface(extcap_conf, ETW_EXTCAP_INTERFACE, "ETW reader", 290, "DLT_ETW"); help_header = g_strdup_printf( " %s --extcap-interfaces\n" " %s --extcap-interface=%s --extcap-dlts\n" " %s --extcap-interface=%s --extcap-config\n" " %s --extcap-interface=%s --etlfile c:\\wwansvc.etl \n" "--fifo=FILENAME --capture\n", argv[0], argv[0], ETW_EXTCAP_INTERFACE, argv[0], ETW_EXTCAP_INTERFACE, argv[0], ETW_EXTCAP_INTERFACE); extcap_help_add_header(extcap_conf, help_header); g_free(help_header); extcap_help_add_option(extcap_conf, "--help", "print this help"); extcap_help_add_option(extcap_conf, "--version", "print the version"); extcap_help_add_option(extcap_conf, "--etlfile ", "A etl filename"); extcap_help_add_option(extcap_conf, "--iue", "Choose if undecidable event is included"); if (argc == 1) { help(extcap_conf); goto end; } while ((result = getopt_long(argc, argv, ":", longopts, &option_idx)) != -1) { switch (result) { case OPT_VERSION: extcap_version_print(extcap_conf); ret = EXIT_SUCCESS; goto end; case OPT_HELP: help(extcap_conf); ret = EXIT_SUCCESS; goto end; case OPT_ETLFILE: etlfile = g_strdup(optarg); break; case OPT_INCLUDE_UNDECIDABLE_EVENT: g_include_undecidable_event = TRUE; break; case ':': /* missing option argument */ g_warning("Option '%s' requires an argument", argv[optind - 1]); break; default: /* Handle extcap specific options */ if (!extcap_base_parse_options(extcap_conf, result - EXTCAP_OPT_LIST_INTERFACES, optarg)) { g_warning("Invalid option: %s", argv[optind - 1]); goto end; } } } extcap_cmdline_debug(argv, argc); if (extcap_base_handle_interface(extcap_conf)) { ret = EXIT_SUCCESS; goto end; } if (extcap_conf->show_config) { ret = list_config(extcap_conf->interface); goto end; } if (extcap_conf->capture) { if (g_strcmp0(extcap_conf->interface, ETW_EXTCAP_INTERFACE)) { g_warning("ERROR: invalid interface"); goto end; } wtap_init(FALSE); switch(etw_dump(etlfile, extcap_conf->fifo, &ret, &err_msg)) { case WTAP_OPEN_ERROR: if (err_msg != NULL) { g_warning("etw_dump failed: %s.", err_msg); g_free(err_msg); } else { g_warning("etw_dump failed"); } break; case WTAP_OPEN_NOT_MINE: if (err_msg != NULL) { g_warning("The file %s is not etl format. Error message: %s.", etlfile, err_msg); g_free(err_msg); } else { g_warning("The file %s is not etl format"); } break; case WTAP_OPEN_MINE: ret = EXIT_SUCCESS; break; } } end: /* clean up stuff */ extcap_base_cleanup(&extcap_conf); if (etlfile != NULL) { g_free(etlfile); } return ret; } /* * Editor modelines - https://www.wireshark.org/tools/modelines.html * * Local variables: * c-basic-offset: 4 * tab-width: 8 * indent-tabs-mode: nil * End: * * vi: set shiftwidth=4 tabstop=8 expandtab: * :indentSize=4:tabSize=8:noTabs=true: */