Compare commits

..

13 Commits

Author SHA1 Message Date
9a6d6292f5
Fix bulid against libpcap when --enable-readpcap is given 2018-10-09 16:58:34 +03:30
Peter Haag
8da06b599b
Merge pull request #125 from marekbecka/scale_summary
Scale numeric values in summary unless -N is used.
2018-08-18 16:09:28 +02:00
Marek Becka
49587e683b Also scale numeric values also in summary unless -N is used. 2018-07-26 10:03:08 -04:00
Peter Haag
4dafc2dc05 Update man page nfreplay for -z parameter 2018-06-24 14:52:34 +02:00
Peter Haag
3fd30239ff
Merge pull request #120 from LouisSinan/master
nfreplay - Distribution accross time
2018-06-24 14:47:20 +02:00
Peter Haag
9049c9f50f Cleanup comment 2018-06-24 14:42:12 +02:00
Peter Haag
db100d7eb5 Add CISCO ASA elements initiatorPackets (298) responderPackets (299) 2018-06-24 14:18:47 +02:00
Peter Haag
3c0c3f8d33 Ignore OSX .DS_Store files in -R file list 2018-06-24 13:05:20 +02:00
Peter Haag
9d187da615 Add multiple packet repeaters to nfcapd/sfcapd 2018-06-24 12:42:05 +02:00
Peter Haag
214091e490 Fix bookkeeper type - use key_t 2018-06-24 11:12:31 +02:00
LouisSinan
97687605d7
Merge pull request #1 from LouisSinan/Distribution-accross-time
nfreplay - Distribution accross time
2018-05-24 14:12:37 +02:00
LouisSinan
eaecb4c992
nfreplay - Distribution accross time
"z" parameter : Lines are sent with their "real distribution" acrross time (with a speed coefficient)
-z 1 --> 5 minutes of records will be sent in 5 minutes
-z 20 --> 5 minutes of record will be sent in 5/20 = 0.25 minute
2018-05-24 14:09:55 +02:00
Peter Haag
11f9159138 New bookkeeper hash broke NfSen. Fixed. ported back to release 1.6.17 2018-05-06 11:10:51 +02:00
16 changed files with 196 additions and 71 deletions

View File

@ -1,3 +1,14 @@
2018-06-24
- Fix bookkeeper type - use key_t
- Add multiple packet repeaters to nfcapd/sfcapd. Up to 8 repeaters (-R) can be defined.
- Ignore OSX .DS_Store files in -R file list
- Add CISCO ASA elements initiatorPackets (298) responderPackets (299)
- Merge #120 pull request for -z parameter to nfreplay
- Update man page nfreplay
2018-05-06
- New bookkeeper hash broke NfSen. Fixed. ported back to release 1.6.17
2018-04-20 2018-04-20
- Release 1.6.17 - Release 1.6.17

View File

@ -43,6 +43,7 @@
#include <sys/shm.h> #include <sys/shm.h>
#include <sys/sem.h> #include <sys/sem.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/param.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
@ -68,7 +69,7 @@ static bookkeeper_list_t *bookkeeper_list = NULL;
/* function prototypes */ /* function prototypes */
static uint32_t hash(char *str, int flag); static key_t hash(char *str, int flag);
static void sem_lock(int sem_set_id); static void sem_lock(int sem_set_id);
@ -80,18 +81,25 @@ static inline bookkeeper_list_t *Get_bookkeeper_list_entry(bookkeeper_t *bookkee
/* hash: compute hash value of string */ /* hash: compute hash value of string */
#define MULTIPLIER 37 #define MULTIPLIER 37
static uint32_t hash(char *str, int flag) { static key_t hash(char *str, int flag) {
uint32_t h; uint32_t h;
unsigned char *p; unsigned char *p;
char cleanPath[MAXPATHLEN];
if ( realpath(str, cleanPath) == NULL ) {
return -1;
}
h = 0; h = 0;
for (p = (unsigned char*)str; *p != '\0'; p++) for (p = (unsigned char*)cleanPath; *p != '\0'; p++)
h = MULTIPLIER * h + *p; h = MULTIPLIER * h + *p;
if ( flag ) { if ( flag ) {
h = MULTIPLIER * h + 'R'; h = MULTIPLIER * h + 'R';
} }
return h; // or, h % ARRAY_SIZE; // LogError("Bookeeper hash for path: '%s' -> '%s': %u flag: %i", str, cleanPath, h, flag);
return (key_t)h; // or, h % ARRAY_SIZE;
} // End of hash } // End of hash
// locks the semaphore, for exclusive access to the bookkeeping record // locks the semaphore, for exclusive access to the bookkeeping record

View File

@ -798,6 +798,9 @@ printf("DGB: short fts: '%s', filer_first: '%s', filter_last: '%s'\n",
continue; continue;
if ( strstr(ftsent->fts_name, ".stat") != NULL ) if ( strstr(ftsent->fts_name, ".stat") != NULL )
continue; continue;
// skip OSX DS_Store files
if ( strstr(ftsent->fts_name, ".DS_Store") != NULL )
continue;
// skip pcap file // skip pcap file
if ( strstr(ftsent->fts_name, "pcap") != NULL ) if ( strstr(ftsent->fts_name, "pcap") != NULL )
continue; continue;

View File

@ -210,6 +210,7 @@ static struct v9_element_map_s {
{ NF9_IN_BYTES, "bytes", _8bytes, _8bytes, move64_sampling, zero64, COMMON_BLOCK }, { NF9_IN_BYTES, "bytes", _8bytes, _8bytes, move64_sampling, zero64, COMMON_BLOCK },
{ NF9_IN_PACKETS, "packets", _4bytes, _8bytes, move32_sampling, zero64, COMMON_BLOCK }, { NF9_IN_PACKETS, "packets", _4bytes, _8bytes, move32_sampling, zero64, COMMON_BLOCK },
{ NF9_IN_PACKETS, "packets", _8bytes, _8bytes, move64_sampling, zero64, COMMON_BLOCK }, { NF9_IN_PACKETS, "packets", _8bytes, _8bytes, move64_sampling, zero64, COMMON_BLOCK },
{ NF_F_INITIATORPACKETS, "packets", _8bytes, _8bytes, move64_sampling, zero64, COMMON_BLOCK },
{ NF9_FLOWS_AGGR, "flows", _4bytes, _4bytes, move32, zero32, EX_AGGR_FLOWS_4 }, { NF9_FLOWS_AGGR, "flows", _4bytes, _4bytes, move32, zero32, EX_AGGR_FLOWS_4 },
{ NF9_FLOWS_AGGR, "flows", _8bytes, _8bytes, move64, zero64, EX_AGGR_FLOWS_8 }, { NF9_FLOWS_AGGR, "flows", _8bytes, _8bytes, move64, zero64, EX_AGGR_FLOWS_8 },
@ -242,6 +243,7 @@ static struct v9_element_map_s {
{ NF9_OUT_BYTES, "out bytes", _8bytes, _8bytes, move64_sampling, zero64, EX_OUT_BYTES_8 }, { NF9_OUT_BYTES, "out bytes", _8bytes, _8bytes, move64_sampling, zero64, EX_OUT_BYTES_8 },
{ NF9_OUT_PKTS, "out packets", _4bytes, _8bytes, move32_sampling, zero64, EX_OUT_PKG_8 }, { NF9_OUT_PKTS, "out packets", _4bytes, _8bytes, move32_sampling, zero64, EX_OUT_PKG_8 },
{ NF9_OUT_PKTS, "out packets", _8bytes, _8bytes, move64_sampling, zero64, EX_OUT_PKG_8 }, { NF9_OUT_PKTS, "out packets", _8bytes, _8bytes, move64_sampling, zero64, EX_OUT_PKG_8 },
{ NF_F_RESPONDERPACKETS, "out packets", _8bytes, _8bytes, move64_sampling, zero64, EX_OUT_PKG_8 },
{ NF9_IPV6_SRC_ADDR, "V6 src addr", _16bytes, _16bytes, move128, zero128, COMMON_BLOCK }, { NF9_IPV6_SRC_ADDR, "V6 src addr", _16bytes, _16bytes, move128, zero128, COMMON_BLOCK },
{ NF9_IPV6_DST_ADDR, "V6 dst addr", _16bytes, _16bytes, move128, zero128, COMMON_BLOCK }, { NF9_IPV6_DST_ADDR, "V6 dst addr", _16bytes, _16bytes, move128, zero128, COMMON_BLOCK },
{ NF9_IPV6_SRC_MASK, "V6 src mask", _1byte, _1byte, move8, zero8, EX_MULIPLE }, { NF9_IPV6_SRC_MASK, "V6 src mask", _1byte, _1byte, move8, zero8, EX_MULIPLE },
@ -783,7 +785,12 @@ size_t size_required;
* This record is expected in the output stream. If not available * This record is expected in the output stream. If not available
* in the template, assume empty 4 bytes value * in the template, assume empty 4 bytes value
*/ */
PushSequence( table, NF9_IN_PACKETS, &offset, &table->packets, 0); if ( cache.lookup_info[NF_F_INITIATORPACKETS].found ) {
PushSequence( table, NF_F_INITIATORPACKETS, &offset, &table->packets, 0);
dbg_printf("Push NF_F_INITIATORPACKETS\n");
} else {
PushSequence( table, NF9_IN_PACKETS, &offset, &table->packets, 0);
}
// fix: always have 64bit counters due to possible sampling // fix: always have 64bit counters due to possible sampling
SetFlag(table->flags, FLAG_PKG_64); SetFlag(table->flags, FLAG_PKG_64);
@ -866,7 +873,12 @@ size_t size_required;
PushSequence( table, NF9_OUT_PKTS, &offset, &table->out_packets, 0); PushSequence( table, NF9_OUT_PKTS, &offset, &table->out_packets, 0);
break; break;
case EX_OUT_PKG_8: case EX_OUT_PKG_8:
PushSequence( table, NF9_OUT_PKTS, &offset, &table->out_packets, 0); if ( cache.lookup_info[NF_F_RESPONDERPACKETS].found ) {
PushSequence( table, NF_F_RESPONDERPACKETS, &offset, &table->out_packets, 0);
dbg_printf("Push NF_F_RESPONDERPACKETS\n");
} else {
PushSequence( table, NF9_OUT_PKTS, &offset, &table->out_packets, 0);
}
break; break;
case EX_OUT_BYTES_4: case EX_OUT_BYTES_4:
if ( cache.lookup_info[NF_F_REV_FLOW_DELTA_BYTES].found ) { if ( cache.lookup_info[NF_F_REV_FLOW_DELTA_BYTES].found ) {

View File

@ -290,6 +290,11 @@ typedef struct common_header_s {
#define NF_F_XLATE_DST_PORT_84 40004 #define NF_F_XLATE_DST_PORT_84 40004
#define NF_F_FW_EVENT_84 40005 #define NF_F_FW_EVENT_84 40005
// ASA 9.x packet counters: initiatorPackets and responderPackets
// see https://www.iana.org/assignments/ipfix/ipfix.xhtml
#define NF_F_INITIATORPACKETS 298
#define NF_F_RESPONDERPACKETS 299
// Cisco ASR 1000 series NEL extension - Nat Event Logging // Cisco ASR 1000 series NEL extension - Nat Event Logging
#define NF_N_NAT_EVENT 230 #define NF_N_NAT_EVENT 230
#define NF_N_INGRESS_VRFID 234 #define NF_N_INGRESS_VRFID 234

View File

@ -658,7 +658,7 @@ char *Get_fwd_status_name(uint32_t id) {
} // End of Get_fwd_status_name } // End of Get_fwd_status_name
void format_file_block_header(void *header, char ** s, int tag) { void format_file_block_header(void *header, char **s, int tag) {
data_block_header_t *h = (data_block_header_t *)header; data_block_header_t *h = (data_block_header_t *)header;
snprintf(data_string,STRINGSIZE-1 ,"" snprintf(data_string,STRINGSIZE-1 ,""
@ -673,7 +673,7 @@ data_block_header_t *h = (data_block_header_t *)header;
} // End of format_file_block_header } // End of format_file_block_header
void format_file_block_record(void *record, char ** s, int tag) { void format_file_block_record(void *record, char **s, int tag) {
char *_s, as[IP_STRING_LEN], ds[IP_STRING_LEN], datestr1[64], datestr2[64], datestr3[64], flags_str[16]; char *_s, as[IP_STRING_LEN], ds[IP_STRING_LEN], datestr1[64], datestr2[64], datestr3[64], flags_str[16];
char s_snet[IP_STRING_LEN], s_dnet[IP_STRING_LEN], s_proto[32]; char s_snet[IP_STRING_LEN], s_dnet[IP_STRING_LEN], s_proto[32];
int i, id; int i, id;

View File

@ -146,7 +146,7 @@ static void daemonize(void);
static void SetPriv(char *userid, char *groupid ); static void SetPriv(char *userid, char *groupid );
static void run(packet_function_t receive_packet, int socket, send_peer_t peer, static void run(packet_function_t receive_packet, int socket, repeater_t *repeater,
time_t twin, time_t t_begin, int report_seq, int use_subdirs, char *time_extension, int compress); time_t twin, time_t t_begin, int report_seq, int use_subdirs, char *time_extension, int compress);
/* Functions */ /* Functions */
@ -166,7 +166,7 @@ static void usage(char *name) {
"-H Add port histogram data to flow file.(default 'no')\n" "-H Add port histogram data to flow file.(default 'no')\n"
"-n Ident,IP,logdir\tAdd this flow source - multiple streams\n" "-n Ident,IP,logdir\tAdd this flow source - multiple streams\n"
"-P pidfile\tset the PID file\n" "-P pidfile\tset the PID file\n"
"-R IP[/port]\tRepeat incoming packets to IP address/port\n" "-R IP[/port]\tRepeat incoming packets to IP address/port. Max 8 repeaters.\n"
"-s rate\tset default sampling rate (default 1)\n" "-s rate\tset default sampling rate (default 1)\n"
"-x process\tlaunch process after a new file becomes available\n" "-x process\tlaunch process after a new file becomes available\n"
"-z\t\tLZO compress flows in output file.\n" "-z\t\tLZO compress flows in output file.\n"
@ -358,7 +358,7 @@ int err;
#include "nffile_inline.c" #include "nffile_inline.c"
#include "collector_inline.c" #include "collector_inline.c"
static void run(packet_function_t receive_packet, int socket, send_peer_t peer, static void run(packet_function_t receive_packet, int socket, repeater_t *repeater,
time_t twin, time_t t_begin, int report_seq, int use_subdirs, char *time_extension, int compress) { time_t twin, time_t t_begin, int report_seq, int use_subdirs, char *time_extension, int compress) {
common_flow_header_t *nf_header; common_flow_header_t *nf_header;
FlowSource_t *fs; FlowSource_t *fs;
@ -422,6 +422,7 @@ srecord_t *commbuff;
*/ */
while ( 1 ) { while ( 1 ) {
struct timeval tv; struct timeval tv;
int i;
/* read next bunch of data into beginn of input buffer */ /* read next bunch of data into beginn of input buffer */
if ( !done) { if ( !done) {
@ -443,12 +444,15 @@ srecord_t *commbuff;
continue; continue;
} }
if ( peer.hostname ) { i = 0;
while ( repeater[i].hostname && (i < MAX_REPEATERS)) {
ssize_t len; ssize_t len;
len = sendto(peer.sockfd, in_buff, cnt, 0, (struct sockaddr *)&(peer.addr), peer.addrlen); len = sendto(repeater[i].sockfd, in_buff, cnt, 0,
(struct sockaddr *)&(repeater[i].addr), repeater[i].addrlen);
if ( len < 0 ) { if ( len < 0 ) {
LogError("ERROR: sendto(): %s", strerror(errno)); LogError("ERROR: sendto(): %s", strerror(errno));
} }
i++;
} }
} }
@ -745,14 +749,14 @@ char *userid, *groupid, *checkptr, *listenport, *mcastgroup, *extension_tags;
char *Ident, *dynsrcdir, *time_extension, pidfile[MAXPATHLEN]; char *Ident, *dynsrcdir, *time_extension, pidfile[MAXPATHLEN];
struct stat fstat; struct stat fstat;
packet_function_t receive_packet; packet_function_t receive_packet;
send_peer_t peer; repeater_t repeater[MAX_REPEATERS];
FlowSource_t *fs; FlowSource_t *fs;
struct sigaction act; struct sigaction act;
int family, bufflen; int family, bufflen;
time_t twin, t_start; time_t twin, t_start;
int sock, synctime, do_daemonize, expire, spec_time_extension, report_sequence; int sock, synctime, do_daemonize, expire, spec_time_extension, report_sequence;
int subdir_index, sampling_rate, compress; int subdir_index, sampling_rate, compress;
int c; int c, i;
#ifdef PCAP #ifdef PCAP
char *pcap_file; char *pcap_file;
@ -780,8 +784,10 @@ char *pcap_file;
expire = 0; expire = 0;
sampling_rate = 1; sampling_rate = 1;
compress = NOT_COMPRESSED; compress = NOT_COMPRESSED;
memset((void *)&peer, 0, sizeof(send_peer_t)); memset((void *)&repeater, 0, sizeof(repeater));
peer.family = AF_UNSPEC; for ( i = 0; i < MAX_REPEATERS; i++ ) {
repeater[i].family = AF_UNSPEC;
}
Ident = "none"; Ident = "none";
FlowSource = NULL; FlowSource = NULL;
extension_tags = DefaultExtensions; extension_tags = DefaultExtensions;
@ -886,14 +892,23 @@ char *pcap_file;
pidfile[MAXPATHLEN-1] = 0; pidfile[MAXPATHLEN-1] = 0;
break; break;
case 'R': { case 'R': {
char *port, *hostname;
char *p = strchr(optarg, '/'); char *p = strchr(optarg, '/');
int i = 0;
if ( p ) { if ( p ) {
*p++ = '\0'; *p++ = '\0';
peer.port = strdup(p); port = strdup(p);
} else { } else {
peer.port = DEFAULTCISCOPORT; port = DEFAULTCISCOPORT;
} }
peer.hostname = strdup(optarg); hostname = strdup(optarg);
while ( repeater[i].hostname && (i < MAX_REPEATERS) ) i++;
if ( i == MAX_REPEATERS ) {
fprintf(stderr, "Too many packet repeaters! Max: %i repeaters allowed.\n", MAX_REPEATERS);
exit(255);
}
repeater[i].hostname = hostname;
repeater[i].port = port;
break; } break; }
case 'r': case 'r':
@ -1040,12 +1055,14 @@ char *pcap_file;
exit(255); exit(255);
} }
if ( peer.hostname ) { i = 0;
peer.sockfd = Unicast_send_socket (peer.hostname, peer.port, peer.family, bufflen, while ( repeater[i].hostname && (i < MAX_REPEATERS) ) {
&peer.addr, &peer.addrlen ); repeater[i].sockfd = Unicast_send_socket (repeater[i].hostname, repeater[i].port, repeater[i].family, bufflen,
if ( peer.sockfd <= 0 ) &repeater[i].addr, &repeater[i].addrlen );
if ( repeater[i].sockfd <= 0 )
exit(255); exit(255);
LogInfo("Replay flows to host: %s port: %s", peer.hostname, peer.port); LogInfo("Replay flows to host: %s port: %s", repeater[i].hostname, repeater[i].port);
i++;
} }
if ( sampling_rate < 0 ) { if ( sampling_rate < 0 ) {
@ -1205,7 +1222,7 @@ char *pcap_file;
sigaction(SIGCHLD, &act, NULL); sigaction(SIGCHLD, &act, NULL);
LogInfo("Startup."); LogInfo("Startup.");
run(receive_packet, sock, peer, twin, t_start, report_sequence, subdir_index, run(receive_packet, sock, repeater, twin, t_start, report_sequence, subdir_index,
time_extension, compress); time_extension, compress);
close(sock); close(sock);
kill_launcher(launcher_pid); kill_launcher(launcher_pid);

View File

@ -348,11 +348,11 @@ char bps_str[NUMBER_STRING_SIZE], pps_str[NUMBER_STRING_SIZE], bpp_str[NUMBER_
(long long unsigned)stat_record->numpackets, (long long unsigned)bps, (long long unsigned)stat_record->numpackets, (long long unsigned)bps,
(long long unsigned)pps, (long long unsigned)bpp ); (long long unsigned)pps, (long long unsigned)bpp );
} else { } else {
format_number(stat_record->numbytes, byte_str, DONT_SCALE_NUMBER, VAR_LENGTH); format_number(stat_record->numbytes, byte_str, DO_SCALE_NUMBER, VAR_LENGTH);
format_number(stat_record->numpackets, packet_str, DONT_SCALE_NUMBER, VAR_LENGTH); format_number(stat_record->numpackets, packet_str, DO_SCALE_NUMBER, VAR_LENGTH);
format_number(bps, bps_str, DONT_SCALE_NUMBER, VAR_LENGTH); format_number(bps, bps_str, DO_SCALE_NUMBER, VAR_LENGTH);
format_number(pps, pps_str, DONT_SCALE_NUMBER, VAR_LENGTH); format_number(pps, pps_str, DO_SCALE_NUMBER, VAR_LENGTH);
format_number(bpp, bpp_str, DONT_SCALE_NUMBER, VAR_LENGTH); format_number(bpp, bpp_str, DO_SCALE_NUMBER, VAR_LENGTH);
printf("Summary: total flows: %llu, total bytes: %s, total packets: %s, avg bps: %s, avg pps: %s, avg bpp: %s\n", printf("Summary: total flows: %llu, total bytes: %s, total packets: %s, avg bps: %s, avg pps: %s, avg bpp: %s\n",
(unsigned long long)stat_record->numflows, byte_str, packet_str, bps_str, pps_str, bpp_str ); (unsigned long long)stat_record->numflows, byte_str, packet_str, bps_str, pps_str, bpp_str );
} }

View File

@ -178,12 +178,11 @@ int error, p, sockfd;
int Unicast_send_socket (const char *hostname, const char *sendport, int family, int Unicast_send_socket (const char *hostname, const char *sendport, int family,
unsigned int wmem_size, struct sockaddr_storage *addr, int *addrlen) { unsigned int wmem_size, struct sockaddr_storage *addr, int *addrlen) {
struct addrinfo hints, *res, *ressave; struct addrinfo hints, *res, *ressave;
int n, sockfd; int error, sockfd;
unsigned int wmem_actual; unsigned int wmem_actual;
socklen_t optlen; socklen_t optlen;
if ( !hostname || !sendport ) { if ( !hostname || !sendport ) {
fprintf(stderr, "hostname and listen port required!\n");
LogError("hostname and listen port required!"); LogError("hostname and listen port required!");
return -1; return -1;
} }
@ -194,10 +193,9 @@ socklen_t optlen;
hints.ai_family = family; hints.ai_family = family;
hints.ai_socktype = SOCK_DGRAM; hints.ai_socktype = SOCK_DGRAM;
n = getaddrinfo(hostname, sendport, &hints, &res); error = getaddrinfo(hostname, sendport, &hints, &res);
if ( error ) {
if ( n < 0 ) { LogError("getaddrinfo() error: %s", gai_strerror(error));
fprintf(stderr, "getaddrinfo error: [%s]\n", strerror(errno));
return -1; return -1;
} }
@ -205,27 +203,28 @@ socklen_t optlen;
sockfd = -1; sockfd = -1;
while (res) { while (res) {
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if ( sockfd < 0 ) {
if ( !(sockfd < 0) ) { LogError("socket() error: could not open the requested socket: %s", strerror (errno));
} else {
// socket call was successsful // socket call was successsful
if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0) { if (connect(sockfd, res->ai_addr, res->ai_addrlen) < 0) {
// unsuccessful connect :(
LogError("connect() error: could not open the requested socket: %s", strerror (errno));
close(sockfd);
sockfd = -1;
} else {
// connect successful - we are done // connect successful - we are done
close(sockfd); close(sockfd);
// ok - we need now an unconnected socket // ok - we need now an unconnected socket
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
break; break;
} }
// unsuccessful connect :(
close(sockfd);
sockfd = -1;
} }
res=res->ai_next; res=res->ai_next;
} }
if (sockfd < 0) { if (sockfd < 0) {
freeaddrinfo(ressave); freeaddrinfo(ressave);
fprintf(stderr, "Send socket error: could not open the requested socket: %s\n", strerror (errno));
LogError("Send socket error: could not open the requested socket: %s", strerror (errno));
return -1; return -1;
} }

View File

@ -57,6 +57,17 @@ typedef struct send_peer_s {
void *endp; void *endp;
} send_peer_t; } send_peer_t;
typedef struct repeater_s {
char *hostname;
char *port;
struct sockaddr_storage addr;
int addrlen;
int family;
int sockfd;
} repeater_t;
#define MAX_REPEATERS 8
/* Function prototypes */ /* Function prototypes */
int Unicast_receive_socket(const char *bindhost, const char *listenport, int family, int sockbuflen ); int Unicast_receive_socket(const char *bindhost, const char *listenport, int family, int sockbuflen );

View File

@ -108,7 +108,7 @@ static void usage(char *name);
static void send_blast(unsigned int delay ); static void send_blast(unsigned int delay );
static void send_data(char *rfile, time_t twin_start, time_t twin_end, uint32_t count, 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); static int FlushBuffer(int confirm);
@ -133,6 +133,7 @@ static void usage(char *name) {
"-r <input>\tread from file. default: stdin\n" "-r <input>\tread from file. default: stdin\n"
"-f <filter>\tfilter syntaxfile\n" "-f <filter>\tfilter syntaxfile\n"
"-v <version>\tUse netflow version to send flows. Either 5 or 9\n" "-v <version>\tUse netflow version to send flows. Either 5 or 9\n"
"-z <distribution>\tSimulate real time distribution with coefficient\n"
"-t <time>\ttime window for sending packets\n" "-t <time>\ttime window for sending packets\n"
"\t\tyyyy/MM/dd.hh:mm:ss[-yyyy/MM/dd.hh:mm:ss]\n" "\t\tyyyy/MM/dd.hh:mm:ss[-yyyy/MM/dd.hh:mm:ss]\n"
, name); , name);
@ -204,13 +205,18 @@ double fps;
} // End of send_blast } // End of send_blast
static void send_data(char *rfile, time_t twin_start, 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; master_record_t master_record;
common_record_t *flow_record; common_record_t *flow_record;
nffile_t *nffile; nffile_t *nffile;
int i, done, ret, again; int i, done, ret, again;
uint32_t numflows, cnt; uint32_t numflows, cnt;
// z-parameter variables
struct timeval todayTime, currentTime;
double first, last, now, today = 0, reftime = 0;
int reducer = 0;
#ifdef COMPAT15 #ifdef COMPAT15
int v1_map_done = 0; int v1_map_done = 0;
#endif #endif
@ -407,6 +413,31 @@ int v1_map_done = 0;
LogError("Skip unknown record type %i\n", flow_record->type); 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(&currentTime, 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(&currentTime, NULL);
now = (double)currentTime.tv_sec + (double)currentTime.tv_usec / 1000000;
}
}
reducer++;
// Advance pointer by number of bytes for netflow record // Advance pointer by number of bytes for netflow record
flow_record = (common_record_t *)((pointer_addr_t)flow_record + flow_record->size); 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 ) { int main( int argc, char **argv ) {
struct stat stat_buff; struct stat stat_buff;
char *rfile, *ffile, *filter, *tstring; 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; unsigned int delay, count, sockbuff_size;
time_t t_start, t_end; time_t t_start, t_end;
@ -458,7 +489,8 @@ time_t t_start, t_end;
blast = 0; blast = 0;
verbose = 0; verbose = 0;
confirm = 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) { switch (c) {
case 'h': case 'h':
usage(argv[0]); usage(argv[0]);
@ -524,6 +556,9 @@ time_t t_start, t_end;
case 'r': case 'r':
rfile = optarg; rfile = optarg;
break; break;
case 'z':
distribution = atoi(optarg);
break;
case '4': case '4':
if ( peer.family == AF_UNSPEC ) if ( peer.family == AF_UNSPEC )
peer.family = AF_INET; peer.family = AF_INET;
@ -611,7 +646,7 @@ time_t t_start, t_end;
exit(255); 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); FreeExtensionMaps(extension_map_list);

View File

@ -1,4 +1,5 @@
/* /*
* Copyright (c) 2018, Peter Haag
* Copyright (c) 2017, Peter Haag * Copyright (c) 2017, Peter Haag
* Copyright (c) 2016, Peter Haag * Copyright (c) 2016, Peter Haag
* Copyright (c) 2014, Peter Haag * Copyright (c) 2014, Peter Haag
@ -124,7 +125,7 @@ static void daemonize(void);
static void SetPriv(char *userid, char *groupid ); static void SetPriv(char *userid, char *groupid );
static void run(packet_function_t receive_packet, int socket, send_peer_t peer, static void run(packet_function_t receive_packet, int socket, repeater_t *repeater,
time_t twin, time_t t_begin, int report_seq, int use_subdirs, char *time_extension, int compress); time_t twin, time_t t_begin, int report_seq, int use_subdirs, char *time_extension, int compress);
/* Functions */ /* Functions */
@ -144,7 +145,7 @@ static void usage(char *name) {
"-H Add port histogram data to flow file.(default 'no')\n" "-H Add port histogram data to flow file.(default 'no')\n"
"-n Ident,IP,logdir\tAdd this flow source - multiple streams\n" "-n Ident,IP,logdir\tAdd this flow source - multiple streams\n"
"-P pidfile\tset the PID file\n" "-P pidfile\tset the PID file\n"
"-R IP[/port]\tRepeat incoming packets to IP address/port\n" "-R IP[/port]\tRepeat incoming packets to IP address/port. Max 8 repeaters\n"
"-x process\tlaunch process after a new file becomes available\n" "-x process\tlaunch process after a new file becomes available\n"
"-z\t\tLZO compress flows in output file.\n" "-z\t\tLZO compress flows in output file.\n"
"-y\t\tLZ4 compress flows in output file.\n" "-y\t\tLZ4 compress flows in output file.\n"
@ -332,7 +333,7 @@ int err;
#include "nffile_inline.c" #include "nffile_inline.c"
#include "collector_inline.c" #include "collector_inline.c"
static void run(packet_function_t receive_packet, int socket, send_peer_t peer, static void run(packet_function_t receive_packet, int socket, repeater_t *repeater,
time_t twin, time_t t_begin, int report_seq, int use_subdirs, char *time_extension, int compress) { time_t twin, time_t t_begin, int report_seq, int use_subdirs, char *time_extension, int compress) {
FlowSource_t *fs; FlowSource_t *fs;
struct sockaddr_storage sf_sender; struct sockaddr_storage sf_sender;
@ -393,6 +394,7 @@ srecord_t *commbuff;
*/ */
while ( 1 ) { while ( 1 ) {
struct timeval tv; struct timeval tv;
int i;
/* read next bunch of data into beginn of input buffer */ /* read next bunch of data into beginn of input buffer */
if ( !done) { if ( !done) {
@ -415,12 +417,15 @@ srecord_t *commbuff;
continue; continue;
} }
if ( peer.hostname ) { i = 0;
while ( repeater[i].hostname && (i < MAX_REPEATERS)) {
ssize_t len; ssize_t len;
len = sendto(peer.sockfd, in_buff, cnt, 0, (struct sockaddr *)&(peer.addr), peer.addrlen); len = sendto(repeater[i].sockfd, in_buff, cnt, 0,
(struct sockaddr *)&(repeater[i].addr), repeater[i].addrlen);
if ( len < 0 ) { if ( len < 0 ) {
LogError("ERROR: sendto(): %s", strerror(errno)); LogError("ERROR: sendto(): %s", strerror(errno));
} }
i++;
} }
} }
@ -658,14 +663,14 @@ char *userid, *groupid, *checkptr, *listenport, *mcastgroup, *extension_tags;
char *Ident, *pcap_file, *time_extension, pidfile[MAXPATHLEN]; char *Ident, *pcap_file, *time_extension, pidfile[MAXPATHLEN];
struct stat fstat; struct stat fstat;
packet_function_t receive_packet; packet_function_t receive_packet;
send_peer_t peer; repeater_t repeater[MAX_REPEATERS];
FlowSource_t *fs; FlowSource_t *fs;
struct sigaction act; struct sigaction act;
int family, bufflen; int family, bufflen;
time_t twin, t_start; time_t twin, t_start;
int sock, synctime, do_daemonize, expire, spec_time_extension, report_sequence; int sock, synctime, do_daemonize, expire, spec_time_extension, report_sequence;
int subdir_index, compress; int subdir_index, compress;
int c; int c, i;
receive_packet = recvfrom; receive_packet = recvfrom;
verbose = synctime = do_daemonize = 0; verbose = synctime = do_daemonize = 0;
@ -687,8 +692,10 @@ int c;
expire = 0; expire = 0;
spec_time_extension = 0; spec_time_extension = 0;
compress = NOT_COMPRESSED; compress = NOT_COMPRESSED;
memset((void *)&peer, 0, sizeof(send_peer_t)); memset((void *)&repeater, 0, sizeof(repeater));
peer.family = AF_UNSPEC; for ( i = 0; i < MAX_REPEATERS; i++ ) {
repeater[i].family = AF_UNSPEC;
}
Ident = "none"; Ident = "none";
FlowSource = NULL; FlowSource = NULL;
extension_tags = DefaultExtensions; extension_tags = DefaultExtensions;
@ -794,14 +801,23 @@ int c;
pidfile[MAXPATHLEN-1] = 0; pidfile[MAXPATHLEN-1] = 0;
break; break;
case 'R': { case 'R': {
char *port, *hostname;
char *p = strchr(optarg, '/'); char *p = strchr(optarg, '/');
int i = 0;
if ( p ) { if ( p ) {
*p++ = '\0'; *p++ = '\0';
peer.port = strdup(p); port = strdup(p);
} else { } else {
peer.port = DEFAULTSFLOWPORT; port = DEFAULTSFLOWPORT;
} }
peer.hostname = strdup(optarg); hostname = strdup(optarg);
while ( repeater[i].hostname && (i < MAX_REPEATERS) ) i++;
if ( i == MAX_REPEATERS ) {
fprintf(stderr, "Too many packet repeaters! Max: %i repeaters allowed.\n", MAX_REPEATERS);
exit(255);
}
repeater[i].hostname = hostname;
repeater[i].port = port;
break; } break; }
case 'r': case 'r':
@ -914,11 +930,14 @@ int c;
exit(255); exit(255);
} }
if ( peer.hostname ) { i = 0;
peer.sockfd = Unicast_send_socket (peer.hostname, peer.port, peer.family, bufflen, while ( repeater[i].hostname && (i < MAX_REPEATERS) ) {
&peer.addr, &peer.addrlen ); repeater[i].sockfd = Unicast_send_socket (repeater[i].hostname, repeater[i].port, repeater[i].family, bufflen,
if ( peer.sockfd <= 0 ) &repeater[i].addr, &repeater[i].addrlen );
if ( repeater[i].sockfd <= 0 )
exit(255); exit(255);
LogInfo("Replay flows to host: %s port: %s", repeater[i].hostname, repeater[i].port);
i++;
} }
SetPriv(userid, groupid); SetPriv(userid, groupid);
@ -1071,7 +1090,7 @@ int c;
sigaction(SIGCHLD, &act, NULL); sigaction(SIGCHLD, &act, NULL);
LogInfo("Startup."); LogInfo("Startup.");
run(receive_packet, sock, peer, twin, t_start, report_sequence, subdir_index, run(receive_packet, sock, repeater, twin, t_start, report_sequence, subdir_index,
time_extension, compress); time_extension, compress);
close(sock); close(sock);
kill_launcher(launcher_pid); kill_launcher(launcher_pid);

View File

@ -104,7 +104,7 @@ fi
) )
AC_ARG_WITH(pcappath, AC_ARG_WITH(pcappath,
[ --with-pcappath=PATH Expect RRD installed in PATH; default /usr/local], [ --with-pcappath=PATH Expect libpcap installed in PATH; default /usr/local],
if test "x$with_pcappath" = "xyes" ; then if test "x$with_pcappath" = "xyes" ; then
CPPFLAGS="${CPPFLAGS} -I/usr/local/include" CPPFLAGS="${CPPFLAGS} -I/usr/local/include"
LDFLAGS="${LDFLAGS} -L/usr/local/lib" LDFLAGS="${LDFLAGS} -L/usr/local/lib"
@ -242,7 +242,7 @@ AC_ARG_ENABLE(nfpcapd,
cat >>config.h <<_ACEOF cat >>config.h <<_ACEOF
#define HAVE_LIBPCAP 1 #define HAVE_LIBPCAP 1
_ACEOF _ACEOF
RRD_LIBS="-lpcap" PCAP_LIBS="-lpcap"
AC_SUBST(PCAP_LIBS) AC_SUBST(PCAP_LIBS)
] ]
, AC_MSG_ERROR(Can not link libpcap. Please specify --with-pcappath=.. configure failed! )) , AC_MSG_ERROR(Can not link libpcap. Please specify --with-pcappath=.. configure failed! ))

View File

@ -65,7 +65,7 @@ Join the specified IPv4 or IPv6 multicast group for listening.
Enable packet repeater. Send all incoming packets to another \fIhost\fR and \fIport\fR. Enable packet repeater. Send all incoming packets to another \fIhost\fR and \fIport\fR.
\fIhost\fR is either a valid IPv4/IPv6 address, or a valid symbolic hostname, which resolves to \fIhost\fR is either a valid IPv4/IPv6 address, or a valid symbolic hostname, which resolves to
a IPv6 or IPv4 address. \fIport\fR may be omitted and defaults to port 9995. Note: Due to IPv4/IPv6 a IPv6 or IPv4 address. \fIport\fR may be omitted and defaults to port 9995. Note: Due to IPv4/IPv6
accepted addresses the port separator is '/'. accepted addresses the port separator is '/'. Up to 8 repeaters my be defined.
.TP 3 .TP 3
.B -I \fIIdentString ( capital letter i ) .B -I \fIIdentString ( capital letter i )
Specifies an ident string, which describes the source e.g. the Specifies an ident string, which describes the source e.g. the

View File

@ -57,6 +57,11 @@ the time spec may be omitted e.g YYYY/MM/dd expands to
YYYY/MM/dd.00:00:00\-YYYY/MM/dd.23:59:59 and sends all flow from a YYYY/MM/dd.00:00:00\-YYYY/MM/dd.23:59:59 and sends all flow from a
given day. given day.
.TP 3 .TP 3
.B -z \fInum
Flows are sent with their "real distribution" acrross time (with a speed coefficient)
-z 1 : 5 minutes of records will be sent in 5 minutes.
-z 20 : 5 minutes of record will be sent in 5/20 = 0.25 minutes.
.TP 3
.B -c \fInum .B -c \fInum
Limit number of records to send to the first \fInum\fR flows. Limit number of records to send to the first \fInum\fR flows.
.TP 3 .TP 3

View File

@ -42,7 +42,7 @@ Join the specified IPv6 or IPv6 multicast group for listening.
Enable packet repeater. Send all incoming packets to another \fIhost\fR and \fIport\fR. Enable packet repeater. Send all incoming packets to another \fIhost\fR and \fIport\fR.
\fIhost\fR is either a valid IPv4/IPv6 address, or a valid simbolic hostname, which resolves to \fIhost\fR is either a valid IPv4/IPv6 address, or a valid simbolic hostname, which resolves to
a IPv6 or IPv4 address. \fIport\fR may be omitted and defaults to port 6343. Note: Due to IPv4/IPv6 a IPv6 or IPv4 address. \fIport\fR may be omitted and defaults to port 6343. Note: Due to IPv4/IPv6
accepted addresses the port separator is '/'. accepted addresses the port separator is '/'. Up to 8 repeaters my be defined.
.TP 3 .TP 3
.B -I \fIIdentString ( capital letter i ) .B -I \fIIdentString ( capital letter i )
Specifies an ident string, which describes the source e.g. the Specifies an ident string, which describes the source e.g. the