diff --git a/README.md b/README.md index ee61effc242e8c808fcbe755e28d6fd6303b8fcc..4abdcb6fb71777f15e18ed887039d2ef5cd026ae 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ pip install -r requirements.txt ## Usage ```bash -python3 pcap_tweaker.py [-h] [-r RANDOM_RANGE] [-n PACKET_NUMBER] [-d] pcap [pcap ...] +python3 pcap_tweaker.py [-h] [-o OUTPUT] [-r RANDOM_RANGE] [-n PACKET_NUMBER] [-d] pcap [pcap ...] ``` The program produces new PCAP file with the same name as the input files, @@ -44,6 +44,7 @@ It will be created if it doesn't exist. ### Optional arguments * `-h`, `--help`: show help message and exit +* `-o`, `--output`: output PCAP file. Used only if a single input file is specified. Default: `<input_pcap>.edit.pcap` * `-r`, `--random-range`: upper bound for the random range, which will select for each packet if it will be edited or not. In practice, each packet will be edited with a probability of `1/r`. Must be a strictly positive integer. Default: `1` (edit all packets). * `-n`, `--packet-number`: index of the packet to edit, starting from 1. Can be specified multiple times. If this is used, only the specified packets will be edited, and no random editing will be performed. * `-d`, `--dry-run`: don't write the output PCAP file (but still write the CSV log file) diff --git a/src/pcap_tweaker.py b/src/pcap_tweaker.py index ce38aaac89c792d62f3b4dab38778d51fdc9a6a4..2475baaf6d2362744ea630cddc44fcf655acec41 100644 --- a/src/pcap_tweaker.py +++ b/src/pcap_tweaker.py @@ -31,7 +31,7 @@ def strictly_positive_int(value: any) -> int: return ivalue -def tweak_pcaps(pcaps: list, random_range: int = 1, packet_numbers: list = None, dry_run: bool = False) -> None: +def tweak_pcaps(pcaps: list, output: str, random_range: int = 1, packet_numbers: list = None, dry_run: bool = False) -> None: """ Main functionality of the program: (Randomly) edit packet fields in a (list of) PCAP file(s). @@ -103,7 +103,10 @@ def tweak_pcaps(pcaps: list, random_range: int = 1, packet_numbers: list = None, # Write output PCAP file output_dir = os.path.join(os.path.dirname(input_pcap), "edited") os.makedirs(output_dir, exist_ok=True) - output_pcap = os.path.basename(input_pcap).replace(".pcap", ".edit.pcap") + if output is not None and len(pcaps) == 1: + output_pcap = output + else: + output_pcap = os.path.basename(input_pcap).replace(".pcap", ".edit.pcap") output_pcap = os.path.join(output_dir, output_pcap) if dry_run: logging.info(f"Dry run: did not write output PCAP file: {output_pcap}") @@ -129,6 +132,8 @@ if __name__ == "__main__": ) # Positional arguments: input PCAP file parser.add_argument("input_pcaps", metavar="pcap", type=str, nargs="+", help="Input PCAP files.") + # Optional flag: -o / --output + parser.add_argument("-o", "--output", type=str, help="Output PCAP file name. Used only if a single input file is specified. Default: <input_pcap>.edit.pcap") # Optional flag: -r / --random-range parser.add_argument("-r", "--random-range", type=strictly_positive_int, default=1, help="Upper bound for random range (not included). Must be a strictly positive integer. Default: 1 (edit each packet).") @@ -140,11 +145,15 @@ if __name__ == "__main__": help="Dry run: do not write output PCAP file.") # Parse arguments args = parser.parse_args() + # Verify arguments + if args.output is not None and len(args.input_pcaps) > 1: + logging.warning("Multiple input PCAP files specified, ignoring output PCAP file name.") ### MAIN PROGRAM ### tweak_pcaps( pcaps=args.input_pcaps, + output=args.output, random_range=args.random_range, packet_numbers=args.packet_number, dry_run=args.dry_run