Generate randpkt_core/doxygen.cfg.
[metze/wireshark/wip.git] / editcap.c
index ab929c5eb78d9fb6e7b5f84886e93f62a50c4cdf..fdb80c8d09a3d3a398e76e79ae156cf67b91d57e 100644 (file)
--- a/editcap.c
+++ b/editcap.c
@@ -58,7 +58,9 @@
 #include <zlib.h>     /* to get the libz version number */
 #endif
 
-#include "wtap.h"
+#include <wiretap/wtap.h>
+
+#include "epan/etypes.h"
 
 #ifndef HAVE_GETOPT_LONG
 #include "wsutil/wsgetopt.h"
@@ -95,8 +97,8 @@
  */
 
 struct select_item {
-    int inclusive;
-    int first, second;
+    gboolean inclusive;
+    guint first, second;
 };
 
 /*
@@ -152,7 +154,7 @@ GTree *frames_user_comments = NULL;
 
 #define MAX_SELECTIONS 512
 static struct select_item     selectfrm[MAX_SELECTIONS];
-static int                    max_selected              = -1;
+static guint                  max_selected              = 0;
 static int                    keep_em                   = 0;
 #ifdef PCAP_NG_DEFAULT
 static int                    out_file_type_subtype     = WTAP_FILE_TYPE_SUBTYPE_PCAPNG; /* default to pcapng   */
@@ -167,6 +169,7 @@ static double                 err_prob                  = 0.0;
 static time_t                 starttime                 = 0;
 static time_t                 stoptime                  = 0;
 static gboolean               check_startstop           = FALSE;
+static gboolean               rem_vlan                  = FALSE;
 static gboolean               dup_detect                = FALSE;
 static gboolean               dup_detect_by_time        = FALSE;
 
@@ -262,12 +265,12 @@ fileset_extract_prefix_suffix(const char *fname, gchar **fprefix, gchar **fsuffi
 
 /* Add a selection item, a simple parser for now */
 static gboolean
-add_selection(char *sel)
+add_selection(char *sel, guint* max_selection)
 {
     char *locn;
     char *next;
 
-    if (++max_selected >= MAX_SELECTIONS) {
+    if (max_selected >= MAX_SELECTIONS) {
         /* Let the user know we stopped selecting */
         fprintf(stderr, "Out of room for packet selections!\n");
         return(FALSE);
@@ -280,8 +283,10 @@ add_selection(char *sel)
         if (verbose)
             fprintf(stderr, "Not inclusive ...");
 
-        selectfrm[max_selected].inclusive = 0;
-        selectfrm[max_selected].first = atoi(sel);
+        selectfrm[max_selected].inclusive = FALSE;
+        selectfrm[max_selected].first = (guint)strtoul(sel, NULL, 10);
+        if (selectfrm[max_selected].first < *max_selection)
+            *max_selection = selectfrm[max_selected].first;
 
         if (verbose)
             fprintf(stderr, " %i\n", selectfrm[max_selected].first);
@@ -290,26 +295,35 @@ add_selection(char *sel)
             fprintf(stderr, "Inclusive ...");
 
         next = locn + 1;
-        selectfrm[max_selected].inclusive = 1;
-        selectfrm[max_selected].first = atoi(sel);
-        selectfrm[max_selected].second = atoi(next);
+        selectfrm[max_selected].inclusive = TRUE;
+        selectfrm[max_selected].first = (guint)strtoul(sel, NULL, 10);
+        selectfrm[max_selected].second = (guint)strtoul(next, NULL, 10);
+
+        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)
+            *max_selection = selectfrm[max_selected].second;
 
         if (verbose)
             fprintf(stderr, " %i, %i\n", selectfrm[max_selected].first,
                    selectfrm[max_selected].second);
     }
 
+    max_selected++;
     return(TRUE);
 }
 
 /* Was the packet selected? */
 
 static int
-selected(int recno)
+selected(guint recno)
 {
-    int i;
+    guint i;
 
-    for (i = 0; i <= max_selected; i++) {
+    for (i = 0; i < max_selected; i++) {
         if (selectfrm[i].inclusive) {
             if (selectfrm[i].first <= recno && selectfrm[i].second >= recno)
                 return 1;
@@ -534,6 +548,34 @@ set_rel_time(char *optarg_str_p)
     relative_time_window.nsecs = (int)val;
 }
 
+#define LINUX_SLL_OFFSETP 14
+#define VLAN_SIZE 4
+static void
+sll_remove_vlan_info(guint8* fd, guint32* len) {
+    if (g_ntohs(*(fd + LINUX_SLL_OFFSETP)) == ETHERTYPE_VLAN) {
+        int rest_len;
+        /* point to start of vlan */
+        fd = fd + LINUX_SLL_OFFSETP;
+        /* bytes to read after vlan info */
+        rest_len = *len - (LINUX_SLL_OFFSETP + VLAN_SIZE);
+        /* remove vlan info from packet */
+        memmove(fd, fd + VLAN_SIZE, rest_len);
+        *len -= 4;
+    }
+}
+
+static void
+remove_vlan_info(const struct wtap_pkthdr *phdr, guint8* fd, guint32* len) {
+    switch (phdr->pkt_encap) {
+        case WTAP_ENCAP_SLL:
+            sll_remove_vlan_info(fd, len);
+            break;
+        default:
+            /* no support for current pkt_encap */
+            break;
+    }
+}
+
 static gboolean
 is_duplicate(guint8* fd, guint32 len) {
     int i;
@@ -699,6 +741,7 @@ 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, "  -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, "                         Valid <dup window> values are 0 to %d.\n", MAX_DUP_DEPTH);
@@ -748,8 +791,8 @@ print_usage(FILE *output)
     fprintf(output, "                         all packets to the timestamp of the first packet.\n");
     fprintf(output, "  -E <error probability> set the probability (between 0.0 and 1.0 incl.) that\n");
     fprintf(output, "                         a particular packet byte will be randomly changed.\n");
-    fprintf(output, "  -o <change offset>     When used in conjuction with -E, skip some bytes from the\n");
-    fprintf(output, "                         beginning of the packet. This allows to preserve some\n");
+    fprintf(output, "  -o <change offset>     When used in conjunction with -E, skip some bytes from the\n");
+    fprintf(output, "                         beginning of the packet. This allows one to preserve some\n");
     fprintf(output, "                         bytes, in order to have some headers untouched.\n");
     fprintf(output, "\n");
     fprintf(output, "Output File(s):\n");
@@ -841,14 +884,17 @@ list_encap_types(void) {
     g_free(encaps);
 }
 
-/* TODO: is there the equivalent of g_direct_equal? */
 static int
-framenum_equal(gconstpointer a, gconstpointer b, gpointer user_data _U_)
+framenum_compare(gconstpointer a, gconstpointer b, gpointer user_data _U_)
 {
-    return (a != b);
-}
+    if (GPOINTER_TO_UINT(a) < GPOINTER_TO_UINT(b))
+        return -1;
 
+    if (GPOINTER_TO_UINT(a) > GPOINTER_TO_UINT(b))
+        return 1;
 
+    return 0;
+}
 
 #ifdef HAVE_PLUGINS
 /*
@@ -920,13 +966,12 @@ main(int argc, char *argv[])
     int           i, j, read_err, write_err;
     gchar        *read_err_info, *write_err_info;
     int           opt;
-DIAG_OFF(cast-qual)
     static const struct option long_options[] = {
-        {(char *)"help", no_argument, NULL, 'h'},
-        {(char *)"version", no_argument, NULL, 'V'},
+        {"novlan", no_argument, NULL, 0x8100},
+        {"help", no_argument, NULL, 'h'},
+        {"version", no_argument, NULL, 'V'},
         {0, 0, 0, 0 }
     };
-DIAG_ON(cast-qual)
 
     char         *p;
     guint32       snaplen            = 0; /* No limit               */
@@ -949,7 +994,7 @@ DIAG_ON(cast-qual)
     gchar        *fprefix            = NULL;
     gchar        *fsuffix            = NULL;
     guint32       change_offset      = 0;
-
+    guint         max_packet_number  = G_MAXUINT;
     const struct wtap_pkthdr    *phdr;
     struct wtap_pkthdr           temp_phdr;
     wtapng_iface_descriptions_t *idb_inf = NULL;
@@ -987,7 +1032,7 @@ DIAG_ON(cast-qual)
 
 #ifdef HAVE_PLUGINS
     /* Register wiretap plugins */
-    if ((init_progfile_dir_error = init_progfile_dir(argv[0], (void *)main))) {
+    if ((init_progfile_dir_error = init_progfile_dir(argv[0], main))) {
         g_warning("editcap: init_progfile_dir(): %s", init_progfile_dir_error);
         g_free(init_progfile_dir_error);
     } else {
@@ -1008,6 +1053,12 @@ DIAG_ON(cast-qual)
     /* Process the options */
     while ((opt = getopt_long(argc, argv, "a:A:B:c:C:dD:E:F:hi:I:Lo:rs:S:t:T:vVw:", long_options, NULL)) != -1) {
         switch (opt) {
+        case 0x8100:
+        {
+            rem_vlan = TRUE;
+            break;
+        }
+
         case 'a':
         {
             guint frame_number;
@@ -1021,7 +1072,7 @@ DIAG_ON(cast-qual)
 
             /* Lazily create the table */
             if (!frames_user_comments) {
-                frames_user_comments = g_tree_new_full(framenum_equal, NULL, NULL, g_free);
+                frames_user_comments = g_tree_new_full(framenum_compare, NULL, NULL, g_free);
             }
 
             /* Insert this entry (framenum -> comment) */
@@ -1160,7 +1211,7 @@ DIAG_ON(cast-qual)
         case 'h':
             printf("Editcap (Wireshark) %s\n"
                    "Edit and/or translate the format of capture files.\n"
-                   "See http://www.wireshark.org for more information.\n",
+                   "See https://www.wireshark.org for more information.\n",
                get_ws_vcs_version_info());
             print_usage(stdout);
             exit(0);
@@ -1323,9 +1374,12 @@ DIAG_ON(cast-qual)
             out_frame_type = wtap_file_encap(wth);
 
         for (i = optind + 2; i < argc; i++)
-            if (add_selection(argv[i]) == FALSE)
+            if (add_selection(argv[i], &max_packet_number) == FALSE)
                 break;
 
+        if (keep_em == FALSE)
+            max_packet_number = G_MAXUINT;
+
         if (dup_detect || dup_detect_by_time) {
             for (i = 0; i < dup_window; i++) {
                 memset(&fd_hash[i].digest, 0, 16);
@@ -1336,6 +1390,9 @@ DIAG_ON(cast-qual)
 
         /* Read all of the packets in turn */
         while (wtap_read(wth, &read_err, &read_err_info, &data_offset)) {
+            if (max_packet_number <= read_count)
+                break;
+
             read_count++;
 
             phdr = wtap_phdr(wth);
@@ -1377,8 +1434,7 @@ DIAG_ON(cast-qual)
              */
             if (phdr->presence_flags & WTAP_HAS_TS) {
                 if (nstime_is_unset(&block_start)) {
-                    block_start.secs = phdr->ts.secs;
-                    block_start.nsecs = phdr->ts.nsecs;
+                    block_start = phdr->ts;
                 }
 
                 if (secs_per_block > 0) {
@@ -1498,8 +1554,7 @@ DIAG_ON(cast-qual)
                                 nstime_t current;
                                 nstime_t delta;
 
-                                current.secs = phdr->ts.secs;
-                                current.nsecs = phdr->ts.nsecs;
+                                current = phdr->ts;
 
                                 nstime_delta(&delta, &current, &previous_time);
 
@@ -1543,13 +1598,10 @@ DIAG_ON(cast-qual)
                                 phdr = &temp_phdr;
                             }
                         }
-                        previous_time.secs = phdr->ts.secs;
-                        previous_time.nsecs = phdr->ts.nsecs;
+                        previous_time = phdr->ts;
                     }
 
-                    /* assume that if the frame's tv_sec is 0, then
-                     * the timestamp isn't supported */
-                    if (phdr->ts.secs > 0 && time_adj.tv.secs != 0) {
+                    if (time_adj.tv.secs != 0) {
                         temp_phdr = *phdr;
                         if (time_adj.is_negative)
                             temp_phdr.ts.secs -= time_adj.tv.secs;
@@ -1558,9 +1610,7 @@ DIAG_ON(cast-qual)
                         phdr = &temp_phdr;
                     }
 
-                    /* assume that if the frame's tv_sec is 0, then
-                     * the timestamp isn't supported */
-                    if (phdr->ts.secs > 0 && time_adj.tv.nsecs != 0) {
+                    if (time_adj.tv.nsecs != 0) {
                         temp_phdr = *phdr;
                         if (time_adj.is_negative) { /* subtract */
                             if (temp_phdr.ts.nsecs < time_adj.tv.nsecs) { /* borrow */
@@ -1581,6 +1631,12 @@ DIAG_ON(cast-qual)
                     }
                 } /* time stamp adjustment */
 
+                /* remove vlan info */
+                if (rem_vlan) {
+                    /* TODO: keep casting const like this? change pointer instead of value? */
+                    remove_vlan_info(phdr, buf, (guint32 *) &phdr->caplen);
+                }
+
                 /* suppress duplicates by packet window */
                 if (dup_detect) {
                     if (is_duplicate(buf, phdr->caplen)) {