aboutsummaryrefslogtreecommitdiffstats
path: root/editcap.c
diff options
context:
space:
mode:
authorChris Maynard <Christopher.Maynard@GTECH.COM>2013-09-09 19:39:45 +0000
committerChris Maynard <Christopher.Maynard@GTECH.COM>2013-09-09 19:39:45 +0000
commit51ccb61256e5d97d0e6d46b84cb857f4ac3b4daf (patch)
tree9b03e33a9cd83c7b4419f81128e52aba46810ef9 /editcap.c
parent2632e1698515095f510862f3dd5dd9044057138d (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
Diffstat (limited to 'editcap.c')
-rw-r--r--editcap.c210
1 files changed, 128 insertions, 82 deletions
diff --git a/editcap.c b/editcap.c
index 4ee9e6aaca..b06a397c81 100644
--- a/editcap.c
+++ b/editcap.c
@@ -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: