diff options
author | Chris Maynard <Christopher.Maynard@GTECH.COM> | 2013-09-08 20:29:26 +0000 |
---|---|---|
committer | Chris Maynard <Christopher.Maynard@GTECH.COM> | 2013-09-08 20:29:26 +0000 |
commit | 54adc0d2ffe70561ffbe8b38a4bc36e33ef9ae0d (patch) | |
tree | b070446f39b89c3ee0b3645f8222799560fd08cd | |
parent | 1b009df7495d3bd20aa09d7691855d927d96a87d (diff) | |
download | wireshark-54adc0d2ffe70561ffbe8b38a4bc36e33ef9ae0d.tar.gz |
Allow an optional offset to be specified when chopping bytes from packets.
svn path=/trunk/; revision=51845
-rw-r--r-- | doc/editcap.pod | 19 | ||||
-rw-r--r-- | docbook/release-notes.asciidoc | 3 | ||||
-rw-r--r-- | editcap.c | 108 |
3 files changed, 100 insertions, 30 deletions
diff --git a/doc/editcap.pod b/doc/editcap.pod index b89ecb51ca..d5abe28a1f 100644 --- a/doc/editcap.pod +++ b/doc/editcap.pod @@ -9,7 +9,7 @@ B<editcap> S<[ B<-A> E<lt>start timeE<gt> ]> S<[ B<-B> E<lt>stop timeE<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<-F> E<lt>file formatE<gt> ]> 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 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 chopped by <choplen> bytes of data. Positive values chop at the packet beginning while negative values chop at the packet end. -This is useful for chopping headers for decapsulation of an entire capture or -in the rare case that the conversion between two file formats leaves some random -bytes at the end of each packet. +If the optional offset precedes the <choplen>, then the bytes chopped will be +offset from that value. Positve offsets are from the packet beginning, while +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 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 +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 pcap(3), wireshark(1), tshark(1), mergecap(1), dumpcap(1), capinfos(1), diff --git a/docbook/release-notes.asciidoc b/docbook/release-notes.asciidoc index 2bb33014c9..d93b2650ca 100644 --- a/docbook/release-notes.asciidoc +++ b/docbook/release-notes.asciidoc @@ -35,6 +35,9 @@ since version 1.10: * 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 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 @@ -730,9 +730,13 @@ usage(gboolean is_error) fprintf(output, "\n"); fprintf(output, "Packet manipulation:\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, " 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, " -t <time adjustment> adjust the timestamp of each packet;\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 */ int choplen_begin = 0; /* No chop at beginning */ 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; wtap_dumper *pdh = NULL; unsigned int count = 1; @@ -962,18 +968,37 @@ main(int argc, char *argv[]) case 'C': { - int choplen; - - choplen = (int)strtol(optarg, &p, 10); - if (p == optarg || *p != '\0') { - fprintf(stderr, "editcap: \"%s\" isn't a valid chop length\n", + int choplen = 0, chopoff = 0; + + switch (sscanf(optarg, "%d:%d", &chopoff, &choplen)) { + case 1: /* only the chop length was specififed */ + 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); - exit(1); + exit(1); + break; } + if (choplen > 0) choplen_begin += choplen; else if (choplen < 0) choplen_end += choplen; + if (chopoff > 0) + chopoff_begin += chopoff; + else if (chopoff < 0) + chopoff_end += chopoff; 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; - if (((signed int) phdr->caplen + choplen_end) > 0) - snap_phdr.caplen += choplen_end; - else - snap_phdr.caplen = 0; + + if (chopoff_begin > 0) { + memmove(&buf[chopoff_begin], &buf[chopoff_begin + choplen_begin], + snap_phdr.caplen - choplen_begin); + } + else { + buf += choplen_begin; + } + snap_phdr.caplen -= choplen_begin; + if (adjlen) { - if (((signed int) phdr->len + choplen_end) > 0) - snap_phdr.len += choplen_end; - else + if (phdr->len > (guint32)choplen_begin) { + snap_phdr.len -= choplen_begin; + } else { snap_phdr.len = 0; + } } 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; - if (phdr->caplen > (unsigned int) choplen_begin) { - snap_phdr.caplen -= choplen_begin; - buf += choplen_begin; - } else - snap_phdr.caplen = 0; + + if (chopoff_end < 0) { + memmove(&buf[(gint)snap_phdr.caplen + (choplen_end + chopoff_end)], + &buf[(gint)snap_phdr.caplen + chopoff_end], -chopoff_end); + } + snap_phdr.caplen += choplen_end; + if (adjlen) { - if (phdr->len > (unsigned int) choplen_begin) { - snap_phdr.len -= choplen_begin; - } else + if (((signed int) phdr->len + choplen_end) > 0) { + snap_phdr.len += choplen_end; + } else { snap_phdr.len = 0; + } } phdr = &snap_phdr; } |