Compare commits
13 Commits
Author | SHA1 | Date | |
---|---|---|---|
9a6d6292f5 | |||
|
8da06b599b | ||
|
49587e683b | ||
|
4dafc2dc05 | ||
|
3fd30239ff | ||
|
9049c9f50f | ||
|
db100d7eb5 | ||
|
3c0c3f8d33 | ||
|
9d187da615 | ||
|
214091e490 | ||
|
97687605d7 | ||
|
eaecb4c992 | ||
|
11f9159138 |
11
ChangeLog
11
ChangeLog
@ -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
|
||||
- Release 1.6.17
|
||||
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include <sys/shm.h>
|
||||
#include <sys/sem.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
@ -68,7 +69,7 @@ static bookkeeper_list_t *bookkeeper_list = NULL;
|
||||
|
||||
/* 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);
|
||||
|
||||
@ -80,18 +81,25 @@ static inline bookkeeper_list_t *Get_bookkeeper_list_entry(bookkeeper_t *bookkee
|
||||
|
||||
/* hash: compute hash value of string */
|
||||
#define MULTIPLIER 37
|
||||
static uint32_t hash(char *str, int flag) {
|
||||
static key_t hash(char *str, int flag) {
|
||||
uint32_t h;
|
||||
unsigned char *p;
|
||||
char cleanPath[MAXPATHLEN];
|
||||
|
||||
if ( realpath(str, cleanPath) == NULL ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
h = 0;
|
||||
for (p = (unsigned char*)str; *p != '\0'; p++)
|
||||
for (p = (unsigned char*)cleanPath; *p != '\0'; p++)
|
||||
h = MULTIPLIER * h + *p;
|
||||
|
||||
if ( flag ) {
|
||||
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
|
||||
|
||||
// locks the semaphore, for exclusive access to the bookkeeping record
|
||||
|
@ -798,6 +798,9 @@ printf("DGB: short fts: '%s', filer_first: '%s', filter_last: '%s'\n",
|
||||
continue;
|
||||
if ( strstr(ftsent->fts_name, ".stat") != NULL )
|
||||
continue;
|
||||
// skip OSX DS_Store files
|
||||
if ( strstr(ftsent->fts_name, ".DS_Store") != NULL )
|
||||
continue;
|
||||
// skip pcap file
|
||||
if ( strstr(ftsent->fts_name, "pcap") != NULL )
|
||||
continue;
|
||||
|
@ -210,6 +210,7 @@ static struct v9_element_map_s {
|
||||
{ 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", _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", _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_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 },
|
||||
{ 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_DST_ADDR, "V6 dst addr", _16bytes, _16bytes, move128, zero128, COMMON_BLOCK },
|
||||
{ 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
|
||||
* 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
|
||||
SetFlag(table->flags, FLAG_PKG_64);
|
||||
|
||||
@ -866,7 +873,12 @@ size_t size_required;
|
||||
PushSequence( table, NF9_OUT_PKTS, &offset, &table->out_packets, 0);
|
||||
break;
|
||||
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;
|
||||
case EX_OUT_BYTES_4:
|
||||
if ( cache.lookup_info[NF_F_REV_FLOW_DELTA_BYTES].found ) {
|
||||
|
@ -290,6 +290,11 @@ typedef struct common_header_s {
|
||||
#define NF_F_XLATE_DST_PORT_84 40004
|
||||
#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
|
||||
#define NF_N_NAT_EVENT 230
|
||||
#define NF_N_INGRESS_VRFID 234
|
||||
|
@ -658,7 +658,7 @@ char *Get_fwd_status_name(uint32_t id) {
|
||||
|
||||
} // 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;
|
||||
|
||||
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
|
||||
|
||||
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_snet[IP_STRING_LEN], s_dnet[IP_STRING_LEN], s_proto[32];
|
||||
int i, id;
|
||||
|
53
bin/nfcapd.c
53
bin/nfcapd.c
@ -146,7 +146,7 @@ static void daemonize(void);
|
||||
|
||||
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);
|
||||
|
||||
/* Functions */
|
||||
@ -166,7 +166,7 @@ static void usage(char *name) {
|
||||
"-H Add port histogram data to flow file.(default 'no')\n"
|
||||
"-n Ident,IP,logdir\tAdd this flow source - multiple streams\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"
|
||||
"-x process\tlaunch process after a new file becomes available\n"
|
||||
"-z\t\tLZO compress flows in output file.\n"
|
||||
@ -358,7 +358,7 @@ int err;
|
||||
#include "nffile_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) {
|
||||
common_flow_header_t *nf_header;
|
||||
FlowSource_t *fs;
|
||||
@ -422,6 +422,7 @@ srecord_t *commbuff;
|
||||
*/
|
||||
while ( 1 ) {
|
||||
struct timeval tv;
|
||||
int i;
|
||||
|
||||
/* read next bunch of data into beginn of input buffer */
|
||||
if ( !done) {
|
||||
@ -443,12 +444,15 @@ srecord_t *commbuff;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( peer.hostname ) {
|
||||
i = 0;
|
||||
while ( repeater[i].hostname && (i < MAX_REPEATERS)) {
|
||||
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 ) {
|
||||
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];
|
||||
struct stat fstat;
|
||||
packet_function_t receive_packet;
|
||||
send_peer_t peer;
|
||||
repeater_t repeater[MAX_REPEATERS];
|
||||
FlowSource_t *fs;
|
||||
struct sigaction act;
|
||||
int family, bufflen;
|
||||
time_t twin, t_start;
|
||||
int sock, synctime, do_daemonize, expire, spec_time_extension, report_sequence;
|
||||
int subdir_index, sampling_rate, compress;
|
||||
int c;
|
||||
int c, i;
|
||||
#ifdef PCAP
|
||||
char *pcap_file;
|
||||
|
||||
@ -780,8 +784,10 @@ char *pcap_file;
|
||||
expire = 0;
|
||||
sampling_rate = 1;
|
||||
compress = NOT_COMPRESSED;
|
||||
memset((void *)&peer, 0, sizeof(send_peer_t));
|
||||
peer.family = AF_UNSPEC;
|
||||
memset((void *)&repeater, 0, sizeof(repeater));
|
||||
for ( i = 0; i < MAX_REPEATERS; i++ ) {
|
||||
repeater[i].family = AF_UNSPEC;
|
||||
}
|
||||
Ident = "none";
|
||||
FlowSource = NULL;
|
||||
extension_tags = DefaultExtensions;
|
||||
@ -886,14 +892,23 @@ char *pcap_file;
|
||||
pidfile[MAXPATHLEN-1] = 0;
|
||||
break;
|
||||
case 'R': {
|
||||
char *port, *hostname;
|
||||
char *p = strchr(optarg, '/');
|
||||
int i = 0;
|
||||
if ( p ) {
|
||||
*p++ = '\0';
|
||||
peer.port = strdup(p);
|
||||
port = strdup(p);
|
||||
} 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; }
|
||||
case 'r':
|
||||
@ -1040,12 +1055,14 @@ char *pcap_file;
|
||||
exit(255);
|
||||
}
|
||||
|
||||
if ( peer.hostname ) {
|
||||
peer.sockfd = Unicast_send_socket (peer.hostname, peer.port, peer.family, bufflen,
|
||||
&peer.addr, &peer.addrlen );
|
||||
if ( peer.sockfd <= 0 )
|
||||
i = 0;
|
||||
while ( repeater[i].hostname && (i < MAX_REPEATERS) ) {
|
||||
repeater[i].sockfd = Unicast_send_socket (repeater[i].hostname, repeater[i].port, repeater[i].family, bufflen,
|
||||
&repeater[i].addr, &repeater[i].addrlen );
|
||||
if ( repeater[i].sockfd <= 0 )
|
||||
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 ) {
|
||||
@ -1205,7 +1222,7 @@ char *pcap_file;
|
||||
sigaction(SIGCHLD, &act, NULL);
|
||||
|
||||
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);
|
||||
close(sock);
|
||||
kill_launcher(launcher_pid);
|
||||
|
10
bin/nfdump.c
10
bin/nfdump.c
@ -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)pps, (long long unsigned)bpp );
|
||||
} else {
|
||||
format_number(stat_record->numbytes, byte_str, DONT_SCALE_NUMBER, VAR_LENGTH);
|
||||
format_number(stat_record->numpackets, packet_str, DONT_SCALE_NUMBER, VAR_LENGTH);
|
||||
format_number(bps, bps_str, DONT_SCALE_NUMBER, VAR_LENGTH);
|
||||
format_number(pps, pps_str, DONT_SCALE_NUMBER, VAR_LENGTH);
|
||||
format_number(bpp, bpp_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, DO_SCALE_NUMBER, VAR_LENGTH);
|
||||
format_number(bps, bps_str, DO_SCALE_NUMBER, VAR_LENGTH);
|
||||
format_number(pps, pps_str, DO_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",
|
||||
(unsigned long long)stat_record->numflows, byte_str, packet_str, bps_str, pps_str, bpp_str );
|
||||
}
|
||||
|
27
bin/nfnet.c
27
bin/nfnet.c
@ -178,12 +178,11 @@ int error, p, sockfd;
|
||||
int Unicast_send_socket (const char *hostname, const char *sendport, int family,
|
||||
unsigned int wmem_size, struct sockaddr_storage *addr, int *addrlen) {
|
||||
struct addrinfo hints, *res, *ressave;
|
||||
int n, sockfd;
|
||||
int error, sockfd;
|
||||
unsigned int wmem_actual;
|
||||
socklen_t optlen;
|
||||
|
||||
if ( !hostname || !sendport ) {
|
||||
fprintf(stderr, "hostname and listen port required!\n");
|
||||
LogError("hostname and listen port required!");
|
||||
return -1;
|
||||
}
|
||||
@ -194,10 +193,9 @@ socklen_t optlen;
|
||||
hints.ai_family = family;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
|
||||
n = getaddrinfo(hostname, sendport, &hints, &res);
|
||||
|
||||
if ( n < 0 ) {
|
||||
fprintf(stderr, "getaddrinfo error: [%s]\n", strerror(errno));
|
||||
error = getaddrinfo(hostname, sendport, &hints, &res);
|
||||
if ( error ) {
|
||||
LogError("getaddrinfo() error: %s", gai_strerror(error));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -205,27 +203,28 @@ socklen_t optlen;
|
||||
sockfd = -1;
|
||||
while (res) {
|
||||
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
|
||||
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
|
||||
close(sockfd);
|
||||
// ok - we need now an unconnected socket
|
||||
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
||||
break;
|
||||
}
|
||||
// unsuccessful connect :(
|
||||
close(sockfd);
|
||||
sockfd = -1;
|
||||
}
|
||||
res=res->ai_next;
|
||||
}
|
||||
|
||||
if (sockfd < 0) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
11
bin/nfnet.h
11
bin/nfnet.h
@ -57,6 +57,17 @@ typedef struct send_peer_s {
|
||||
void *endp;
|
||||
} 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 */
|
||||
|
||||
int Unicast_receive_socket(const char *bindhost, const char *listenport, int family, int sockbuflen );
|
||||
|
@ -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 <input>\tread from file. default: stdin\n"
|
||||
"-f <filter>\tfilter syntaxfile\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\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);
|
||||
|
||||
|
53
bin/sfcapd.c
53
bin/sfcapd.c
@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Peter Haag
|
||||
* Copyright (c) 2017, Peter Haag
|
||||
* Copyright (c) 2016, Peter Haag
|
||||
* Copyright (c) 2014, Peter Haag
|
||||
@ -124,7 +125,7 @@ static void daemonize(void);
|
||||
|
||||
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);
|
||||
|
||||
/* Functions */
|
||||
@ -144,7 +145,7 @@ static void usage(char *name) {
|
||||
"-H Add port histogram data to flow file.(default 'no')\n"
|
||||
"-n Ident,IP,logdir\tAdd this flow source - multiple streams\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"
|
||||
"-z\t\tLZO 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 "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) {
|
||||
FlowSource_t *fs;
|
||||
struct sockaddr_storage sf_sender;
|
||||
@ -393,6 +394,7 @@ srecord_t *commbuff;
|
||||
*/
|
||||
while ( 1 ) {
|
||||
struct timeval tv;
|
||||
int i;
|
||||
|
||||
/* read next bunch of data into beginn of input buffer */
|
||||
if ( !done) {
|
||||
@ -415,12 +417,15 @@ srecord_t *commbuff;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( peer.hostname ) {
|
||||
i = 0;
|
||||
while ( repeater[i].hostname && (i < MAX_REPEATERS)) {
|
||||
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 ) {
|
||||
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];
|
||||
struct stat fstat;
|
||||
packet_function_t receive_packet;
|
||||
send_peer_t peer;
|
||||
repeater_t repeater[MAX_REPEATERS];
|
||||
FlowSource_t *fs;
|
||||
struct sigaction act;
|
||||
int family, bufflen;
|
||||
time_t twin, t_start;
|
||||
int sock, synctime, do_daemonize, expire, spec_time_extension, report_sequence;
|
||||
int subdir_index, compress;
|
||||
int c;
|
||||
int c, i;
|
||||
|
||||
receive_packet = recvfrom;
|
||||
verbose = synctime = do_daemonize = 0;
|
||||
@ -687,8 +692,10 @@ int c;
|
||||
expire = 0;
|
||||
spec_time_extension = 0;
|
||||
compress = NOT_COMPRESSED;
|
||||
memset((void *)&peer, 0, sizeof(send_peer_t));
|
||||
peer.family = AF_UNSPEC;
|
||||
memset((void *)&repeater, 0, sizeof(repeater));
|
||||
for ( i = 0; i < MAX_REPEATERS; i++ ) {
|
||||
repeater[i].family = AF_UNSPEC;
|
||||
}
|
||||
Ident = "none";
|
||||
FlowSource = NULL;
|
||||
extension_tags = DefaultExtensions;
|
||||
@ -794,14 +801,23 @@ int c;
|
||||
pidfile[MAXPATHLEN-1] = 0;
|
||||
break;
|
||||
case 'R': {
|
||||
char *port, *hostname;
|
||||
char *p = strchr(optarg, '/');
|
||||
int i = 0;
|
||||
if ( p ) {
|
||||
*p++ = '\0';
|
||||
peer.port = strdup(p);
|
||||
port = strdup(p);
|
||||
} 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; }
|
||||
case 'r':
|
||||
@ -914,11 +930,14 @@ int c;
|
||||
exit(255);
|
||||
}
|
||||
|
||||
if ( peer.hostname ) {
|
||||
peer.sockfd = Unicast_send_socket (peer.hostname, peer.port, peer.family, bufflen,
|
||||
&peer.addr, &peer.addrlen );
|
||||
if ( peer.sockfd <= 0 )
|
||||
i = 0;
|
||||
while ( repeater[i].hostname && (i < MAX_REPEATERS) ) {
|
||||
repeater[i].sockfd = Unicast_send_socket (repeater[i].hostname, repeater[i].port, repeater[i].family, bufflen,
|
||||
&repeater[i].addr, &repeater[i].addrlen );
|
||||
if ( repeater[i].sockfd <= 0 )
|
||||
exit(255);
|
||||
LogInfo("Replay flows to host: %s port: %s", repeater[i].hostname, repeater[i].port);
|
||||
i++;
|
||||
}
|
||||
|
||||
SetPriv(userid, groupid);
|
||||
@ -1071,7 +1090,7 @@ int c;
|
||||
sigaction(SIGCHLD, &act, NULL);
|
||||
|
||||
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);
|
||||
close(sock);
|
||||
kill_launcher(launcher_pid);
|
||||
|
@ -104,7 +104,7 @@ fi
|
||||
)
|
||||
|
||||
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
|
||||
CPPFLAGS="${CPPFLAGS} -I/usr/local/include"
|
||||
LDFLAGS="${LDFLAGS} -L/usr/local/lib"
|
||||
@ -242,7 +242,7 @@ AC_ARG_ENABLE(nfpcapd,
|
||||
cat >>config.h <<_ACEOF
|
||||
#define HAVE_LIBPCAP 1
|
||||
_ACEOF
|
||||
RRD_LIBS="-lpcap"
|
||||
PCAP_LIBS="-lpcap"
|
||||
AC_SUBST(PCAP_LIBS)
|
||||
]
|
||||
, AC_MSG_ERROR(Can not link libpcap. Please specify --with-pcappath=.. configure failed! ))
|
||||
|
@ -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.
|
||||
\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
|
||||
accepted addresses the port separator is '/'.
|
||||
accepted addresses the port separator is '/'. Up to 8 repeaters my be defined.
|
||||
.TP 3
|
||||
.B -I \fIIdentString ( capital letter i )
|
||||
Specifies an ident string, which describes the source e.g. the
|
||||
|
@ -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
|
||||
given day.
|
||||
.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
|
||||
Limit number of records to send to the first \fInum\fR flows.
|
||||
.TP 3
|
||||
|
@ -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.
|
||||
\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
|
||||
accepted addresses the port separator is '/'.
|
||||
accepted addresses the port separator is '/'. Up to 8 repeaters my be defined.
|
||||
.TP 3
|
||||
.B -I \fIIdentString ( capital letter i )
|
||||
Specifies an ident string, which describes the source e.g. the
|
||||
|
Loading…
x
Reference in New Issue
Block a user