diff --git a/bin/nfreplay.c b/bin/nfreplay.c
index 76a29fb..0aaf2e6 100644
--- a/bin/nfreplay.c
+++ b/bin/nfreplay.c
@@ -108,7 +108,7 @@ static void usage(char *name);
static void send_blast(unsigned int delay );
static void send_data(char *rfile, time_t twin_start, time_t twin_end, uint32_t count,
- unsigned int delay, int confirm, int netflow_version);
+ unsigned int delay, int confirm, int netflow_version, int distribution);
static int FlushBuffer(int confirm);
@@ -133,6 +133,7 @@ static void usage(char *name) {
"-r \tread from file. default: stdin\n"
"-f \tfilter syntaxfile\n"
"-v \tUse netflow version to send flows. Either 5 or 9\n"
+ "-z \tSimulate real time distribution with coefficient\n"
"-t \ttime window for sending packets\n"
"\t\tyyyy/MM/dd.hh:mm:ss[-yyyy/MM/dd.hh:mm:ss]\n"
, name);
@@ -204,13 +205,18 @@ double fps;
} // End of send_blast
static void send_data(char *rfile, time_t twin_start,
- time_t twin_end, uint32_t count, unsigned int delay, int confirm, int netflow_version) {
+ time_t twin_end, uint32_t count, unsigned int delay, int confirm, int netflow_version, int distribution) {
master_record_t master_record;
common_record_t *flow_record;
nffile_t *nffile;
int i, done, ret, again;
uint32_t numflows, cnt;
+ // z-parameter variables
+ struct timeval todayTime, currentTime;
+ double first, last, now, today = 0, reftime = 0;
+ int reducer = 0;
+
#ifdef COMPAT15
int v1_map_done = 0;
#endif
@@ -407,6 +413,31 @@ int v1_map_done = 0;
LogError("Skip unknown record type %i\n", flow_record->type);
}
}
+
+ // z-parameter
+ //first and last are line (tstart and tend) timestamp with milliseconds
+ first = (double) flow_record->first + ((double)flow_record->msec_first / 1000);
+ last = (double) flow_record->last + ((double)flow_record->msec_last / 1000);
+
+ gettimeofday(¤tTime, NULL);
+ now = (double)currentTime.tv_sec + (double)currentTime.tv_usec / 1000000;
+
+ // remove incoherent values
+ if (reftime == 0 && last > 1000000000 && last < 2000000000){
+ reftime = last;
+ gettimeofday(&todayTime, NULL);
+ today = (double)todayTime.tv_sec + (double)todayTime.tv_usec / 1000000;
+ }
+
+ // Reducer avoid to have too much computation: It takes 1 over 3 line to regulate sending time
+ if (reducer % 3 == 0 && distribution != 0 && reftime != 0 && last > 1000000000){
+ while (last - reftime > distribution * (now - today)){
+ gettimeofday(¤tTime, NULL);
+ now = (double)currentTime.tv_sec + (double)currentTime.tv_usec / 1000000;
+ }
+ }
+ reducer++;
+
// Advance pointer by number of bytes for netflow record
flow_record = (common_record_t *)((pointer_addr_t)flow_record + flow_record->size);
@@ -438,7 +469,7 @@ int v1_map_done = 0;
int main( int argc, char **argv ) {
struct stat stat_buff;
char *rfile, *ffile, *filter, *tstring;
-int c, confirm, ffd, ret, blast, netflow_version;
+int c, confirm, ffd, ret, blast, netflow_version, distribution;
unsigned int delay, count, sockbuff_size;
time_t t_start, t_end;
@@ -458,7 +489,8 @@ time_t t_start, t_end;
blast = 0;
verbose = 0;
confirm = 0;
- while ((c = getopt(argc, argv, "46BhH:i:K:L:p:d:c:b:j:r:f:t:v:VY")) != EOF) {
+ distribution = 0;
+ while ((c = getopt(argc, argv, "46BhH:i:K:L:p:d:c:b:j:r:f:t:v:z:VY")) != EOF) {
switch (c) {
case 'h':
usage(argv[0]);
@@ -524,6 +556,9 @@ time_t t_start, t_end;
case 'r':
rfile = optarg;
break;
+ case 'z':
+ distribution = atoi(optarg);
+ break;
case '4':
if ( peer.family == AF_UNSPEC )
peer.family = AF_INET;
@@ -611,7 +646,7 @@ time_t t_start, t_end;
exit(255);
}
- send_data(rfile, t_start, t_end, count, delay, confirm, netflow_version);
+ send_data(rfile, t_start, t_end, count, delay, confirm, netflow_version,distribution);
FreeExtensionMaps(extension_map_list);