diff options
author | Chris Maynard <Christopher.Maynard@GTECH.COM> | 2013-09-09 19:39:45 +0000 |
---|---|---|
committer | Chris Maynard <Christopher.Maynard@GTECH.COM> | 2013-09-09 19:39:45 +0000 |
commit | 51ccb61256e5d97d0e6d46b84cb857f4ac3b4daf (patch) | |
tree | 9b03e33a9cd83c7b4419f81128e52aba46810ef9 | |
parent | 2632e1698515095f510862f3dd5dd9044057138d (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.pod | 20 | ||||
-rw-r--r-- | editcap.c | 210 |
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), @@ -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: |