Skip to content

Commit

Permalink
Merge pull request #3 from plangarbalint/read_pcap_with_nanosec
Browse files Browse the repository at this point in the history
Read pcap files with nanosec precision, set nano_sleep as default sle…
  • Loading branch information
plangarbalint authored May 2, 2023
2 parents a57b3e2 + 00e9f83 commit ea08502
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 27 deletions.
2 changes: 1 addition & 1 deletion src/common/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ init_timestamp(struct timespec *timestamp)
}

int get_current_time(struct timespec *ts){
#ifdef _POSIX_C_SOURCE >= 199309L
#if defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 199309L
return clock_gettime(CLOCK_REALTIME, ts);
#else
struct timeval tv;
Expand Down
7 changes: 7 additions & 0 deletions src/defines.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,13 @@ typedef u_int32_t uint32_t
(a)->tv_nsec = (b)->tv_nsec; \
} while(0)

/* libpcap puts nanosec values in tv_usec when pcap file is read with nanosec precision*/
#define TIMEVAL_AS_TIMESPEC_SET(a, b) \
do { \
(a)->tv_sec = (b)->tv_sec; \
(a)->tv_nsec = (b)->tv_usec; \
} while(0)

/*
* Help suppress some compiler warnings
* No problem if variable is actually used
Expand Down
18 changes: 9 additions & 9 deletions src/replay.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ replay_file(tcpreplay_t *ctx, int idx)

/* read from pcap file if we haven't cached things yet */
if (!ctx->options->preload_pcap) {
if ((pcap = pcap_open_offline(path, ebuf)) == NULL) {
if ((pcap = pcap_open_offline_with_tstamp_precision(path, PCAP_TSTAMP_PRECISION_NANO, ebuf)) == NULL) {
tcpreplay_seterr(ctx, "Error opening pcap file: %s", ebuf);
return -1;
}
Expand All @@ -140,10 +140,10 @@ replay_file(tcpreplay_t *ctx, int idx)

} else {
if (!ctx->options->file_cache[idx].cached) {
if ((pcap = pcap_open_offline(path, ebuf)) == NULL) {
tcpreplay_seterr(ctx, "Error opening pcap file: %s", ebuf);
return -1;
}
if ((pcap = pcap_open_offline_with_tstamp_precision(path, PCAP_TSTAMP_PRECISION_NANO, ebuf)) == NULL) {
tcpreplay_seterr(ctx, "Error opening pcap file: %s", ebuf);
return -1;
}
ctx->options->file_cache[idx].dlt = pcap_datalink(pcap);
}
}
Expand All @@ -152,10 +152,10 @@ replay_file(tcpreplay_t *ctx, int idx)
if (ctx->options->verbose) {
/* in cache mode, we may not have opened the file */
if (pcap == NULL)
if ((pcap = pcap_open_offline(path, ebuf)) == NULL) {
tcpreplay_seterr(ctx, "Error opening pcap file: %s", ebuf);
return -1;
}
if ((pcap = pcap_open_offline_with_tstamp_precision(path, PCAP_TSTAMP_PRECISION_NANO, ebuf)) == NULL) {
tcpreplay_seterr(ctx, "Error opening pcap file: %s", ebuf);
return -1;
}

ctx->options->file_cache[idx].dlt = pcap_datalink(pcap);
/* init tcpdump */
Expand Down
32 changes: 16 additions & 16 deletions src/send_packets.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,7 @@ static void increment_iteration(tcpreplay_t *ctx)
void
send_packets(tcpreplay_t *ctx, pcap_t *pcap, int idx)
{
struct timeval last_pkt_ts;
struct timespec now, print_delta;
struct timespec now, print_delta, last_pkt_ts, pkthdr_ts;
tcpreplay_opt_t *options = ctx->options;
tcpreplay_stats_t *stats = &ctx->stats;
COUNTER packetnum = 0;
Expand Down Expand Up @@ -350,7 +349,7 @@ send_packets(tcpreplay_t *ctx, pcap_t *pcap, int idx)
}

ctx->skip_packets = 0;
timerclear(&last_pkt_ts);
timesclear(&last_pkt_ts);
if (options->limit_time > 0)
end_us = TIMESPEC_TO_MICROSEC(&stats->start_time) +
SEC_TO_MICROSEC(options->limit_time);
Expand All @@ -369,7 +368,7 @@ send_packets(tcpreplay_t *ctx, pcap_t *pcap, int idx)
*/
while (!ctx->abort &&
(pktdata = get_next_packet(ctx, pcap, &pkthdr, idx, prev_packet)) != NULL) {

TIMEVAL_AS_TIMESPEC_SET(&pkthdr_ts, &pkthdr.ts); // libpcap puts nanosec values in tv_usec
now_is_now = false;
packetnum++;
#if defined TCPREPLAY || defined TCPREPLAY_EDIT
Expand Down Expand Up @@ -429,20 +428,20 @@ send_packets(tcpreplay_t *ctx, pcap_t *pcap, int idx)
* time stamping is expensive, but now is the
* time to do it.
*/
dbgx(4, "This packet time: " TIMEVAL_FORMAT, pkthdr.ts.tv_sec,
pkthdr.ts.tv_usec);
dbgx(4, "This packet time: " TIMESPEC_FORMAT, pkthdr_ts.tv_sec,
pkthdr_ts.tv_nsec);
skip_length = 0;
ctx->skip_packets = 0;

if (options->speed.mode == speed_multiplier) {
if (!timerisset(&last_pkt_ts)) {
TIMEVAL_SET(&last_pkt_ts, &pkthdr.ts);
} else if (timercmp(&pkthdr.ts, &last_pkt_ts, >)) {
struct timeval delta;

timersub(&pkthdr.ts, &last_pkt_ts, &delta);
timeradd_timeval_timespec(&stats->pkt_ts_delta, &delta, &stats->pkt_ts_delta);
TIMEVAL_SET(&last_pkt_ts, &pkthdr.ts);
if (!timesisset(&last_pkt_ts)) {
TIMESPEC_SET(&last_pkt_ts, &pkthdr_ts);
} else if (timescmp(&pkthdr_ts, &last_pkt_ts, >)) {
struct timespec delta;

timessub(&pkthdr_ts, &last_pkt_ts, &delta);
timeradd_timespec(&stats->pkt_ts_delta, &delta, &stats->pkt_ts_delta);
TIMESPEC_SET(&last_pkt_ts, &pkthdr_ts);
}
}

Expand Down Expand Up @@ -999,7 +998,7 @@ static void calc_sleep_time(tcpreplay_t *ctx, struct timespec *pkt_ts_delta,
if (timescmp(pkt_ts_delta, time_delta, >)) {
/* pkt_time_delta has increased, so handle normally */
timessub(pkt_ts_delta, time_delta, &nap_for);
TIMESPEC_SET(&nap_for, &ctx->nap);
TIMESPEC_SET(&ctx->nap, &nap_for);
dbgx(3, "original packet delta time: " TIMESPEC_FORMAT,
ctx->nap.tv_sec, ctx->nap.tv_nsec);
timesdiv_float(&ctx->nap, options->speed.multiplier);
Expand Down Expand Up @@ -1117,8 +1116,9 @@ static void tcpr_sleep(tcpreplay_t *ctx, sendpacket_t *sp,


/* don't sleep if nap = {0, 0} */
if (!timesisset(nap_this_time))
if (!timesisset(nap_this_time)){
return;
}

/* do we need to limit the total time we sleep? */
if (timesisset(&(options->maxsleep)) && (timescmp(nap_this_time, &(options->maxsleep), >))) {
Expand Down
2 changes: 1 addition & 1 deletion src/sleep.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ static inline void
nanosleep_sleep(sendpacket_t *sp _U_, const struct timespec *nap,
struct timespec *now, bool flush _U_)
{
#ifdef _POSIX_C_SOURCE >= 200112L
struct timespec sleep_until;
timeradd_timespec(now, nap, &sleep_until);
#if defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200112L
clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &sleep_until, NULL);
#else
nanosleep(nap, NULL);
Expand Down

0 comments on commit ea08502

Please sign in to comment.