epan: use json_dumper for json outputs.
[metze/wireshark/wip.git] / editcap.c
index ed11641071b256b877b7e76bbfcb8b0c2fdff65e..c0683aa68ccbd4d39bae9e7fa12e848b90c30a50 100644 (file)
--- a/editcap.c
+++ b/editcap.c
@@ -43,6 +43,7 @@
 #include <getopt.h>
 #endif
 
+#include <wiretap/secrets-types.h>
 #include <wiretap/wtap.h>
 
 #include "epan/etypes.h"
@@ -53,7 +54,6 @@
 #endif
 
 #ifdef _WIN32
-#include <wsutil/unicode-utils.h>
 #include <process.h>    /* getpid */
 #include <winsock2.h>
 #endif
@@ -62,9 +62,8 @@
 # include "wsutil/strptime.h"
 #endif
 
-#include <wsutil/crash_info.h>
-#include <wsutil/clopts_common.h>
-#include <wsutil/cmdarg_err.h>
+#include <ui/clopts_common.h>
+#include <ui/cmdarg_err.h>
 #include <wsutil/filesystem.h>
 #include <wsutil/file_util.h>
 #include <wsutil/wsgcrypt.h>
@@ -73,6 +72,7 @@
 #include <wsutil/report_message.h>
 #include <wsutil/strnatcmp.h>
 #include <wsutil/str_util.h>
+#include <cli_main.h>
 #include <version_info.h>
 #include <wsutil/pint.h>
 #include <wsutil/strtoi.h>
@@ -175,6 +175,13 @@ static int                    do_strict_time_adjustment = FALSE;
 static struct time_adjustment strict_time_adj           = {NSTIME_INIT_ZERO, 0}; /* strict time adjustment */
 static nstime_t               previous_time             = NSTIME_INIT_ZERO; /* previous time */
 
+static const struct {
+    const char *str;
+    guint32     id;
+} secrets_types[] = {
+    { "tls", SECRETS_TYPE_TLS },
+};
+
 static int find_dct2000_real_data(guint8 *buf);
 static void handle_chopping(chop_t chop, wtap_packet_header *out_phdr,
                             const wtap_packet_header *in_phdr, guint8 **buf,
@@ -819,8 +826,12 @@ print_usage(FILE *output)
     fprintf(output, "  -i <seconds per file>  split the packet output to different files based on\n");
     fprintf(output, "                         uniform time intervals with a maximum of\n");
     fprintf(output, "                         <seconds per file> each.\n");
-    fprintf(output, "  -F <capture type>      set the output file type; default is pcapng. An empty\n");
-    fprintf(output, "                         \"-F\" option will list the file types.\n");
+#ifdef PCAP_NG_DEFAULT
+    fprintf(output, "  -F <capture type>      set the output file type; default is pcapng.\n");
+#else
+    fprintf(output, "  -F <capture type>      set the output file type; default is pcap.\n");
+#endif
+    fprintf(output, "                         An empty \"-F\" option will list the file types.\n");
     fprintf(output, "  -T <encap type>        set the output file encapsulation type; default is the\n");
     fprintf(output, "                         same as the input file. An empty \"-T\" option will\n");
     fprintf(output, "                         list the encapsulation types.\n");
@@ -900,6 +911,25 @@ list_encap_types(FILE *stream) {
     g_free(encaps);
 }
 
+static void
+list_secrets_types(FILE *stream)
+{
+    for (guint i = 0; i < G_N_ELEMENTS(secrets_types); i++) {
+        fprintf(stream, "    %s\n", secrets_types[i].str);
+    }
+}
+
+static guint32
+lookup_secrets_type(const char *type)
+{
+    for (guint i = 0; i < G_N_ELEMENTS(secrets_types); i++) {
+        if (!strcmp(secrets_types[i].str, type)) {
+            return secrets_types[i].id;
+        }
+    }
+    return 0;
+}
+
 static int
 framenum_compare(gconstpointer a, gconstpointer b, gpointer user_data _U_)
 {
@@ -942,22 +972,18 @@ editcap_dump_open(const char *filename, const wtap_dump_params *params,
 
   if (strcmp(filename, "-") == 0) {
     /* Write to the standard output. */
-    pdh = wtap_dump_open_stdout(out_file_type_subtype,
-                                FALSE /* compressed */,
+    pdh = wtap_dump_open_stdout(out_file_type_subtype, WTAP_UNCOMPRESSED,
                                 params, write_err);
   } else {
-    pdh = wtap_dump_open(filename, out_file_type_subtype,
-                         FALSE /* compressed */,
+    pdh = wtap_dump_open(filename, out_file_type_subtype, WTAP_UNCOMPRESSED,
                          params, write_err);
   }
   return pdh;
 }
 
-static int
-real_main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
 {
-    GString      *comp_info_str;
-    GString      *runtime_info_str;
     char         *init_progfile_dir_error;
     wtap         *wth = NULL;
     int           i, j, read_err, write_err;
@@ -967,6 +993,7 @@ real_main(int argc, char *argv[])
         {"novlan", no_argument, NULL, 0x8100},
         {"skip-radiotap-header", no_argument, NULL, 0x8101},
         {"seed", required_argument, NULL, 0x8102},
+        {"inject-secrets", required_argument, NULL, 0x8103},
         {"help", no_argument, NULL, 'h'},
         {"version", no_argument, NULL, 'V'},
         {0, 0, 0, 0 }
@@ -994,6 +1021,8 @@ real_main(int argc, char *argv[])
     gchar        *fsuffix            = NULL;
     guint32       change_offset      = 0;
     guint         max_packet_number  = 0;
+    GArray       *dsb_types          = NULL;
+    GPtrArray    *dsb_filenames      = NULL;
     const wtap_rec              *rec;
     wtap_rec                     temp_rec;
     wtap_dump_params             params = WTAP_DUMP_PARAMS_INIT;
@@ -1010,21 +1039,8 @@ real_main(int argc, char *argv[])
     create_app_running_mutex();
 #endif /* _WIN32 */
 
-    /* Get the compile-time version information string */
-    comp_info_str = get_compiled_version_info(NULL, NULL);
-
-    /* Get the run-time version information string */
-    runtime_info_str = get_runtime_version_info(NULL);
-
-    /* Add it to the information to be reported on a crash. */
-    ws_add_crash_info("Editcap (Wireshark) %s\n"
-         "\n"
-         "%s"
-         "\n"
-         "%s",
-      get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
-    g_string_free(comp_info_str, TRUE);
-    g_string_free(runtime_info_str, TRUE);
+    /* Initialize the version information. */
+    ws_init_version_info("Editcap (Wireshark)", NULL, NULL, NULL);
 
     /*
      * Get credential information for later use.
@@ -1075,6 +1091,36 @@ real_main(int argc, char *argv[])
             break;
         }
 
+        case 0x8103: /* --inject-secrets */
+        {
+            guint32 secrets_type_id = 0;
+            const char *secrets_filename = NULL;
+            if (strcmp("help", optarg) == 0) {
+                list_secrets_types(stdout);
+                goto clean_exit;
+            }
+            gchar **splitted = g_strsplit(optarg, ",", 2);
+            if (splitted[0]) {
+                secrets_type_id = lookup_secrets_type(splitted[0]);
+                secrets_filename = splitted[1];
+            }
+
+            if (secrets_type_id == 0) {
+                fprintf(stderr, "editcap: \"%s\" isn't a valid secrets type\n", secrets_filename);
+                g_strfreev(splitted);
+                ret = INVALID_OPTION;
+                goto clean_exit;
+            }
+            if (!dsb_filenames) {
+                dsb_types = g_array_new(FALSE, FALSE, sizeof(guint32));
+                dsb_filenames = g_ptr_array_new_with_free_func(g_free);
+            }
+            g_array_append_val(dsb_types, secrets_type_id);
+            g_ptr_array_add(dsb_filenames, g_strdup(secrets_filename));
+            g_strfreev(splitted);
+            break;
+        }
+
         case 'a':
         {
             guint frame_number;
@@ -1216,10 +1262,7 @@ real_main(int argc, char *argv[])
             break;
 
         case 'h':
-            printf("Editcap (Wireshark) %s\n"
-                   "Edit and/or translate the format of capture files.\n"
-                   "See https://www.wireshark.org for more information.\n",
-               get_ws_vcs_version_info());
+            show_help_header("Edit and/or translate the format of capture files.");
             print_usage(stdout);
             goto clean_exit;
             break;
@@ -1279,11 +1322,7 @@ real_main(int argc, char *argv[])
             break;
 
         case 'V':
-            comp_info_str = get_compiled_version_info(NULL, NULL);
-            runtime_info_str = get_runtime_version_info(NULL);
-            show_version("Editcap (Wireshark)", comp_info_str, runtime_info_str);
-            g_string_free(comp_info_str, TRUE);
-            g_string_free(runtime_info_str, TRUE);
+            show_version();
             goto clean_exit;
             break;
 
@@ -1402,6 +1441,45 @@ real_main(int argc, char *argv[])
 
     wtap_dump_params_init(&params, wth);
 
+    if (dsb_filenames) {
+        for (guint k = 0; k < dsb_filenames->len; k++) {
+            guint32 secrets_type_id = g_array_index(dsb_types, guint32, k);
+            const char *secrets_filename = (const char *)g_ptr_array_index(dsb_filenames, k);
+            char *data;
+            gsize data_len;
+            wtap_block_t block;
+            wtapng_dsb_mandatory_t *dsb;
+            GError *err = NULL;
+
+            if (!g_file_get_contents(secrets_filename, &data, &data_len, &err)) {
+                fprintf(stderr, "editcap: \"%s\" could not be read: %s\n", secrets_filename, err->message);
+                g_clear_error(&err);
+                ret = INVALID_OPTION;
+                goto clean_exit;
+            }
+            if (data_len == 0) {
+                fprintf(stderr, "editcap: \"%s\" is an empty file, ignoring\n", secrets_filename);
+                g_free(data);
+                continue;
+            }
+            if (data_len >= G_MAXINT) {
+                fprintf(stderr, "editcap: \"%s\" is too large, ignoring\n", secrets_filename);
+                g_free(data);
+                continue;
+            }
+
+            block = wtap_block_create(WTAP_BLOCK_DSB);
+            dsb = (wtapng_dsb_mandatory_t *)wtap_block_get_mandatory_data(block);
+            dsb->secrets_type = secrets_type_id;
+            dsb->secrets_len = (guint)data_len;
+            dsb->secrets_data = data;
+            if (params.dsbs_initial == NULL) {
+                params.dsbs_initial = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
+            }
+            g_array_append_val(params.dsbs_initial, block);
+        }
+    }
+
     /*
      * If an encapsulation type was specified, override the encapsulation
      * type of the input file.
@@ -1459,9 +1537,9 @@ real_main(int argc, char *argv[])
             }
             g_assert(filename);
 
-            /* If we don't have an application name add Editcap */
+            /* If we don't have an application name add one */
             if (wtap_block_get_string_option_value(g_array_index(params.shb_hdrs, wtap_block_t, 0), OPT_SHB_USERAPPL, &shb_user_appl) != WTAP_OPTTYPE_SUCCESS) {
-                wtap_block_add_string_option_format(g_array_index(params.shb_hdrs, wtap_block_t, 0), OPT_SHB_USERAPPL, "Editcap " VERSION);
+                wtap_block_add_string_option_format(g_array_index(params.shb_hdrs, wtap_block_t, 0), OPT_SHB_USERAPPL, "%s", get_appname_and_version());
             }
 
             pdh = editcap_dump_open(filename, &params, &write_err);
@@ -1937,6 +2015,10 @@ real_main(int argc, char *argv[])
     }
 
 clean_exit:
+    if (dsb_filenames) {
+        g_array_free(dsb_types, TRUE);
+        g_ptr_array_free(dsb_filenames, TRUE);
+    }
     g_free(params.idb_inf);
     wtap_dump_params_cleanup(&params);
     if (wth != NULL)
@@ -1946,23 +2028,6 @@ clean_exit:
     return ret;
 }
 
-#ifdef _WIN32
-int
-wmain(int argc, wchar_t *wc_argv[])
-{
-    char **argv;
-
-    argv = arg_list_utf_16to8(argc, wc_argv);
-    return real_main(argc, argv);
-}
-#else
-int
-main(int argc, char *argv[])
-{
-    return real_main(argc, argv);
-}
-#endif
-
 /* Skip meta-information read from file to return offset of real
  * protocol data */
 static int