diff options
-rw-r--r-- | doc/editcap.pod | 8 | ||||
-rw-r--r-- | editcap.c | 19 | ||||
-rwxr-xr-x | tools/fuzz-test.sh | 10 |
3 files changed, 32 insertions, 5 deletions
diff --git a/doc/editcap.pod b/doc/editcap.pod index d816926c20..96dd003ad1 100644 --- a/doc/editcap.pod +++ b/doc/editcap.pod @@ -15,6 +15,7 @@ S<[ B<-E> E<lt>error probabilityE<gt> ]> S<[ B<-F> E<lt>file formatE<gt> ]> S<[ B<-h> ]> S<[ B<-i> E<lt>seconds per fileE<gt> ]> +S<[ B<-o> E<lt>change offsetE<gt> ]> S<[ B<-L> ]> S<[ B<-r> ]> S<[ B<-s> E<lt>snaplenE<gt> ]> @@ -188,6 +189,13 @@ Adjust the original frame length accordingly when chopping and/or snapping (in addition to the captured length, which is always adjusted regardless of whether B<-L> is specified or not). See also B<-C <choplen>> and B<-s <snaplen>>. +=item -o E<lt>change offsetE<gt> + +When used in conjuction with -E, skip some bytes from the beginning of the packet +from being changed. In this way some headers don't get changed, and the fuzzer is +more focused on a smaller part of the packet. Keeping a part of the packet fixed +the same dissector is triggered, that make the fuzzing more precise. + =item -r Reverse the packet selection. @@ -747,6 +747,9 @@ print_usage(FILE *output) fprintf(output, " all packets to the timestamp of the first packet.\n"); fprintf(output, " -E <error probability> set the probability (between 0.0 and 1.0 incl.) that\n"); fprintf(output, " a particular packet byte will be randomly changed.\n"); + fprintf(output, " -o <change offset> When used in conjuction with -E, skip some bytes from the\n"); + fprintf(output, " beginning of the packet. This allows to preserve some\n"); + fprintf(output, " bytes, in order to have some headers untouched.\n"); fprintf(output, "\n"); fprintf(output, "Output File(s):\n"); fprintf(output, " -c <packets per file> split the packet output to different files based on\n"); @@ -921,6 +924,7 @@ DIAG_ON(cast-qual) nstime_t block_start; gchar *fprefix = NULL; gchar *fsuffix = NULL; + guint32 change_offset = 0; const struct wtap_pkthdr *phdr; struct wtap_pkthdr temp_phdr; @@ -978,7 +982,7 @@ DIAG_ON(cast-qual) #endif /* Process the options */ - while ((opt = getopt_long(argc, argv, "a:A:B:c:C:dD:E:F:hi:I:Lrs:S:t:T:vVw:", long_options, NULL)) != -1) { + while ((opt = getopt_long(argc, argv, "a:A:B:c:C:dD:E:F:hi:I:Lo:rs:S:t:T:vVw:", long_options, NULL)) != -1) { switch (opt) { case 'a': { @@ -1159,6 +1163,10 @@ DIAG_ON(cast-qual) adjlen = TRUE; break; + case 'o': + change_offset = (guint32)strtol(optarg, &p, 10); + break; + case 'r': keep_em = !keep_em; /* Just invert */ break; @@ -1608,14 +1616,21 @@ DIAG_ON(cast-qual) } } /* suppress duplicates by time window */ + if (change_offset > phdr->caplen) { + fprintf(stderr, "change offset %u is longer than caplen %u in packet %u\n", + change_offset, phdr->caplen, count); + } + /* Random error mutation */ - if (err_prob > 0.0) { + if (err_prob > 0.0 && change_offset <= phdr->caplen) { int real_data_start = 0; /* Protect non-protocol data */ if (wtap_file_type_subtype(wth) == WTAP_FILE_TYPE_SUBTYPE_CATAPULT_DCT2000) real_data_start = find_dct2000_real_data(buf); + real_data_start += change_offset; + for (i = real_data_start; i < (int) phdr->caplen; i++) { if (rand() <= err_prob * RAND_MAX) { err_type = rand() / (RAND_MAX / ERR_WT_TOTAL + 1); diff --git a/tools/fuzz-test.sh b/tools/fuzz-test.sh index b2788b107b..0e535aa51c 100755 --- a/tools/fuzz-test.sh +++ b/tools/fuzz-test.sh @@ -48,13 +48,16 @@ VALGRIND=0 # Run under AddressSanitizer ? ASAN=0 +# Don't skip any byte from being changed +CHANGE_OFFSET=0 + # The maximum permitted amount of memory leaked. Eventually this should be # worked down to zero, but right now that would fail on every single capture. # Only has effect when running under valgrind. MAX_LEAK=`expr 1024 \* 100` # To do: add options for file names and limits -while getopts "2b:C:d:e:agp:P:" OPTCHAR ; do +while getopts "2b:C:d:e:agp:P:o:" OPTCHAR ; do case $OPTCHAR in a) ASAN=1 ;; 2) TWO_PASS="-2 " ;; @@ -65,6 +68,7 @@ while getopts "2b:C:d:e:agp:P:" OPTCHAR ; do g) VALGRIND=1 ;; p) MAX_PASSES=$OPTARG ;; P) MIN_PLUGINS=$OPTARG ;; + o) CHANGE_OFFSET=$OPTARG ;; esac done shift $(($OPTIND - 1)) @@ -176,9 +180,9 @@ while [ \( $PASS -lt $MAX_PASSES -o $MAX_PASSES -lt 1 \) -a $DONE -ne 1 ] ; do DISSECTOR_BUG=0 VG_ERR_CNT=0 - "$EDITCAP" -E $ERR_PROB "$CF" $TMP_DIR/$TMP_FILE > /dev/null 2>&1 + "$EDITCAP" -E $ERR_PROB -o $CHANGE_OFFSET "$CF" $TMP_DIR/$TMP_FILE > /dev/null 2>&1 if [ $? -ne 0 ] ; then - "$EDITCAP" -E $ERR_PROB -T ether "$CF" $TMP_DIR/$TMP_FILE \ + "$EDITCAP" -E $ERR_PROB -o $CHANGE_OFFSET -T ether "$CF" $TMP_DIR/$TMP_FILE \ > /dev/null 2>&1 if [ $? -ne 0 ] ; then echo "Invalid format for editcap" |