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
This commit is contained in:
Chris Maynard 2013-09-09 19:39:45 +00:00
parent 2632e16985
commit 51ccb61256
2 changed files with 142 additions and 88 deletions

View 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),

210
editcap.c
View File

@ -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
*