randpktdump: add --delay option
[metze/wireshark/wip.git] / extcap / extcap-base.c
index 837c297d6adda9d3051de01e0cf2ba6de4580db0..7d47aa41e5a46086a51c067ccf5911941dfa4b38 100644 (file)
@@ -7,19 +7,7 @@
  * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
 #include "config.h"
@@ -29,6 +17,7 @@
 #include <stdlib.h>
 #include <stdint.h>
 #include <string.h>
+#include <errno.h>
 
 #ifdef HAVE_GETOPT_H
     #include <getopt.h>
@@ -37,6 +26,7 @@
 #ifndef HAVE_GETOPT_LONG
     #include "wsutil/wsgetopt.h"
 #endif
+#include "ws_attributes.h"
 
 enum extcap_options {
     EXTCAP_BASE_OPTIONS_ENUM
@@ -52,6 +42,13 @@ typedef struct _extcap_interface
     char * dltdescription;
 } extcap_interface;
 
+typedef struct _extcap_option {
+    char * optname;
+    char * optdesc;
+} extcap_option_t;
+
+FILE* custom_log = NULL;
+
 #ifdef _WIN32
 BOOLEAN IsHandleRedirected(DWORD handle)
 {
@@ -124,9 +121,14 @@ void extcap_base_register_interface_ext(extcap_parameters * extcap,
     extcap->interfaces = g_list_append(extcap->interfaces, (gpointer) iface);
 }
 
-void extcap_base_set_util_info(extcap_parameters * extcap, const char * major, const char * minor, const char * release, const char * helppage)
+void extcap_base_set_util_info(extcap_parameters * extcap, const char * exename, const char * major, const char * minor, const char * release, const char * helppage)
 {
+    extcap->exename = g_path_get_basename(exename);
+
     g_assert(major);
+    if (!minor)
+        g_assert(!release);
+
     extcap->version = g_strdup_printf("%s%s%s%s%s",
         major,
         minor ? "." : "",
@@ -136,7 +138,22 @@ void extcap_base_set_util_info(extcap_parameters * extcap, const char * major, c
     extcap->helppage = g_strdup(helppage);
 }
 
-uint8_t extcap_base_parse_options(extcap_parameters * extcap, int result, char * optargument )
+static void extcap_custom_log(const gchar *log_domain,
+             GLogLevelFlags log_level,
+             const gchar *message,
+             gpointer user_data)
+{
+    if (log_level & G_LOG_LEVEL_DEBUG) {
+        if (!custom_log)
+            return;
+        fprintf(custom_log, "%s\n", message);
+        fflush(custom_log);
+    } else {
+        g_log_default_handler(log_domain, log_level, message, user_data);
+    }
+}
+
+uint8_t extcap_base_parse_options(extcap_parameters * extcap, int result, char * optargument)
 {
     switch (result) {
         case EXTCAP_OPT_DEBUG:
@@ -146,10 +163,15 @@ uint8_t extcap_base_parse_options(extcap_parameters * extcap, int result, char *
             setenv("G_MESSAGES_DEBUG", "all", 1);
 #endif
             break;
+        case EXTCAP_OPT_DEBUG_FILE:
+            extcap_init_custom_log(optargument);
+            g_log_set_default_handler(extcap_custom_log, NULL);
+            break;
         case EXTCAP_OPT_LIST_INTERFACES:
             extcap->do_list_interfaces = 1;
             break;
         case EXTCAP_OPT_VERSION:
+            extcap->ws_version = g_strdup(optargument);
             extcap->do_version = 1;
             break;
         case EXTCAP_OPT_LIST_DLTS:
@@ -257,28 +279,108 @@ static void extcap_iface_free(gpointer data)
     g_free(iface);
 }
 
+static void extcap_help_option_free(gpointer option)
+{
+    extcap_option_t* o = (extcap_option_t*)option;
+    g_free(o->optname);
+    g_free(o->optdesc);
+    g_free(o);
+}
+
 void extcap_base_cleanup(extcap_parameters ** extcap)
 {
-    /* g_list_free_full() only exists since 2.28. g_list_free_full((*extcap)->interfaces, extcap_iface_free);*/
-    g_list_foreach((*extcap)->interfaces, (GFunc)extcap_iface_free, NULL);
-    g_list_free((*extcap)->interfaces);
+    g_list_free_full((*extcap)->interfaces, extcap_iface_free);
+    g_free((*extcap)->exename);
     g_free((*extcap)->fifo);
     g_free((*extcap)->interface);
     g_free((*extcap)->version);
     g_free((*extcap)->helppage);
+    g_free((*extcap)->help_header);
+    g_free((*extcap)->ws_version);
+    g_list_free_full((*extcap)->help_options, extcap_help_option_free);
     g_free(*extcap);
     *extcap = NULL;
 }
 
+static void extcap_print_option(gpointer option, gpointer user_data _U_)
+{
+    extcap_option_t* o = (extcap_option_t*)option;
+    printf("\t%s: %s\n", o->optname, o->optdesc);
+}
+
+void extcap_help_print(extcap_parameters * extcap)
+{
+    printf("\nWireshark - %s v%s\n\n", extcap->exename, extcap->version);
+    printf("Usage:\n");
+    printf("%s", extcap->help_header);
+    printf("\n");
+    printf("Options:\n");
+    g_list_foreach(extcap->help_options, extcap_print_option, NULL);
+    printf("\n");
+}
+
+void extcap_help_add_option(extcap_parameters * extcap, const char * help_option_name, const char * help_option_desc)
+{
+    extcap_option_t* o = g_new0(extcap_option_t, 1);
+    o->optname = g_strdup(help_option_name);
+    o->optdesc = g_strdup(help_option_desc);
+
+    extcap->help_options = g_list_append(extcap->help_options, o);
+}
+
+void extcap_help_add_header(extcap_parameters * extcap, char * help_header)
+{
+    extcap->help_header = g_strdup(help_header);
+    extcap_help_add_option(extcap, "--extcap-interfaces", "list the extcap Interfaces");
+    extcap_help_add_option(extcap, "--extcap-dlts", "list the DLTs");
+    extcap_help_add_option(extcap, "--extcap-interface <iface>", "specify the extcap interface");
+    extcap_help_add_option(extcap, "--extcap-config", "list the additional configuration for an interface");
+    extcap_help_add_option(extcap, "--capture", "run the capture");
+    extcap_help_add_option(extcap, "--extcap-capture-filter <filter>", "the capture filter");
+    extcap_help_add_option(extcap, "--fifo <file>", "dump data to file or fifo");
+    extcap_help_add_option(extcap, "--extcap-version", "print tool version");
+    extcap_help_add_option(extcap, "--debug", "print additional messages");
+    extcap_help_add_option(extcap, "--debug-file", "print debug messages to file");
+}
+
+void extcap_init_custom_log(const char* filename)
+{
+    if (!filename || strlen(filename) == 0)
+        return;
+    custom_log = fopen(filename, "w");
+    if (!custom_log)
+        g_error("Can't open custom log file: %s (%s)", filename, strerror(errno));
+}
+
+void extcap_config_debug(unsigned* count)
+{
+    printf("arg {number=%u}{call=--debug}{display=Run in debug mode}"
+    "{type=boolean}{default=false}{tooltip=Print debug messages}{required=false}"
+    "{group=Debug}\n", (*count)++);
+    printf("arg {number=%u}{call=--debug-file}{display=Use a file for debug}"
+    "{type=string}{tooltip=Set a file where the debug messages are written}{required=false}"
+    "{group=Debug}\n", (*count)++);
+}
+
+void extcap_cmdline_debug(char** ar, const unsigned n)
+{
+    GString* cmdline = g_string_new("cmdline: ");
+    unsigned i;
+    for (i = 0; i < n; i++)
+        g_string_append_printf(cmdline, "%s ", ar[i]);
+    g_debug("%s", cmdline->str);
+    g_string_free(cmdline, TRUE);
+}
+
 /*
  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
  *
  * Local variables:
  * c-basic-offset: 4
- * tab-width: 8
- * indent-tabs-mode: t
+ * tab-width: 4
+ * indent-tabs-mode: nil
  * End:
  *
- * vi: set shiftwidth=4 tabstop=8 noexpandtab:
- * :indentSize=4:tabSize=8:noTabs=false:
+ * vi: set shiftwidth=4 tabstop=expandtab:
+ * :indentSize=4:tabSize=4:noTabs=true:
  */