/** * \brief sends the traffic out the interfaces * * Designed to be called in a separate thread if you need to. Blocks until * the replay is complete or you call tcpreplay_abort() in another thread. * Pass the index of the pcap you want to replay, or -1 for all pcaps. * * In dualfile mode, we will process idx and idx+1 */ int tcpreplay_replay(tcpreplay_t *ctx, int idx) { int rcode; assert(ctx); if (idx < 0 || idx > ctx->options->source_cnt) { tcpreplay_seterr(ctx, "invalid source index value: %d", idx); return -1; } if (ctx->options->dualfile && ((idx + 1) > ctx->options->source_cnt)) { tcpreplay_seterr(ctx, "invalid dualfile source index value: %d", (idx + 1)); return -1; } if (gettimeofday(&ctx->stats.start_time, NULL) < 0) { tcpreplay_seterr(ctx, "gettimeofday() failed: %s", strerror(errno)); return -1; } ctx->running = true; /* main loop, when not looping forever */ if (ctx->options->loop > 0) { while (ctx->options->loop--) { /* limited loop */ if ((rcode = tcpr_replay_index(ctx, idx)) < 0) return rcode; } } else { while (1) { /* loop forever */ if ((rcode = tcpr_replay_index(ctx, idx)) < 0) return rcode; } } ctx->running = false; return 0; }
int main(int argc, char *argv[]) { int i, optct = 0; int rcode; ctx = tcpreplay_init(); #ifdef TCPREPLAY optct = optionProcess(&tcpreplayOptions, argc, argv); #elif defined TCPREPLAY_EDIT optct = optionProcess(&tcpreplay_editOptions, argc, argv); #endif argc -= optct; argv += optct; rcode = tcpreplay_post_args(ctx, argc); if (rcode <= -2) { warnx("%s", tcpreplay_getwarn(ctx)); } else if (rcode == -1) { errx(-1, "Unable to parse args: %s", tcpreplay_geterr(ctx)); } #ifdef TCPREPLAY_EDIT /* init tcpedit context */ if (tcpedit_init(&tcpedit, sendpacket_get_dlt(ctx->intf1)) < 0) { errx(-1, "Error initializing tcpedit: %s", tcpedit_geterr(tcpedit)); } /* parse the tcpedit args */ rcode = tcpedit_post_args(tcpedit); if (rcode < 0) { errx(-1, "Unable to parse args: %s", tcpedit_geterr(tcpedit)); } else if (rcode == 1) { warnx("%s", tcpedit_geterr(tcpedit)); } if (tcpedit_validate(tcpedit) < 0) { errx(-1, "Unable to edit packets given options:\n%s", tcpedit_geterr(tcpedit)); } #endif if ((ctx->options->enable_file_cache || ctx->options->preload_pcap) && ! HAVE_OPT(QUIET)) { notice("File Cache is enabled"); } /* * Setup up the file cache, if required */ if (ctx->options->enable_file_cache || ctx->options->preload_pcap) { /* Initialise each of the file cache structures */ for (i = 0; i < argc; i++) { ctx->options->file_cache[i].index = i; ctx->options->file_cache[i].cached = FALSE; ctx->options->file_cache[i].packet_cache = NULL; } } for (i = 0; i < argc; i++) { tcpreplay_add_pcapfile(ctx, argv[i]); /* preload our pcap file? */ if (ctx->options->preload_pcap) { preload_pcap_file(ctx, i); } } /* init the signal handlers */ init_signal_handlers(); if (gettimeofday(&ctx->stats.start_time, NULL) < 0) errx(-1, "gettimeofday() failed: %s", strerror(errno)); /* main loop, when not looping forever */ if (ctx->options->loop > 0) { while (ctx->options->loop--) { /* limited loop */ if (ctx->options->dualfile) { /* process two files at a time for network taps */ for (i = 0; i < argc; i += 2) { tcpr_replay_index(ctx, i); } } else { /* process each pcap file in order */ for (i = 0; i < argc; i++) { /* reset cache markers for each iteration */ ctx->cache_byte = 0; ctx->cache_bit = 0; tcpr_replay_index(ctx, i); } } } } else { /* loop forever */ while (1) { if (ctx->options->dualfile) { /* process two files at a time for network taps */ for (i = 0; i < argc; i += 2) { tcpr_replay_index(ctx, i); } } else { /* process each pcap file in order */ for (i = 0; i < argc; i++) { /* reset cache markers for each iteration */ ctx->cache_byte = 0; ctx->cache_bit = 0; tcpr_replay_index(ctx, i); } } } } if (ctx->stats.bytes_sent > 0) { if (gettimeofday(&ctx->stats.end_time, NULL) < 0) errx(-1, "gettimeofday() failed: %s", strerror(errno)); packet_stats(&ctx->stats); printf("%s", sendpacket_getstat(ctx->intf1)); if (ctx->intf2 != NULL) printf("%s", sendpacket_getstat(ctx->intf2)); } tcpreplay_close(ctx); return 0; } /* main() */