Fix the "crossed chopping region" problem. Also, move chopping to its own function...
authorcmaynard <cmaynard@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 9 Sep 2013 19:39:45 +0000 (19:39 +0000)
committercmaynard <cmaynard@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 9 Sep 2013 19:39:45 +0000 (19:39 +0000)
Lastly, try to improve the documentation a bit concerning chopping and provide another example depicting 2 separate chopping regions.  *Maybe* this is clearer?

One more example here for posterity:  Given the following 75 byte packet, there
are 8 different ways to chop the 2 regions marked as 10 and 20 in a single pass:

    <--------------------------- 75 ---------------------------->

    +---+-------+-----------+---------------+-------------------+
    | 5 |   10  |     15    |       20      |         25        |
    +---+-------+-----------+---------------+-------------------+

1) editcap -C 5:10 -C -25:-20 in.pcap out.pcap
2) editcap -C 5:10 -C 50:-20 in.pcap out.pcap
3) editcap -C -70:10 -C -25:-20 in.pcap out.pcap
4) editcap -C -70:10 -C 50:-20 in.pcap out.pcap
5) editcap -C 30:20 -C -60:-10 in.pcap out.pcap
6) editcap -C 30:20 -C 15:-10 in.pcap out.pcap
7) editcap -C -45:20 -C -60:-10 in.pcap out.pcap
8) editcap -C -45:20 -C 15:-10 in.pcap out.pcap

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@51886 f5534014-38df-0310-8fa8-9805f1628bb7

doc/editcap.pod
editcap.c

index fda1228558f7f655331d638af54f91909793cf72..abeacb87f0888d7d93b7e7780203e788ba718d9b 100644 (file)
@@ -105,8 +105,10 @@ file formats leaves some random bytes at the end of each packet. Another use is
 for removing vlan tags.
 
 NOTE: This option can be used more than once, effectively allowing you to chop
-bytes from the beginning of a packet as well as from the end of a packet in a
-single step.
+bytes from two different areas of a packet in a single pass provided that
+you specify at least one chop length as a postive value and at least one as a
+negative value.  All positive chop lengths are added together as are all
+negative chop lengths.
 
 =item -d
 
@@ -189,7 +191,7 @@ packets were used).
 
 =item -S  E<lt>strict time adjustmentE<gt>
 
-Time adjust selected packets to insure strict chronological order.
+Time adjust selected packets to ensure strict chronological order.
 
 The <strict time adjustment> value represents relative seconds
 specified as [-]I<seconds>[I<.fractional seconds>].
@@ -205,7 +207,7 @@ will adjusted.  The adjusted timestamp value will be set to be
 equal to the timestamp value of the previous packet plus the value
 of the <strict time adjustment> value.  A <strict time adjustment>
 value of 0 will adjust the minimum number of timestamp values
-necessary to insure that the resulting capture file is in
+necessary to ensure that the resulting capture file is in
 strict chronological order.
 
 If <strict time adjustment> value is specified as a
@@ -344,7 +346,7 @@ To advance the timestamps of each packet forward by 3.0827 seconds:
 
     editcap -t 3.0827 capture.pcap adjusted.pcap
 
-To insure all timestamps are in strict chronological order:
+To ensure all timestamps are in strict chronological order:
 
     editcap -S 0 capture.pcap adjusted.pcap
 
@@ -352,10 +354,16 @@ To introduce 5% random errors in a capture file use:
 
     editcap -E 0.05 capture.pcap capture_error.pcap
 
-To remove vlan tags from an Ethernet-encapsulated capture file use:
+To remove vlan tags from all packets within an Ethernet-encapsulated capture
+file, use:
 
     editcap -L -C 12:4 capture_vlan.pcap capture_no_vlan.pcap
 
+To remove the IP header as well as the last 4 bytes from all packets within an
+Ethernet-encapsulated capture file, use:
+
+    editcap -C 14:20 -C -4 capture.pcap chopped.pcap
+
 =head1 SEE ALSO
 
 pcap(3), wireshark(1), tshark(1), mergecap(1), dumpcap(1), capinfos(1),
index 4ee9e6aaca31785735bc6d04352ad36317ac1c76..b06a397c812eb554896bcf1f587615b786ea9b71 100644 (file)
--- a/editcap.c
+++ b/editcap.c
@@ -143,6 +143,15 @@ struct time_adjustment {
     int is_negative;
 };
 
+typedef struct _chop_t {
+    int len_begin;
+    int off_begin_pos;
+    int off_begin_neg;
+    int len_end;
+    int off_end_pos;
+    int off_end_neg;
+} chop_t;
+
 #define MAX_SELECTIONS  512
 static struct select_item selectfrm[MAX_SELECTIONS];
 static int max_selected = -1;
@@ -168,6 +177,9 @@ static struct time_adjustment strict_time_adj = {{0, 0}, 0}; /* strict time adju
 static nstime_t previous_time = {0, 0}; /* previous time */
 
 static int find_dct2000_real_data(guint8 *buf);
+static void handle_chopping(chop_t chop, struct wtap_pkthdr *out_phdr,
+                            const struct wtap_pkthdr *in_phdr, guint8 *buf,
+                            gboolean adjlen);
 
 static gchar *
 abs_time_to_str_with_sec_resolution(const struct wtap_nstime *abs_time)
@@ -721,7 +733,9 @@ usage(gboolean is_error)
     fprintf(output, "                         then the bytes chopped will be offset from that value.\n");
     fprintf(output, "                         Positive offsets are from the packet beginning,\n");
     fprintf(output, "                         negative offsets are from the packet end. You can use\n");
-    fprintf(output, "                         this option more than once.\n");
+    fprintf(output, "                         this option more than once, allowing up to 2 chopping\n");
+    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 length when chopping 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");
@@ -847,10 +861,7 @@ main(int argc, char *argv[])
 
     char *p;
     guint32 snaplen = 0;                /* No limit               */
-    int choplen_begin = 0;              /* No chop at beginning   */
-    int choplen_end = 0;                /* No chop at end         */
-    int chopoff_begin_pos = 0, chopoff_begin_neg = 0;/* Offsets for chopping from beginning */
-    int chopoff_end_pos = 0, chopoff_end_neg = 0;    /* Offset for chopping from end */
+    chop_t chop = {0, 0, 0, 0, 0, 0};   /* No chop */
     gboolean adjlen = FALSE;
     wtap_dumper *pdh = NULL;
     unsigned int count = 1;
@@ -955,7 +966,12 @@ main(int argc, char *argv[])
         case 'C':
         {
             int choplen = 0, chopoff = 0;
-
+#if 0
+    int choplen_begin = 0;              /* No chop at beginning   */
+    int choplen_end = 0;                /* No chop at end         */
+    int chopoff_begin_pos = 0, chopoff_begin_neg = 0;/* Offsets for chopping from beginning */
+    int chopoff_end_pos = 0, chopoff_end_neg = 0;    /* Offset for chopping from end */
+#endif
             switch (sscanf(optarg, "%d:%d", &chopoff, &choplen)) {
             case 1: /* only the chop length was specififed */
                 choplen = chopoff;
@@ -973,17 +989,17 @@ main(int argc, char *argv[])
             }
 
             if (choplen > 0) {
-                choplen_begin += choplen;
+                chop.len_begin += choplen;
                 if (chopoff > 0)
-                    chopoff_begin_pos += chopoff;
+                    chop.off_begin_pos += chopoff;
                 else
-                    chopoff_begin_neg += chopoff;
+                    chop.off_begin_neg += chopoff;
             } else if (choplen < 0) {
-                choplen_end += choplen;
+                chop.len_end += choplen;
                 if (chopoff > 0)
-                    chopoff_end_pos += chopoff;
+                    chop.off_end_pos += chopoff;
                 else
-                    chopoff_end_neg += chopoff;
+                    chop.off_end_neg += chopoff;
             }
             break;
         }
@@ -1310,76 +1326,9 @@ main(int argc, char *argv[])
                 }
 
                 /* CHOP */
-                /* If we're not chopping anything from one side, then the
-                 * offset for that side is meaningless. */
-                if (choplen_begin == 0)
-                    chopoff_begin_pos = chopoff_begin_neg = 0;
-                if (choplen_end == 0)
-                    chopoff_end_pos = chopoff_end_neg = 0;
-
-                if (chopoff_begin_neg < 0) {
-                    chopoff_begin_pos += phdr->caplen + chopoff_begin_neg;
-                    chopoff_begin_neg = 0;
-                }
-                if (chopoff_end_pos > 0) {
-                    chopoff_end_neg += chopoff_end_pos - phdr->caplen;
-                    chopoff_end_pos = 0;
-                }
-
-                /* Make sure we don't chop off more than we have available */
-                if (phdr->caplen < (guint32)(chopoff_begin_pos - chopoff_end_neg)) {
-                    choplen_begin = 0;
-                    choplen_end = 0;
-                }
-                if ((guint32)(choplen_begin - choplen_end) >
-                    (phdr->caplen - (guint32)(chopoff_begin_pos - chopoff_end_neg))) {
-                    choplen_begin = phdr->caplen - (chopoff_begin_pos - chopoff_end_neg);
-                    choplen_end = 0;
-                }
-
-                /* Handle chopping from the beginning.  Note that if a
-                 * beginning offset was specified, we need to keep that piece */
-                if (choplen_begin > 0) {
-                    snap_phdr = *phdr;
-
-                    if (chopoff_begin_pos > 0) {
-                        memmove(&buf[chopoff_begin_pos],
-                                &buf[chopoff_begin_pos + choplen_begin],
-                                snap_phdr.caplen - choplen_begin);
-                    } else {
-                        buf += choplen_begin;
-                    }
-                    snap_phdr.caplen -= choplen_begin;
-
-                    if (adjlen) {
-                        if (phdr->len > (guint32)choplen_begin)
-                            snap_phdr.len -= choplen_begin;
-                        else
-                            snap_phdr.len = 0;
-                    }
-                    phdr = &snap_phdr;
-                }
-
-                /* Handle chopping from the end.  Note that if an ending offset
-                 * was specified, we need to keep that piece */
-                if (choplen_end < 0) {
-                    snap_phdr = *phdr;
-
-                    if (chopoff_end_neg < 0) {
-                        memmove(&buf[(gint)snap_phdr.caplen + (choplen_end + chopoff_end_neg)],
-                                &buf[(gint)snap_phdr.caplen + chopoff_end_neg], -
-                                chopoff_end_neg);
-                    }
-                    snap_phdr.caplen += choplen_end;
-
-                    if (adjlen) {
-                        if (((signed int) phdr->len + choplen_end) > 0)
-                            snap_phdr.len += choplen_end;
-                        else
-                            snap_phdr.len = 0;
-                    }
-                    phdr = &snap_phdr;
-                }
+                snap_phdr = *phdr;
+                handle_chopping(chop, &snap_phdr, phdr, buf, adjlen);
+                phdr = &snap_phdr;
 
                 /* Do we adjust timestamps to ensure strict chronological
                  * order? */
@@ -1687,6 +1636,103 @@ find_dct2000_real_data(guint8 *buf)
     return n;
 }
 
+/*
+ * We support up to 2 chopping regions in a single pas, one specified by the
+ * positive chop length, and one by the negative chop length.
+ */
+static void
+handle_chopping(chop_t chop, struct wtap_pkthdr *out_phdr,
+                const struct wtap_pkthdr *in_phdr, guint8 *buf,
+                gboolean adjlen)
+{
+    /* If we're not chopping anything from one side, then the offset for that
+     * side is meaningless. */
+    if (chop.len_begin == 0)
+        chop.off_begin_pos = chop.off_begin_neg = 0;
+    if (chop.len_end == 0)
+        chop.off_end_pos = chop.off_end_neg = 0;
+
+    if (chop.off_begin_neg < 0) {
+        chop.off_begin_pos += in_phdr->caplen + chop.off_begin_neg;
+        chop.off_begin_neg = 0;
+    }
+    if (chop.off_end_pos > 0) {
+        chop.off_end_neg += chop.off_end_pos - in_phdr->caplen;
+        chop.off_end_pos = 0;
+    }
+
+    /* If we've crossed chopping regions, swap them */
+    if (chop.len_begin && chop.len_end) {
+        if (chop.off_begin_pos > ((int)in_phdr->caplen + chop.off_end_neg)) {
+            int tmp_len, tmp_off;
+
+            tmp_off = in_phdr->caplen + chop.off_end_neg + chop.len_end;
+            tmp_len = -chop.len_end;
+
+            chop.off_end_neg = chop.len_begin + chop.off_begin_pos - in_phdr->caplen;
+            chop.len_end = -chop.len_begin;
+
+            chop.len_begin = tmp_len;
+            chop.off_begin_pos = tmp_off;
+        }
+    }
+
+    /* Make sure we don't chop off more than we have available */
+    if (in_phdr->caplen < (guint32)(chop.off_begin_pos - chop.off_end_neg)) {
+        chop.len_begin = 0;
+        chop.len_end = 0;
+    }
+    if ((guint32)(chop.len_begin - chop.len_end) >
+        (in_phdr->caplen - (guint32)(chop.off_begin_pos - chop.off_end_neg))) {
+        chop.len_begin = in_phdr->caplen - (chop.off_begin_pos - chop.off_end_neg);
+        chop.len_end = 0;
+    }
+
+    /* Handle chopping from the beginning.  Note that if a beginning offset
+     * was specified, we need to keep that piece */
+    if (chop.len_begin > 0) {
+        *out_phdr = *in_phdr;
+
+        if (chop.off_begin_pos > 0) {
+            memmove(&buf[chop.off_begin_pos],
+                    &buf[chop.off_begin_pos + chop.len_begin],
+                    out_phdr->caplen - chop.len_begin);
+        } else {
+            buf += chop.len_begin;
+        }
+        out_phdr->caplen -= chop.len_begin;
+
+        if (adjlen) {
+            if (in_phdr->len > (guint32)chop.len_begin)
+                out_phdr->len -= chop.len_begin;
+            else
+                out_phdr->len = 0;
+        }
+        in_phdr = out_phdr;
+    }
+
+    /* Handle chopping from the end.  Note that if an ending offset was
+     * specified, we need to keep that piece */
+    if (chop.len_end < 0) {
+        *out_phdr = *in_phdr;
+
+        if (chop.off_end_neg < 0) {
+            memmove(&buf[(gint)out_phdr->caplen + (chop.len_end + chop.off_end_neg)],
+                    &buf[(gint)out_phdr->caplen + chop.off_end_neg],
+                    -chop.off_end_neg);
+        }
+        out_phdr->caplen += chop.len_end;
+
+        if (adjlen) {
+            if (((signed int) in_phdr->len + chop.len_end) > 0)
+                out_phdr->len += chop.len_end;
+            else
+                out_phdr->len = 0;
+        }
+        in_phdr = out_phdr;
+    }
+}
+
 /*
  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
  *