forked from osmocom/wireshark
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:
parent
2632e16985
commit
51ccb61256
|
@ -105,8 +105,10 @@ file formats leaves some random bytes at the end of each packet. Another use is
|
||||||
for removing vlan tags.
|
for removing vlan tags.
|
||||||
|
|
||||||
NOTE: This option can be used more than once, effectively allowing you to chop
|
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
|
bytes from two different areas of a packet in a single pass provided that
|
||||||
single step.
|
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
|
=item -d
|
||||||
|
|
||||||
|
@ -189,7 +191,7 @@ packets were used).
|
||||||
|
|
||||||
=item -S E<lt>strict time adjustmentE<gt>
|
=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
|
The <strict time adjustment> value represents relative seconds
|
||||||
specified as [-]I<seconds>[I<.fractional 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
|
equal to the timestamp value of the previous packet plus the value
|
||||||
of the <strict time adjustment> value. A <strict time adjustment>
|
of the <strict time adjustment> value. A <strict time adjustment>
|
||||||
value of 0 will adjust the minimum number of timestamp values
|
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.
|
strict chronological order.
|
||||||
|
|
||||||
If <strict time adjustment> value is specified as a
|
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
|
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
|
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
|
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
|
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
|
=head1 SEE ALSO
|
||||||
|
|
||||||
pcap(3), wireshark(1), tshark(1), mergecap(1), dumpcap(1), capinfos(1),
|
pcap(3), wireshark(1), tshark(1), mergecap(1), dumpcap(1), capinfos(1),
|
||||||
|
|
210
editcap.c
210
editcap.c
|
@ -143,6 +143,15 @@ struct time_adjustment {
|
||||||
int is_negative;
|
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
|
#define MAX_SELECTIONS 512
|
||||||
static struct select_item selectfrm[MAX_SELECTIONS];
|
static struct select_item selectfrm[MAX_SELECTIONS];
|
||||||
static int max_selected = -1;
|
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 nstime_t previous_time = {0, 0}; /* previous time */
|
||||||
|
|
||||||
static int find_dct2000_real_data(guint8 *buf);
|
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 *
|
static gchar *
|
||||||
abs_time_to_str_with_sec_resolution(const struct wtap_nstime *abs_time)
|
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, " then the bytes chopped will be offset from that value.\n");
|
||||||
fprintf(output, " Positive offsets are from the packet beginning,\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, " 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, " -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, " -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, " <time adjustment> is in relative seconds (e.g. -0.5).\n");
|
||||||
|
@ -847,10 +861,7 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
char *p;
|
char *p;
|
||||||
guint32 snaplen = 0; /* No limit */
|
guint32 snaplen = 0; /* No limit */
|
||||||
int choplen_begin = 0; /* No chop at beginning */
|
chop_t chop = {0, 0, 0, 0, 0, 0}; /* No chop */
|
||||||
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 */
|
|
||||||
gboolean adjlen = FALSE;
|
gboolean adjlen = FALSE;
|
||||||
wtap_dumper *pdh = NULL;
|
wtap_dumper *pdh = NULL;
|
||||||
unsigned int count = 1;
|
unsigned int count = 1;
|
||||||
|
@ -955,7 +966,12 @@ main(int argc, char *argv[])
|
||||||
case 'C':
|
case 'C':
|
||||||
{
|
{
|
||||||
int choplen = 0, chopoff = 0;
|
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)) {
|
switch (sscanf(optarg, "%d:%d", &chopoff, &choplen)) {
|
||||||
case 1: /* only the chop length was specififed */
|
case 1: /* only the chop length was specififed */
|
||||||
choplen = chopoff;
|
choplen = chopoff;
|
||||||
|
@ -973,17 +989,17 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
if (choplen > 0) {
|
if (choplen > 0) {
|
||||||
choplen_begin += choplen;
|
chop.len_begin += choplen;
|
||||||
if (chopoff > 0)
|
if (chopoff > 0)
|
||||||
chopoff_begin_pos += chopoff;
|
chop.off_begin_pos += chopoff;
|
||||||
else
|
else
|
||||||
chopoff_begin_neg += chopoff;
|
chop.off_begin_neg += chopoff;
|
||||||
} else if (choplen < 0) {
|
} else if (choplen < 0) {
|
||||||
choplen_end += choplen;
|
chop.len_end += choplen;
|
||||||
if (chopoff > 0)
|
if (chopoff > 0)
|
||||||
chopoff_end_pos += chopoff;
|
chop.off_end_pos += chopoff;
|
||||||
else
|
else
|
||||||
chopoff_end_neg += chopoff;
|
chop.off_end_neg += chopoff;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1310,76 +1326,9 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CHOP */
|
/* CHOP */
|
||||||
/* If we're not chopping anything from one side, then the
|
snap_phdr = *phdr;
|
||||||
* offset for that side is meaningless. */
|
handle_chopping(chop, &snap_phdr, phdr, buf, adjlen);
|
||||||
if (choplen_begin == 0)
|
phdr = &snap_phdr;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Do we adjust timestamps to ensure strict chronological
|
/* Do we adjust timestamps to ensure strict chronological
|
||||||
* order? */
|
* order? */
|
||||||
|
@ -1687,6 +1636,103 @@ find_dct2000_real_data(guint8 *buf)
|
||||||
return n;
|
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
|
* Editor modelines - http://www.wireshark.org/tools/modelines.html
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue