forked from osmocom/wireshark
Allow an optional offset to be specified when chopping bytes from packets.
svn path=/trunk/; revision=51845
This commit is contained in:
parent
1b009df749
commit
54adc0d2ff
|
@ -9,7 +9,7 @@ B<editcap>
|
||||||
S<[ B<-A> E<lt>start timeE<gt> ]>
|
S<[ B<-A> E<lt>start timeE<gt> ]>
|
||||||
S<[ B<-B> E<lt>stop timeE<gt> ]>
|
S<[ B<-B> E<lt>stop timeE<gt> ]>
|
||||||
S<[ B<-c> E<lt>packets per fileE<gt> ]>
|
S<[ B<-c> E<lt>packets per fileE<gt> ]>
|
||||||
S<[ B<-C> E<lt>choplenE<gt> ]>
|
S<[ B<-C> [offset:]E<lt>choplenE<gt> ]>
|
||||||
S<[ B<-E> E<lt>error probabilityE<gt> ]>
|
S<[ B<-E> E<lt>error probabilityE<gt> ]>
|
||||||
S<[ B<-F> E<lt>file formatE<gt> ]>
|
S<[ B<-F> E<lt>file formatE<gt> ]>
|
||||||
S<[ B<-h> ]>
|
S<[ B<-h> ]>
|
||||||
|
@ -89,15 +89,20 @@ be created with a suffix -nnnnn, starting with 00000. If the specified
|
||||||
number of packets is written to the output file, the next output file is
|
number of packets is written to the output file, the next output file is
|
||||||
opened. The default is to use a single output file.
|
opened. The default is to use a single output file.
|
||||||
|
|
||||||
=item -C E<lt>choplenE<gt>
|
=item -C [offset:]E<lt>choplenE<gt>
|
||||||
|
|
||||||
Sets the chop length to use when writing the packet data. Each packet is
|
Sets the chop length to use when writing the packet data. Each packet is
|
||||||
chopped by <choplen> bytes of data. Positive values chop at the packet
|
chopped by <choplen> bytes of data. Positive values chop at the packet
|
||||||
beginning while negative values chop at the packet end.
|
beginning while negative values chop at the packet end.
|
||||||
|
|
||||||
This is useful for chopping headers for decapsulation of an entire capture or
|
If the optional offset precedes the <choplen>, then the bytes chopped will be
|
||||||
in the rare case that the conversion between two file formats leaves some random
|
offset from that value. Positve offsets are from the packet beginning, while
|
||||||
bytes at the end of each packet.
|
negative offsets are from the packet end.
|
||||||
|
|
||||||
|
This is useful for chopping headers for decapsulation of an entire capture,
|
||||||
|
removing tunneling headers, or in the rare case that the conversion between two
|
||||||
|
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
|
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 the beginning of a packet as well as from the end of a packet in a
|
||||||
|
@ -347,6 +352,10 @@ 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:
|
||||||
|
|
||||||
|
editcap -L -C 12:4 capture_vlan.pcap capture_no_vlan.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),
|
||||||
|
|
|
@ -35,6 +35,9 @@ since version 1.10:
|
||||||
* You can now pass the -C <choplen> option to editcap multiple times, which
|
* You can now pass the -C <choplen> option to editcap multiple times, which
|
||||||
allows you to chop bytes from the beginning of a packet as well as at the end
|
allows you to chop bytes from the beginning of a packet as well as at the end
|
||||||
of a packet in a single step.
|
of a packet in a single step.
|
||||||
|
* You can now specify an optional offset to the -C option for editcap, which
|
||||||
|
allows you to start chopping from that offset instead of from the absolute
|
||||||
|
packet beginning or end.
|
||||||
|
|
||||||
=== New Protocol Support
|
=== New Protocol Support
|
||||||
|
|
||||||
|
|
106
editcap.c
106
editcap.c
|
@ -730,9 +730,13 @@ usage(gboolean is_error)
|
||||||
fprintf(output, "\n");
|
fprintf(output, "\n");
|
||||||
fprintf(output, "Packet manipulation:\n");
|
fprintf(output, "Packet manipulation:\n");
|
||||||
fprintf(output, " -s <snaplen> truncate each packet to max. <snaplen> bytes of data.\n");
|
fprintf(output, " -s <snaplen> truncate each packet to max. <snaplen> bytes of data.\n");
|
||||||
fprintf(output, " -C <choplen> chop each packet by <choplen> bytes. Positive values\n");
|
fprintf(output, " -C [offset:]<choplen> chop each packet by <choplen> bytes. Positive values\n");
|
||||||
fprintf(output, " chop at the packet beginning, negative values at the\n");
|
fprintf(output, " chop at the packet beginning, negative values at the\n");
|
||||||
fprintf(output, " packet end. You can use this option more than once.\n");
|
fprintf(output, " packet end. If an optional offset precedes the length,\n");
|
||||||
|
fprintf(output, " then the bytes chopped will be offset from that value.\n");
|
||||||
|
fprintf(output, " Positve 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, " -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");
|
||||||
|
@ -861,6 +865,8 @@ main(int argc, char *argv[])
|
||||||
guint32 snaplen = 0; /* No limit */
|
guint32 snaplen = 0; /* No limit */
|
||||||
int choplen_begin = 0; /* No chop at beginning */
|
int choplen_begin = 0; /* No chop at beginning */
|
||||||
int choplen_end = 0; /* No chop at end */
|
int choplen_end = 0; /* No chop at end */
|
||||||
|
int chopoff_begin = 0; /* Offset when chop from beginning */
|
||||||
|
int chopoff_end = 0; /* Offset when chop from end */
|
||||||
gboolean adjlen = FALSE;
|
gboolean adjlen = FALSE;
|
||||||
wtap_dumper *pdh = NULL;
|
wtap_dumper *pdh = NULL;
|
||||||
unsigned int count = 1;
|
unsigned int count = 1;
|
||||||
|
@ -962,18 +968,37 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
case 'C':
|
case 'C':
|
||||||
{
|
{
|
||||||
int choplen;
|
int choplen = 0, chopoff = 0;
|
||||||
|
|
||||||
choplen = (int)strtol(optarg, &p, 10);
|
switch (sscanf(optarg, "%d:%d", &chopoff, &choplen)) {
|
||||||
if (p == optarg || *p != '\0') {
|
case 1: /* only the chop length was specififed */
|
||||||
fprintf(stderr, "editcap: \"%s\" isn't a valid chop length\n",
|
choplen = chopoff;
|
||||||
|
chopoff = 0;
|
||||||
|
break;
|
||||||
|
case 2: /* both an offset and chop length was specified */
|
||||||
|
/* While the following would technically not be a problem, it's
|
||||||
|
* probably not what the user wanted, so treat it as an error */
|
||||||
|
if ((choplen > 0 && chopoff < 0) || (choplen < 0 && chopoff > 0)) {
|
||||||
|
fprintf(stderr, "editcap: \"%s\" isn't a valid chop offset:length\n",
|
||||||
|
optarg);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "editcap: \"%s\" isn't a valid chop length or offset:length\n",
|
||||||
optarg);
|
optarg);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (choplen > 0)
|
if (choplen > 0)
|
||||||
choplen_begin += choplen;
|
choplen_begin += choplen;
|
||||||
else if (choplen < 0)
|
else if (choplen < 0)
|
||||||
choplen_end += choplen;
|
choplen_end += choplen;
|
||||||
|
if (chopoff > 0)
|
||||||
|
chopoff_begin += chopoff;
|
||||||
|
else if (chopoff < 0)
|
||||||
|
chopoff_end += chopoff;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1302,33 +1327,66 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (choplen_end < 0) {
|
/* CHOP */
|
||||||
|
/* If we're not chopping anything from one side, then the offset for
|
||||||
|
* that side is meaningless. */
|
||||||
|
if (choplen_begin == 0)
|
||||||
|
chopoff_begin = 0;
|
||||||
|
if (choplen_end == 0)
|
||||||
|
chopoff_end = 0;
|
||||||
|
|
||||||
|
/* Make sure we don't chop off more than we have available */
|
||||||
|
if (phdr->caplen < (guint32)(chopoff_begin - chopoff_end)) {
|
||||||
|
choplen_begin = 0;
|
||||||
|
choplen_end = 0;
|
||||||
|
}
|
||||||
|
if ((guint32)(choplen_begin - choplen_end) >
|
||||||
|
(phdr->caplen - (guint32)(chopoff_begin - chopoff_end))) {
|
||||||
|
choplen_begin = phdr->caplen - (chopoff_begin - chopoff_end);
|
||||||
|
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;
|
snap_phdr = *phdr;
|
||||||
if (((signed int) phdr->caplen + choplen_end) > 0)
|
|
||||||
snap_phdr.caplen += choplen_end;
|
if (chopoff_begin > 0) {
|
||||||
else
|
memmove(&buf[chopoff_begin], &buf[chopoff_begin + choplen_begin],
|
||||||
snap_phdr.caplen = 0;
|
snap_phdr.caplen - choplen_begin);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
buf += choplen_begin;
|
||||||
|
}
|
||||||
|
snap_phdr.caplen -= choplen_begin;
|
||||||
|
|
||||||
if (adjlen) {
|
if (adjlen) {
|
||||||
if (((signed int) phdr->len + choplen_end) > 0)
|
if (phdr->len > (guint32)choplen_begin) {
|
||||||
snap_phdr.len += choplen_end;
|
snap_phdr.len -= choplen_begin;
|
||||||
else
|
} else {
|
||||||
snap_phdr.len = 0;
|
snap_phdr.len = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
phdr = &snap_phdr;
|
phdr = &snap_phdr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (choplen_begin > 0) {
|
/* 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;
|
snap_phdr = *phdr;
|
||||||
if (phdr->caplen > (unsigned int) choplen_begin) {
|
|
||||||
snap_phdr.caplen -= choplen_begin;
|
if (chopoff_end < 0) {
|
||||||
buf += choplen_begin;
|
memmove(&buf[(gint)snap_phdr.caplen + (choplen_end + chopoff_end)],
|
||||||
} else
|
&buf[(gint)snap_phdr.caplen + chopoff_end], -chopoff_end);
|
||||||
snap_phdr.caplen = 0;
|
}
|
||||||
|
snap_phdr.caplen += choplen_end;
|
||||||
|
|
||||||
if (adjlen) {
|
if (adjlen) {
|
||||||
if (phdr->len > (unsigned int) choplen_begin) {
|
if (((signed int) phdr->len + choplen_end) > 0) {
|
||||||
snap_phdr.len -= choplen_begin;
|
snap_phdr.len += choplen_end;
|
||||||
} else
|
} else {
|
||||||
snap_phdr.len = 0;
|
snap_phdr.len = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
phdr = &snap_phdr;
|
phdr = &snap_phdr;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue