aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Maynard <Christopher.Maynard@GTECH.COM>2013-09-09 19:39:45 +0000
committerChris Maynard <Christopher.Maynard@GTECH.COM>2013-09-09 19:39:45 +0000
commit51ccb61256e5d97d0e6d46b84cb857f4ac3b4daf (patch)
tree9b03e33a9cd83c7b4419f81128e52aba46810ef9
parent2632e1698515095f510862f3dd5dd9044057138d (diff)
Fix the "crossed chopping region" problem. Also, move chopping to its own function for both clarity and correctness since we need to compute chop offsets and lengths on a per-packet basis whereas previously this was not being done.
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 svn path=/trunk/; revision=51886
-rw-r--r--doc/editcap.pod20
-rw-r--r--editcap.c210
2 files changed, 142 insertions, 88 deletions
diff --git a/doc/editcap.pod b/doc/editcap.pod
index fda1228558..abeacb87f0 100644
--- a/doc/editcap.pod
+++ b/doc/editcap.pod
@@ -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),
diff --git a/editcap.c b/editcap.c
index 4ee9e6aaca..b06a397c81 100644
--- 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? */
@@ -1688,6 +1637,103 @@ find_dct2000_real_data(guint8 *buf)
}
/*
+ * 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
*
* Local variables: