Color filters: Initialize a variable.
[metze/wireshark/wip.git] / editcap.c
index a67e6ae747eedf6222f8519e74b24374b4f94881..40a6a81746c57d445998dff875dc1085489ce3f7 100644 (file)
--- a/editcap.c
+++ b/editcap.c
@@ -1,4 +1,5 @@
-/* Edit capture files.  We can delete packets, adjust timestamps, or
+/* editcap.c
+ * Edit capture files.  We can delete packets, adjust timestamps, or
  * simply convert from one format to another format.
  *
  * Originally written by Richard Sharpe.
@@ -75,6 +76,8 @@
 #endif
 
 #include <wsutil/crash_info.h>
+#include <wsutil/clopts_common.h>
+#include <wsutil/cmdarg_err.h>
 #include <wsutil/filesystem.h>
 #include <wsutil/file_util.h>
 #include <wsutil/md5.h>
@@ -85,6 +88,7 @@
 #include <wsutil/str_util.h>
 #include <ws_version_info.h>
 #include <wsutil/pint.h>
+#include <wsutil/strtoi.h>
 #include <wiretap/wtap_opttypes.h>
 #include <wiretap/pcapng.h>
 
@@ -115,7 +119,7 @@ static fd_hash_t fd_hash[MAX_DUP_DEPTH];
 static int       dup_window    = DEFAULT_DUP_DEPTH;
 static int       cur_dup_entry = 0;
 
-static int       ignored_bytes  = 0;  /* Used with -I */
+static guint32   ignored_bytes  = 0;  /* Used with -I */
 
 #define ONE_BILLION 1000000000
 
@@ -282,31 +286,31 @@ add_selection(char *sel, guint* max_selection)
             fprintf(stderr, "Not inclusive ...");
 
         selectfrm[max_selected].inclusive = FALSE;
-        selectfrm[max_selected].first = (guint)strtoul(sel, NULL, 10);
-        if (selectfrm[max_selected].first < *max_selection)
+        selectfrm[max_selected].first = get_guint32(sel, "packet number");
+        if (selectfrm[max_selected].first > *max_selection)
             *max_selection = selectfrm[max_selected].first;
 
         if (verbose)
-            fprintf(stderr, " %i\n", selectfrm[max_selected].first);
+            fprintf(stderr, " %u\n", selectfrm[max_selected].first);
     } else {
         if (verbose)
             fprintf(stderr, "Inclusive ...");
 
         next = locn + 1;
         selectfrm[max_selected].inclusive = TRUE;
-        selectfrm[max_selected].first = (guint)strtoul(sel, NULL, 10);
-        selectfrm[max_selected].second = (guint)strtoul(next, NULL, 10);
+        selectfrm[max_selected].first = get_guint32(sel, "beginning of packet range");
+        selectfrm[max_selected].second = get_guint32(next, "end of packet range");
 
         if (selectfrm[max_selected].second == 0)
         {
             /* Not a valid number, presume all */
             selectfrm[max_selected].second = *max_selection = G_MAXUINT;
         }
-        else if (selectfrm[max_selected].second < *max_selection)
+        else if (selectfrm[max_selected].second > *max_selection)
             *max_selection = selectfrm[max_selected].second;
 
         if (verbose)
-            fprintf(stderr, " %i, %i\n", selectfrm[max_selected].first,
+            fprintf(stderr, " %u, %u\n", selectfrm[max_selected].first,
                    selectfrm[max_selected].second);
     }
 
@@ -736,9 +740,9 @@ print_usage(FILE *output)
     fprintf(output, "                         given time (format as YYYY-MM-DD hh:mm:ss).\n");
     fprintf(output, "\n");
     fprintf(output, "Duplicate packet removal:\n");
-    fprintf(output, "  --novlan                remove vlan info from packets before checking for duplicates.\n");
+    fprintf(output, "  --novlan               remove vlan info from packets before checking for duplicates.\n");
     fprintf(output, "  -d                     remove packet if duplicate (window == %d).\n", DEFAULT_DUP_DEPTH);
-    fprintf(output, "  -D <dup window>        remove packet if duplicate; configurable <dup window>\n");
+    fprintf(output, "  -D <dup window>        remove packet if duplicate; configurable <dup window>.\n");
     fprintf(output, "                         Valid <dup window> values are 0 to %d.\n", MAX_DUP_DEPTH);
     fprintf(output, "                         NOTE: A <dup window> of 0 with -v (verbose option) is\n");
     fprintf(output, "                         useful to print MD5 hashes.\n");
@@ -746,14 +750,14 @@ print_usage(FILE *output)
     fprintf(output, "                         LESS THAN <dup time window> prior to current packet.\n");
     fprintf(output, "                         A <dup time window> is specified in relative seconds\n");
     fprintf(output, "                         (e.g. 0.000001).\n");
-    fprintf(output, "  -a <framenum>:<comment>  Add or replace comment for given frame number\n");
+    fprintf(output, "  -a <framenum>:<comment> Add or replace comment for given frame number\n");
     fprintf(output, "\n");
     fprintf(output, "  -I <bytes to ignore>   ignore the specified bytes at the beginning of\n");
-    fprintf(output, "                         the frame during MD5 hash calculation\n");
+    fprintf(output, "                         the frame during MD5 hash calculation.\n");
     fprintf(output, "                         Useful to remove duplicated packets taken on\n");
-    fprintf(output, "                         several routers(differents mac addresses for \n");
-    fprintf(output, "                         example)\n");
-    fprintf(output, "                         e.g. -I 26 in case of Ether/IP/ will ignore \n");
+    fprintf(output, "                         several routers (different mac addresses for\n");
+    fprintf(output, "                         example).\n");
+    fprintf(output, "                         e.g. -I 26 in case of Ether/IP will ignore\n");
     fprintf(output, "                         ether(14) and IP header(20 - 4(src ip) - 4(dst ip)).\n");
     fprintf(output, "\n");
     fprintf(output, "           NOTE: The use of the 'Duplicate packet removal' options with\n");
@@ -773,10 +777,10 @@ print_usage(FILE *output)
     fprintf(output, "                         regions within a packet provided that at least 1\n");
     fprintf(output, "                         choplen is positive and at least 1 is negative.\n");
     fprintf(output, "  -L                     adjust the frame (i.e. reported) length when chopping\n");
-    fprintf(output, "                         and/or snapping\n");
-    fprintf(output, "  -t <time adjustment>   adjust the timestamp of each packet;\n");
+    fprintf(output, "                         and/or snapping.\n");
+    fprintf(output, "  -t <time adjustment>   adjust the timestamp of each packet.\n");
     fprintf(output, "                         <time adjustment> is in relative seconds (e.g. -0.5).\n");
-    fprintf(output, "  -S <strict adjustment> adjust timestamp of packets if necessary to insure\n");
+    fprintf(output, "  -S <strict adjustment> adjust timestamp of packets if necessary to ensure\n");
     fprintf(output, "                         strict chronological increasing order. The <strict\n");
     fprintf(output, "                         adjustment> is specified in relative seconds with\n");
     fprintf(output, "                         values of 0 or 0.000001 being the most reasonable.\n");
@@ -891,23 +895,32 @@ framenum_compare(gconstpointer a, gconstpointer b, gpointer user_data _U_)
     return 0;
 }
 
-#ifdef HAVE_PLUGINS
 /*
- *  Don't report failures to load plugins because most (non-wiretap) plugins
- *  *should* fail to load (because we're not linked against libwireshark and
- *  dissector plugins need libwireshark).
+ * General errors are reported with an console message in editcap.
  */
 static void
-failure_message(const char *msg_format _U_, va_list ap _U_)
+failure_message(const char *msg_format, va_list ap)
 {
+  fprintf(stderr, "editcap: ");
+  vfprintf(stderr, msg_format, ap);
+  fprintf(stderr, "\n");
+}
+
+/*
+ * Report additional information for an error in command-line arguments.
+ */
+static void
+failure_message_cont(const char *msg_format, va_list ap)
+{
+    vfprintf(stderr, msg_format, ap);
+    fprintf(stderr, "\n");
 }
-#endif
 
 static wtap_dumper *
 editcap_dump_open(const char *filename, guint32 snaplen,
-                  wtap_optionblock_t shb_hdr,
+                  GArray* shb_hdrs,
                   wtapng_iface_descriptions_t *idb_inf,
-                  wtap_optionblock_t nrb_hdr, int *write_err)
+                  GArray* nrb_hdrs, int *write_err)
 {
   wtap_dumper *pdh;
 
@@ -915,13 +928,11 @@ editcap_dump_open(const char *filename, guint32 snaplen,
     /* Write to the standard output. */
     pdh = wtap_dump_open_stdout_ng(out_file_type_subtype, out_frame_type,
                                    snaplen, FALSE /* compressed */,
-                                   shb_hdr, idb_inf, nrb_hdr,
-                                   write_err);
+                                   shb_hdrs, idb_inf, nrb_hdrs, write_err);
   } else {
     pdh = wtap_dump_open_ng(filename, out_file_type_subtype, out_frame_type,
                             snaplen, FALSE /* compressed */,
-                            shb_hdr, idb_inf, nrb_hdr,
-                           write_err);
+                            shb_hdrs, idb_inf, nrb_hdrs, write_err);
   }
   return pdh;
 }
@@ -953,28 +964,30 @@ main(int argc, char *argv[])
     int           err_type;
     guint8       *buf;
     guint32       read_count         = 0;
-    int           split_packet_count = 0;
+    guint32       split_packet_count = 0;
     int           written_count      = 0;
     char         *filename           = NULL;
     gboolean      ts_okay;
-    int           secs_per_block     = 0;
+    guint32       secs_per_block     = 0;
     int           block_cnt          = 0;
     nstime_t      block_start;
     gchar        *fprefix            = NULL;
     gchar        *fsuffix            = NULL;
     guint32       change_offset      = 0;
-    guint         max_packet_number  = G_MAXUINT;
+    guint         max_packet_number  = 0;
     const struct wtap_pkthdr    *phdr;
     struct wtap_pkthdr           temp_phdr;
     wtapng_iface_descriptions_t *idb_inf = NULL;
-    wtap_optionblock_t           shb_hdr = NULL;
-    wtap_optionblock_t           nrb_hdr = NULL;
+    GArray                      *shb_hdrs = NULL;
+    GArray                      *nrb_hdrs = NULL;
     char                        *shb_user_appl;
 
 #ifdef HAVE_PLUGINS
     char* init_progfile_dir_error;
 #endif
 
+    cmdarg_err_init(failure_message, failure_message_cont);
+
 #ifdef _WIN32
     arg_list_utf_16to8(argc, argv);
     create_app_running_mutex();
@@ -993,6 +1006,8 @@ main(int argc, char *argv[])
          "\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);
 
     /*
      * Get credential information for later use.
@@ -1012,8 +1027,12 @@ main(int argc, char *argv[])
         init_report_err(failure_message,NULL,NULL,NULL);
 
         /* Scan for plugins.  This does *not* call their registration routines;
-           that's done later. */
-        scan_plugins();
+           that's done later.
+
+           Don't report failures to load plugins because most (non-wiretap)
+           plugins *should* fail to load (because we're not linked against
+           libwireshark and dissector plugins need libwireshark). */
+        scan_plugins(DONT_REPORT_LOAD_FAILURE);
 
         /* Register all libwiretap plugin modules. */
         register_all_wiretap_modules();
@@ -1087,17 +1106,7 @@ main(int argc, char *argv[])
         }
 
         case 'c':
-            split_packet_count = (int)strtol(optarg, &p, 10);
-            if (p == optarg || *p != '\0') {
-                fprintf(stderr, "editcap: \"%s\" isn't a valid packet count\n",
-                        optarg);
-                exit(1);
-            }
-            if (split_packet_count <= 0) {
-                fprintf(stderr, "editcap: \"%d\" packet count must be larger than zero\n",
-                        split_packet_count);
-                exit(1);
-            }
+            split_packet_count = get_nonzero_guint32(optarg, "packet count");
             break;
 
         case 'C':
@@ -1145,13 +1154,8 @@ main(int argc, char *argv[])
         case 'D':
             dup_detect = TRUE;
             dup_detect_by_time = FALSE;
-            dup_window = (int)strtol(optarg, &p, 10);
-            if (p == optarg || *p != '\0') {
-                fprintf(stderr, "editcap: \"%s\" isn't a valid duplicate window value\n",
-                        optarg);
-                exit(1);
-            }
-            if (dup_window < 0 || dup_window > MAX_DUP_DEPTH) {
+            dup_window = get_guint32(optarg, "duplicate window");
+            if (dup_window > MAX_DUP_DEPTH) {
                 fprintf(stderr, "editcap: \"%d\" duplicate window value must be between 0 and %d inclusive.\n",
                         dup_window, MAX_DUP_DEPTH);
                 exit(1);
@@ -1188,20 +1192,11 @@ main(int argc, char *argv[])
             break;
 
         case 'i': /* break capture file based on time interval */
-            secs_per_block = atoi(optarg);
-            if (secs_per_block <= 0) {
-                fprintf(stderr, "editcap: \"%s\" isn't a valid time interval\n\n",
-                        optarg);
-                exit(1);
-            }
+            secs_per_block = get_nonzero_guint32(optarg, "time interval");
             break;
 
         case 'I': /* ignored_bytes at the beginning of the frame for duplications removal */
-            ignored_bytes = atoi(optarg);
-            if(ignored_bytes <= 0) {
-                fprintf(stderr, "editcap: \"%s\" isn't a valid number of bytes to ignore\n", optarg);
-                exit(1);
-            }
+            ignored_bytes = get_guint32(optarg, "number of bytes to ignore");
             break;
 
         case 'L':
@@ -1209,7 +1204,7 @@ main(int argc, char *argv[])
             break;
 
         case 'o':
-            change_offset = (guint32)strtol(optarg, &p, 10);
+            change_offset = get_guint32(optarg, "change offset");
             break;
 
         case 'r':
@@ -1217,12 +1212,7 @@ main(int argc, char *argv[])
             break;
 
         case 's':
-            snaplen = (guint32)strtol(optarg, &p, 10);
-            if (p == optarg || *p != '\0') {
-                fprintf(stderr, "editcap: \"%s\" isn't a valid snapshot length\n",
-                        optarg);
-                exit(1);
-            }
+            snaplen = get_nonzero_guint32(optarg, "snapshot length");
             break;
 
         case 'S':
@@ -1249,6 +1239,8 @@ 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);
@@ -1307,7 +1299,7 @@ main(int argc, char *argv[])
         exit(1);
     }
 
-    if (split_packet_count > 0 && secs_per_block > 0) {
+    if (split_packet_count != 0 && secs_per_block != 0) {
         fprintf(stderr, "editcap: can't split on both packet count and time interval\n");
         fprintf(stderr, "editcap: at the same time\n");
         exit(1);
@@ -1330,9 +1322,9 @@ main(int argc, char *argv[])
                 wtap_file_type_subtype_string(wtap_file_type_subtype(wth)));
     }
 
-    shb_hdr = wtap_file_get_shb_for_new_file(wth);
+    shb_hdrs = wtap_file_get_shb_for_new_file(wth);
     idb_inf = wtap_file_get_idb_info(wth);
-    nrb_hdr = wtap_file_get_nrb_for_new_file(wth);
+    nrb_hdrs = wtap_file_get_nrb_for_new_file(wth);
 
     /*
      * Now, process the rest, if any ... we only write if there is an extra
@@ -1369,7 +1361,7 @@ main(int argc, char *argv[])
 
             /* Extra actions for the first packet */
             if (read_count == 1) {
-                if (split_packet_count > 0 || secs_per_block > 0) {
+                if (split_packet_count != 0 || secs_per_block != 0) {
                     if (!fileset_extract_prefix_suffix(argv[optind+1], &fprefix, &fsuffix))
                         goto error_on_exit;
 
@@ -1380,14 +1372,13 @@ main(int argc, char *argv[])
                 g_assert(filename);
 
                 /* If we don't have an application name add Editcap */
-                wtap_optionblock_get_option_string(shb_hdr, OPT_SHB_USERAPPL, &shb_user_appl);
-                if (shb_user_appl == NULL) {
-                    wtap_optionblock_set_option_string_format(shb_hdr, OPT_SHB_USERAPPL, "Editcap " VERSION);
+                if (wtap_block_get_string_option_value(g_array_index(shb_hdrs, wtap_block_t, 0), OPT_SHB_USERAPPL, &shb_user_appl) != WTAP_OPTTYPE_SUCCESS) {
+                    wtap_block_add_string_option_format(g_array_index(shb_hdrs, wtap_block_t, 0), OPT_SHB_USERAPPL, "Editcap " VERSION);
                 }
 
                 pdh = editcap_dump_open(filename,
                                         snaplen ? MIN(snaplen, wtap_snapshot_length(wth)) : wtap_snapshot_length(wth),
-                                        shb_hdr, idb_inf, nrb_hdr, &write_err);
+                                        shb_hdrs, idb_inf, nrb_hdrs, &write_err);
 
                 if (pdh == NULL) {
                     fprintf(stderr, "editcap: Can't open or create %s: %s\n",
@@ -1407,10 +1398,9 @@ main(int argc, char *argv[])
                 if (nstime_is_unset(&block_start)) {
                     block_start = phdr->ts;
                 }
-
-                if (secs_per_block > 0) {
-                    while ((phdr->ts.secs - block_start.secs >  secs_per_block)
-                           || (phdr->ts.secs - block_start.secs == secs_per_block
+                if (secs_per_block != 0) {
+                    while (((guint32)(phdr->ts.secs - block_start.secs) >  secs_per_block)
+                           || ((guint32)(phdr->ts.secs - block_start.secs) == secs_per_block
                                && phdr->ts.nsecs >= block_start.nsecs )) { /* time for the next file */
 
                         if (!wtap_dump_close(pdh, &write_err)) {
@@ -1428,7 +1418,7 @@ main(int argc, char *argv[])
 
                         pdh = editcap_dump_open(filename,
                                                 snaplen ? MIN(snaplen, wtap_snapshot_length(wth)) : wtap_snapshot_length(wth),
-                                                shb_hdr, idb_inf, nrb_hdr, &write_err);
+                                                shb_hdrs, idb_inf, nrb_hdrs, &write_err);
 
                         if (pdh == NULL) {
                             fprintf(stderr, "editcap: Can't open or create %s: %s\n",
@@ -1439,9 +1429,9 @@ main(int argc, char *argv[])
                 }
             }  /* time stamp handling */
 
-            if (split_packet_count > 0) {
+            if (split_packet_count != 0) {
                 /* time for the next file? */
-                if (written_count > 0 && written_count % split_packet_count == 0) {
+                if (written_count > 0 && (written_count % split_packet_count) == 0) {
                     if (!wtap_dump_close(pdh, &write_err)) {
                         fprintf(stderr, "editcap: Error writing to %s: %s\n",
                                 filename, wtap_strerror(write_err));
@@ -1457,7 +1447,7 @@ main(int argc, char *argv[])
 
                     pdh = editcap_dump_open(filename,
                                             snaplen ? MIN(snaplen, wtap_snapshot_length(wth)) : wtap_snapshot_length(wth),
-                                            shb_hdr, idb_inf, nrb_hdr, &write_err);
+                                            shb_hdrs, idb_inf, nrb_hdrs, &write_err);
                     if (pdh == NULL) {
                         fprintf(stderr, "editcap: Can't open or create %s: %s\n",
                                 filename, wtap_strerror(write_err));
@@ -1828,7 +1818,7 @@ main(int argc, char *argv[])
 
             pdh = editcap_dump_open(filename,
                                     snaplen ? MIN(snaplen, wtap_snapshot_length(wth)): wtap_snapshot_length(wth),
-                                    shb_hdr, idb_inf, nrb_hdr, &write_err);
+                                    shb_hdrs, idb_inf, nrb_hdrs, &write_err);
             if (pdh == NULL) {
                 fprintf(stderr, "editcap: Can't open or create %s: %s\n",
                         filename, wtap_strerror(write_err));
@@ -1836,18 +1826,11 @@ main(int argc, char *argv[])
             }
         }
 
-        g_free(idb_inf);
-        idb_inf = NULL;
-
         if (!wtap_dump_close(pdh, &write_err)) {
             fprintf(stderr, "editcap: Error writing to %s: %s\n", filename,
                     wtap_strerror(write_err));
             goto error_on_exit;
         }
-        wtap_optionblock_free(shb_hdr);
-        shb_hdr = NULL;
-        wtap_optionblock_free(nrb_hdr);
-        nrb_hdr = NULL;
         g_free(filename);
 
         if (frames_user_comments) {
@@ -1867,11 +1850,16 @@ main(int argc, char *argv[])
                 (long int)relative_time_window.nsecs);
     }
 
+    wtap_block_array_free(shb_hdrs);
+    wtap_block_array_free(nrb_hdrs);
+    g_free(idb_inf);
+    wtap_close(wth);
+
     return 0;
 
 error_on_exit:
-    wtap_optionblock_free(shb_hdr);
-    wtap_optionblock_free(nrb_hdr);
+    wtap_block_array_free(shb_hdrs);
+    wtap_block_array_free(nrb_hdrs);
     g_free(idb_inf);
     exit(2);
 }