Example #1
0
static char *GuessSubDir(char *channeldir, char *filename) {
char s[MAXPATHLEN];
struct  tm *t_tm;
int	i;

	if ( strlen(filename) == 19 && (strncmp(filename, "nfcapd.", 7) == 0) ) {
		char *p  = &filename[7];
		time_t t = ISO2UNIX(p);
		t_tm = localtime(&t);
	} else
		return NULL;

	i = 0;
	// if the file exists, it must be in any of the possible subdirs
	// so try one after the next - one will match
	while ( subdir_def[i] ) {
		char const *sub_fmt = subdir_def[i];
		char subpath[255];
		struct stat stat_buf;
		strftime(subpath, 254, sub_fmt, t_tm);
		subpath[254] = '\0';

		snprintf(s, MAXPATHLEN-1, "%s/%s/%s", channeldir, subpath, filename);
		if ( stat(s, &stat_buf) == 0 && S_ISREG(stat_buf.st_mode) ) {
			// found file in subdir 
			return strdup(subpath);
		}
		i++;
	}

	return NULL;

} // End of GuessSubDir
Example #2
0
int main( int argc, char **argv ) {
int i, c;
master_record_t		record;
nffile_t			*nffile;

	when = ISO2UNIX(strdup("200407111030"));
	while ((c = getopt(argc, argv, "h")) != EOF) {
		switch(c) {
			case 'h':
				break;
			default:
				fprintf(stderr, "ERROR: Unsupported option: '%c'\n", c);
				exit(255);
		}
	}

	extension_info.map = (extension_map_t *)malloc(sizeof(extension_map_t) + 32 * sizeof(uint16_t));
	if ( !extension_info.map ) {
		fprintf(stderr, "malloc() error in %s line %d: %s\n", __FILE__, __LINE__, strerror (errno));
		exit(255);
	}
	extension_info.map->type = ExtensionMapType;
	extension_info.map->map_id = 0;
	i = 0;
	extension_info.map->ex_id[i++] = EX_IO_SNMP_2;
	extension_info.map->ex_id[i++] = EX_AS_2;
	extension_info.map->ex_id[i++] = EX_MULIPLE;
	extension_info.map->ex_id[i++] = EX_NEXT_HOP_v4;
	extension_info.map->ex_id[i++] = EX_NEXT_HOP_BGP_v4;
	extension_info.map->ex_id[i++] = EX_VLAN;
	extension_info.map->ex_id[i++] = EX_OUT_PKG_4;
	extension_info.map->ex_id[i++] = EX_OUT_BYTES_4;
	extension_info.map->ex_id[i++] = EX_AGGR_FLOWS_4;
 	extension_info.map->ex_id[i++] = EX_MAC_1;
 	extension_info.map->ex_id[i++] = EX_MAC_2;
 	extension_info.map->ex_id[i++] = EX_MPLS;
 	extension_info.map->ex_id[i++] = EX_ROUTER_IP_v4;
 	extension_info.map->ex_id[i++] = EX_ROUTER_ID;
 	extension_info.map->ex_id[i++] = EX_BGPADJ;
	extension_info.map->ex_id[i] = 0;
	extension_info.map->size = sizeof(extension_map_t) + i * sizeof(uint16_t);

    // align 32bits
    if (( extension_info.map->size & 0x3 ) != 0 ) {
        extension_info.map->size += 4 - ( extension_info.map->size & 0x3 );
    }

	extension_info.map->extension_size = 0;
	i=0;
	while (extension_info.map->ex_id[i]) {
		int id = extension_info.map->ex_id[i];
		extension_info.map->extension_size += extension_descriptor[id].size;
		i++;
	}
	memset((void *)&record, 0, sizeof(record));

	nffile = OpenNewFile("-", NULL, 0, 0, NULL);
	if ( !nffile ) {
		exit(255);
	}

	AppendToBuffer(nffile, (void *)extension_info.map, extension_info.map->size);
	
	record.map_ref = extension_info.map;
	record.type	= CommonRecordType;

	record.flags   		= 0;
	record.exporter_sysid = 1;
	record.tcp_flags   	= 1;
	record.tos 		   	= 2;
	record.fwd_status	= 0;
	record.srcport 	 	= 1024;
	record.dstport 	 	= 25;
	record.prot 	 	= IPPROTO_TCP;
	record.input 	 	= 12;
	record.output 	 	= 14;
	record.srcas 	 	= 775;
	record.dstas 	 	= 8404;
	SetIPaddress(&record,  PF_INET, "172.16.1.66", "192.168.170.100");
	SetNextIPaddress(&record,  PF_INET, "172.72.1.2");
	SetBGPNextIPaddress(&record,  PF_INET, "172.73.2.3");
	SetRouterIPaddress(&record,  PF_INET, "127.0.0.1");
	record.engine_type	= 5;
	record.engine_id	= 6;
	record.dPkts 	 	= 202;
	record.dOctets 	 	= 303;
	record.dst_tos		= 128;
	record.dir			= 1;
	record.src_mask		= 16;
	record.dst_mask		= 24;
	record.src_vlan		= 82;
	record.dst_vlan		= 93;
	record.out_pkts		= 212;
	record.out_bytes	= 3234;
	record.aggr_flows	= 3;
	record.in_src_mac	= 0x0234567890aaLL;
	record.out_dst_mac	= 0xffeeddccbbaaLL;
	record.out_src_mac	= 0xaa3456789002LL;
	record.in_dst_mac	= 0xaaeeddccbbffLL;
	record.mpls_label[0] = 1010 << 4;
	record.mpls_label[1] = 2020 << 4;
	record.mpls_label[2] = 3030 << 4;
	record.mpls_label[3] = 4040 << 4;
	record.mpls_label[4] = 5050 << 4;
	record.mpls_label[5] = 6060 << 4;
	record.mpls_label[6] = 7070 << 4;
	record.mpls_label[7] = 8080 << 4;
	record.mpls_label[8] = 9090 << 4;
	record.mpls_label[9] = (100100 << 4) + 1;
	record.client_nw_delay_usec = 2;
	record.server_nw_delay_usec = 22;
	record.appl_latency_usec = 222;
	record.bgpNextAdjacentAS = 45804;
	record.bgpPrevAdjacentAS = 32775;

	fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
	UpdateRecord(&record);
	PackRecord(&record, nffile);

	SetIPaddress(&record,  PF_INET, "172.16.2.66", "192.168.170.101");
	fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
	UpdateRecord(&record);
	PackRecord(&record, nffile);

	record.dPkts 	 	= 101;
	record.dOctets 	 	= 102;
	fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
	UpdateRecord(&record);
	PackRecord(&record, nffile);

	SetIPaddress(&record,  PF_INET, "172.16.3.66", "192.168.170.102");
	fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
	UpdateRecord(&record);
	PackRecord(&record, nffile);

	SetIPaddress(&record,  PF_INET, "172.16.4.66", "192.168.170.103");
	record.srcport 	 = 2024;
	record.prot 	 = IPPROTO_UDP;
	record.tcp_flags = 1;
	record.tos 		 = 1;
	record.dPkts 	 = 1001;
	record.dOctets 	 = 1002;
	fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
	UpdateRecord(&record);
	PackRecord(&record, nffile);

	SetIPaddress(&record,  PF_INET, "172.16.5.66", "192.168.170.104");
	record.srcport 	 	= 3024;
	record.prot 	 	= 51;
	record.tcp_flags 	= 2;
	record.tos 		 	= 2;
	record.dPkts 	 	= 10001;
	record.dOctets 	 	= 10002;
	fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
	UpdateRecord(&record);
	PackRecord(&record, nffile);

	SetIPaddress(&record,  PF_INET, "172.16.6.66", "192.168.170.105");
	record.srcport 	 	= 4024;
	record.prot 	 	= IPPROTO_TCP;
	record.tcp_flags 	= 4;
	record.tos 		 	= 3;
	record.dPkts 	 	= 100001;
	record.dOctets 	 	= 100002;
	fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
	UpdateRecord(&record);
	PackRecord(&record, nffile);

	SetIPaddress(&record,  PF_INET, "172.16.7.66", "192.168.170.106");
	record.srcport 	 	= 5024;
	record.tcp_flags 	= 8;
	record.tos 		 	= 4;
	record.dPkts 	 	= 1000001;
	record.dOctets 	 	= 1000002;
	fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
	UpdateRecord(&record);
	PackRecord(&record, nffile);

	SetIPaddress(&record,  PF_INET, "172.16.8.66", "192.168.170.107");
	record.tcp_flags 	= 1;
	record.tos 		 	= 4;
	record.dPkts 	 	= 10000001;
	record.dOctets 	 	= 1001;
	fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
	UpdateRecord(&record);
	PackRecord(&record, nffile);

	SetIPaddress(&record,  PF_INET, "172.16.9.66", "192.168.170.108");
	record.srcport 	 	= 6024;
	record.tcp_flags 	= 16;
	record.tos 		 	= 5;
	record.dPkts 	 	= 500;
	record.dOctets 	 	= 10000001;
	fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
	UpdateRecord(&record);
	PackRecord(&record, nffile);

	SetIPaddress(&record,  PF_INET, "172.16.10.66", "192.168.170.109");
	fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
	UpdateRecord(&record);
	PackRecord(&record, nffile);

	SetIPaddress(&record,  PF_INET, "172.16.11.66", "192.168.170.110");
	record.srcport 		= 7024;
	record.tcp_flags 	= 32;
	record.tos 		 	= 255;
	record.dPkts 	 	= 5000;
	record.dOctets 	 	= 100000001;
	fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
	UpdateRecord(&record);
	PackRecord(&record, nffile);

	SetIPaddress(&record,  PF_INET, "172.16.12.66", "192.168.170.111");
	record.srcport 	 	= 8024;
	record.tcp_flags 	= 63;
	record.tos 		 	= 0;
	record.dOctets 	 	= 1000000001;
	fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
	UpdateRecord(&record);
	PackRecord(&record, nffile);

	SetIPaddress(&record,  PF_INET, "172.16.13.66", "192.168.170.112");
	record.srcport 	 	= 0;
	record.dstport 	 	= 8;
	record.prot 	 	= 1;
	record.tcp_flags 	= 0;
	record.tos 		 	= 0;
	record.dPkts 	 	= 50002;
	record.dOctets 	 	= 50000;
	fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
	UpdateRecord(&record);
	PackRecord(&record, nffile);

	SetIPaddress(&record,  PF_INET, "172.160.160.166", "172.160.160.180");
	record.srcport 	 = 10024;
	record.dstport 	 = 25000;
	record.prot 	 = IPPROTO_TCP;
	record.dPkts 	 = 500001;
	record.dOctets 	 = 500000;
	fprintf(stderr, "IPv4 32bit packets 32bit bytes\n");
	UpdateRecord(&record);
	PackRecord(&record, nffile);

	SetIPaddress(&record,  PF_INET6, "fe80::2110:abcd:1234:0", "fe80::2110:abcd:1235:4321");
//	SetNextIPaddress(&record,  PF_INET6, "2003:234:aabb::211:24ff:fe80:d01e");
//	SetBGPNextIPaddress(&record,  PF_INET6, "2004:234:aabb::211:24ff:fe80:d01e");
	record.srcport 	 = 1024;
	record.dstport 	 = 25;
	record.tcp_flags = 27;
	record.dPkts 	 = 10;
	record.dOctets 	 = 15100;
	fprintf(stderr, "IPv6 32bit packets 32bit bytes\n");
	UpdateRecord(&record);
	PackRecord(&record, nffile);

	SetIPaddress(&record,  PF_INET6, "2001:234:aabb::211:24ff:fe80:d01e", "2001:620::8:203:baff:fe52:38e5");
	record.srcport 	 = 10240;
	record.dstport 	 = 52345;
	record.dPkts 	 = 10100;
	record.dOctets 	 = 15000000;
	fprintf(stderr, "IPv6 32bit packets 32bit bytes\n");
	UpdateRecord(&record);
	PackRecord(&record, nffile);

	record.dPkts 	 = 10100000;
	record.dOctets 	 = 0x100000000LL;
	fprintf(stderr, "IPv6 32bit packets 64bit bytes\n");
	UpdateRecord(&record);
	PackRecord(&record, nffile);

	record.dPkts 	 = 0x100000000LL;
	record.dOctets 	 = 15000000;
	fprintf(stderr, "IPv6 64bit packets 32bit bytes\n");
	UpdateRecord(&record);
	PackRecord(&record, nffile);

	record.dOctets 	 = 0x200000000LL;
	fprintf(stderr, "IPv6 64bit packets 64bit bytes\n");
	UpdateRecord(&record);
	PackRecord(&record, nffile);

	SetIPaddress(&record,  PF_INET, "172.16.14.18", "192.168.170.113");
//	SetNextIPaddress(&record,  PF_INET, "172.72.1.2");
//	SetBGPNextIPaddress(&record,  PF_INET, "172.73.2.3");
	record.srcport 	 = 10240;
	record.dstport 	 = 52345;
	record.dPkts 	 = 10100000;
	record.dOctets 	 = 0x100000000LL;
	fprintf(stderr, "IPv4 32bit packets 64bit bytes\n");
	UpdateRecord(&record);
	PackRecord(&record, nffile);

	SetIPaddress(&record,  PF_INET, "172.16.15.18", "192.168.170.114");
	record.dPkts 	 = 0x100000000LL;
	record.dOctets 	 = 15000000;
	fprintf(stderr, "IPv4 64bit packets 32bit bytes\n");
	UpdateRecord(&record);
	PackRecord(&record, nffile);

	SetIPaddress(&record,  PF_INET, "172.16.16.18", "192.168.170.115");
	record.dOctets 	 = 0x200000000LL;
	fprintf(stderr, "IPv4 64bit packets 64bit bytes\n");
	UpdateRecord(&record);
	PackRecord(&record, nffile);

	extension_info.map->ex_id[0] = EX_IO_SNMP_4;

	extension_info.map->extension_size = 0;
	i=0;
	while (extension_info.map->ex_id[i]) {
		int id = extension_info.map->ex_id[i];
		extension_info.map->extension_size += extension_descriptor[id].size;
		i++;
	}

	memcpy(nffile->buff_ptr, (void *)extension_info.map, extension_info.map->size);
	nffile->buff_ptr += extension_info.map->size;
	nffile->block_header->NumRecords++;
	nffile->block_header->size 		+= extension_info.map->size;

	UpdateRecord(&record);
	fprintf(stderr, "4 bytes interfaces, 2 bytes AS numbers %d %d\n", record.fwd_status, nffile->block_header->NumRecords);
	PackRecord(&record, nffile);

	extension_info.map->ex_id[0] = EX_IO_SNMP_2;
	extension_info.map->ex_id[1] = EX_AS_4;

	extension_info.map->extension_size = 0;
	i=0;
	while (extension_info.map->ex_id[i]) {
		int id = extension_info.map->ex_id[i];
		extension_info.map->extension_size += extension_descriptor[id].size;
		i++;
	}

	memcpy(nffile->buff_ptr, (void *)extension_info.map, extension_info.map->size);
	nffile->buff_ptr += extension_info.map->size;
	nffile->block_header->NumRecords++;
	nffile->block_header->size 		+= extension_info.map->size;

	UpdateRecord(&record);
	fprintf(stderr, "2 bytes interfaces, 4 bytes AS numbers %d %d\n", record.fwd_status, nffile->block_header->NumRecords);
	PackRecord(&record, nffile);

	extension_info.map->ex_id[0] = EX_IO_SNMP_4;

	extension_info.map->extension_size = 0;
	i=0;
	while (extension_info.map->ex_id[i]) {
		int id = extension_info.map->ex_id[i];
		extension_info.map->extension_size += extension_descriptor[id].size;
		i++;
	}

	memcpy(nffile->buff_ptr, (void *)extension_info.map, extension_info.map->size);
	nffile->buff_ptr += extension_info.map->size;
	nffile->block_header->NumRecords++;
	nffile->block_header->size 		+= extension_info.map->size;

	UpdateRecord(&record);
	fprintf(stderr, "4 bytes interfaces, 4 bytes AS numbers %d %d\n", record.fwd_status, nffile->block_header->NumRecords);
	PackRecord(&record, nffile);

	if ( nffile->block_header->NumRecords ) {
		if ( WriteBlock(nffile) <= 0 ) {
			fprintf(stderr, "Failed to write output buffer to disk: '%s'" , strerror(errno));
		} 
	}

	return 0;
}
Example #3
0
int RRD_StoreDataRow(char *path, char *iso_time, data_row *row) {
char 	rrd_filename[1024], *buff, *s;
char	*rrd_arg[10];
time_t	when, frag;
int 	i, j, len, p, t, buffsize, argc;
uint32_t	pnum;
struct stat statbuf;

	buffsize = MAXBUFF;
	buff = (char *)malloc(buffsize);
	if ( !buff ) {
		perror("Memory error!");
		return 0;
	}

	when = ISO2UNIX(iso_time);
	if ( !when ) 
		return 0;

	// make sure, we are at a 5min boundary
	frag = when % 300;
	if ( frag ) {
		fprintf(stderr, "Round to next timeslot: offset %lld\n", (long long)frag);
		when -= frag;
	}

	for ( p=tcp; p<=udp; p++ ) {
		// for every protocol TCP - UDP
		for ( t=flows; t<=bytes; t++ ) {
			// for every type flows - packets - bytes
			for (j=0; j<64; j++) {	
				// for all 64 RRD files in proto - type
				len = snprintf(rrd_filename, 1024, "%s/%s-%s-%d.rrd", path, proto[p], type[t], j);
				if ( len >= 1024 ) {
					fprintf(stderr, "Failed to concat RRD filename: string overflow");
					return 0;
				}
		
				// Check if RRD file exists
				if ( (stat(rrd_filename, &statbuf) < 0 ) || !(statbuf.st_mode & S_IFREG) ) {
					fprintf(stderr, "No such RRD file: '%s'\n", rrd_filename);
					return 0;
				}

				buffsize = MAXBUFF;
				s = buff;
		
				/* add time to RRD arg string */
				len = snprintf(s, buffsize, "%lld:", (long long)when);
				buffsize -= len;
				s += len;
		
				/* add port data to RRD arg string */
				for ( i=0; i<1024; i++) {
					pnum = ( j << 10 ) + i;
/*
if ( row[pnum].proto[p].type[t] ) {
	fprintf(stderr, "%d %d %d\n", pnum, p, t);
}
*/
					len = snprintf(s, buffsize, "%llu:", (long long unsigned)row[pnum].proto[p].type[t]);
					if ( len >= buffsize ) {
						fprintf(stderr, "No enough space to create RRD arg\n");
						return 0;
					}
					buffsize -= len;
					s += len;
				}
				s--;
				*s = '\0';

				// Create arg vector
				argc = 0;
				rrd_arg[argc++] = "update";
				rrd_arg[argc++] = rrd_filename;
				rrd_arg[argc++] = buff;
				rrd_arg[argc]   = NULL;
			
				optind = 0; opterr = 0;
				rrd_clear_error();
				if ( ( i=rrd_update(argc, rrd_arg))) {
					fprintf(stderr, "RRD: %s Insert Error: %d %s\n", rrd_filename, i, rrd_get_error());
				}
			} // for all 64 rrd files
		} // for every type flows - packets - bytes
	} // for every protocol TCP - UDP

	return 1;
} // End of RRD_StoreDataRow
Example #4
0
static void SetupProfileChannels(char *profile_datadir, char *profile_statdir, profile_param_info_t *profile_param, 
	int subdir_index, char *filterfile, char *filename, int verify_only, int compress ) {
FilterEngine_data_t	*engine;
struct 	stat stat_buf;
char 	*p, *filter, *subdir, *wfile, *ofile, *rrdfile, *source_filter;
char	path[MAXPATHLEN];
int		ffd, ret;
size_t	filter_size;
nffile_t *nffile;

	ofile = wfile = NULL;
	nffile = NULL;

	/* 
	 * Compile the complete filter:
	 * this consists of the source list and the filter stored in the file
	 */
	snprintf(path, MAXPATHLEN-1, "%s/%s/%s/%s-%s", 
		profile_statdir, profile_param->profilegroup, profile_param->profilename, profile_param->channelname, filterfile);
	path[MAXPATHLEN-1] = '\0';

	if ( stat(path, &stat_buf) || !S_ISREG(stat_buf.st_mode) ) {
		LogError("Skipping channel %s in profile '%s' group '%s'. No profile filter found.\n", 
			profile_param->channelname, profile_param->profilename, profile_param->profilegroup);
		return;
	}

	// prepare source filter for this channel
	if ( profile_param->channel_sourcelist ) {
		// we have a channel_sourcelist: channel1|channel2|channel3
		// source filter - therefore pattern is '( sourcefilter ) and ( filter )'
		// where sourcefilter is 'ident source1 or ident source2 ... '
		char *q;
		size_t	len = strlen(profile_param->channel_sourcelist);
		int num_sources = 1;	// at least one source, otherwise we would not be in this code

		q = profile_param->channel_sourcelist;
		while ( (p = strchr(q, '|')) != NULL  ) {
			num_sources++;
			q = p;
			q++;
		}
		// allocate a temp buffer for the source filter. 
		// for each source add 'ident <source>  or ', which makes 10 char per sources, including '()\0 and ' = 8
		len += 10 * num_sources + 8;
		source_filter = (char *)malloc(len);
		if ( !source_filter ) {
			LogError("malloc() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) );
			exit(255);
		}

		source_filter[0] = '(';
		source_filter[1] = '\0';
		len--;
		q = profile_param->channel_sourcelist;
		do {
			p = strchr(q, '|');
			if (p) 
				*p = '\0';

			if ( !AppendString(source_filter, "ident ", &len) ) 
				return;

			if ( !AppendString(source_filter, q, &len) ) 
				return;

			if ( p ) {
				// there is another source waiting behind *p
				if ( !AppendString(source_filter, " or ", &len) )
					return;
				q = p;
				q++;
			}
		} while (p);

		if ( !AppendString(source_filter, ") and (", &len) ) 
			return;
	} else 
		// no source filter - therefore pattern is '(' filter ')'
		source_filter = "(";

	filter_size = stat_buf.st_size + strlen(source_filter) + 2;	// +2 : ')\0' at the end of the filter

	filter = (char *)malloc(filter_size);
	if ( !filter ) {
		LogError("malloc() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) );
		exit(255);
	}
	ffd = open(path, O_RDONLY);
	if ( ffd < 0 ) {
		LogError("Can't open file '%s' for reading: %s\n",path, strerror(errno) );
		return;
	}

	strncpy(filter, source_filter, strlen(source_filter));
	p = filter + strlen(source_filter);

	ret = read(ffd, (void *)p, stat_buf.st_size);
	if ( ret < 0   ) {
		LogError("Can't read from file '%s': %s\n",path, strerror(errno) );
		close(ffd);
		return;
	}
	close(ffd);

	p[stat_buf.st_size]   = ')';
	p[stat_buf.st_size+1] = '\0';


	// compile profile filter
	if ( verify_only )
		printf("Check filter for channel %s in profile '%s' in group '%s': ", 
			profile_param->channelname, profile_param->profilename, profile_param->profilegroup);
	engine = CompileFilter(filter);

	if ( !engine ) {
		printf("\n");
		LogError("*** Compiling filter failed for channel %s in profile '%s' in group '%s'.",
			profile_param->channelname, profile_param->profilename, profile_param->profilegroup);
		LogError("*** File: %s", path);
		LogError("*** Error: %s\n", yyerror_buff);
		LogError("*** Failed Filter: %s", filter);			
		free(filter);
		return;
	}
	free(filter);

	if ( verify_only ) {
		printf("ok.\n");
		return;
	}

	// path to the channel
	// channel exists and is a directory - checked in ParseParams
	snprintf(path, MAXPATHLEN-1, "%s/%s/%s/%s", 
		profile_datadir, profile_param->profilegroup, profile_param->profilename, profile_param->channelname);
	path[MAXPATHLEN-1] = '\0';

	if ( chdir(path)) {
		LogError("Error can't chdir to '%s': %s", path, strerror(errno));
		exit(255);
	}

	// check for subdir hierarchy
	subdir = NULL;
	if ( (profile_param->profiletype & 4) ==  0  ) { // no shadow profile
		int is_alert = (profile_param->profiletype & 8) ==  8;
		if ( !is_alert && subdir_index && strlen(filename) == 19 && (strncmp(filename, "nfcapd.", 7) == 0) ) {
			char *p = &filename[7];	// points to ISO timstamp in filename
			time_t	t = ISO2UNIX(p);
			struct  tm *t_tm = localtime(&t);
			char error[255];
	
			subdir = GetSubDir(t_tm);
			if ( !subdir ) {
				// failed to generate subdir path - put flows into base directory
				LogError( "Failed to create subdir path!");
			}
			if ( !SetupSubDir(path, subdir, error, 255) ) {
				LogError( "Failed to create subdir path: '%s'" , error);
				// nothing else need to be done, as subdir == NULL means put files into channel directory
			}
		}

		if ( is_alert ) { // alert
			snprintf(path, MAXPATHLEN, "%s/%s/%s/%s/%s", 
				profile_datadir, profile_param->profilegroup, profile_param->profilename, profile_param->channelname, filename);
		} else {
			// prepare output file for profile types != shadow
			if ( subdir ) 
				snprintf(path, MAXPATHLEN, "%s/%s/%s/%s/%s/%s", 
					profile_datadir, profile_param->profilegroup, profile_param->profilename, 
					profile_param->channelname, subdir, filename);
			else
				snprintf(path, MAXPATHLEN, "%s/%s/%s/%s/%s", 
					profile_datadir, profile_param->profilegroup, profile_param->profilename, profile_param->channelname, filename);
		}
		path[MAXPATHLEN-1] = '\0';
		wfile = strdup(path);

		// ofile: file while profiling
		snprintf(path, MAXPATHLEN, "%s/%s/%s/%s/nfprofile.%llu", 
			profile_datadir, profile_param->profilegroup, profile_param->profilename, profile_param->channelname, 
			(unsigned long long)getpid());
		path[MAXPATHLEN-1] = '\0';

		ofile = strdup(path);
	
		nffile = OpenNewFile(path, NULL, compress, 0, NULL);
		if ( !nffile ) {
			return;
		}
	} 

	snprintf(path, MAXPATHLEN-1, "%s/%s/%s/%s.rrd", 
		profile_statdir, profile_param->profilegroup, profile_param->profilename, profile_param->channelname);
	path[MAXPATHLEN-1] = '\0';
	rrdfile = strdup(path);

	snprintf(path, MAXPATHLEN, "%s/%s/%s/%s", profile_datadir, profile_param->profilegroup, 
		profile_param->profilename, profile_param->channelname );
	path[MAXPATHLEN-1] = '\0';

	// collect all channel info
	profile_channels = realloc(profile_channels, (num_channels+1) * sizeof(profile_channel_info_t) );
	if ( !profile_channels ) {
		LogError("Memory allocation error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) );
		exit(255);
	}

	memset(&profile_channels[num_channels], 0, sizeof(profile_channel_info_t));

	profile_channels[num_channels].engine					= engine;
	profile_channels[num_channels].group 	 				= profile_param->profilegroup;
	profile_channels[num_channels].profile 	 				= profile_param->profilename;
	profile_channels[num_channels].channel 	 				= profile_param->channelname;
	profile_channels[num_channels].wfile 					= wfile;
	profile_channels[num_channels].ofile 					= ofile;
	profile_channels[num_channels].rrdfile 					= rrdfile;
	profile_channels[num_channels].dirstat_path 			= strdup(path);
	profile_channels[num_channels].type						= profile_param->profiletype;
	profile_channels[num_channels].nffile					= nffile;

	memset((void *)&profile_channels[num_channels].stat_record, 0, sizeof(stat_record_t));

	profile_channels[num_channels].stat_record.first_seen	= 0x7fffffff;
	profile_channels[num_channels].stat_record.last_seen	= 0;

	num_channels++;

	return;

} // End of SetupProfileChannels
Example #5
0
void ExpireProfile(channel_t *channel, dirstat_t *current_stat, uint64_t maxsize, uint64_t maxlife, uint32_t runtime ) {
int  		size_done, lifetime_done, done;
char 		*expire_timelimit = "";
time_t		now = time(NULL);
uint64_t	sizelimit, num_expired;

	if ( !channel ) 
		return;

	done = 0;
	SetupSignalHandler();

	if ( maxlife ) {
//		time_t t_expire = now - maxlife;
		// build an appropriate string for comparing
		time_t t_watermark = now - (time_t)((maxlife * current_stat->low_water)/100);

//	printf("Expire files before %s", ctime(&t_expire));
		expire_timelimit = strdup(UNIX2ISO(t_watermark));
//	printf("down to %s", ctime(&t_watermark));
//	printf("Diff: %i\n", t_watermark - t_expire );

	}

	size_done 		= maxsize == 0 || current_stat->filesize < maxsize;
	sizelimit 		= (current_stat->low_water * maxsize)/100;
	lifetime_done 	= maxlife == 0 || ( now - current_stat->first ) < maxlife;

	num_expired = 0;

	PrepareDirLists(channel);
	if ( runtime )
		alarm(runtime);
	while ( !done ) {
		char *p;
		int file_removed;

		// search for the channel with oldest file. If all channel have same age, 
		// get the last in the list
		channel_t *expire_channel  = channel;
		channel_t *compare_channel = expire_channel->next;
		while ( compare_channel ) {
			if ( expire_channel->ftsent == NULL ) {
				expire_channel = compare_channel;
			}
			if ( compare_channel->ftsent == NULL ) {
				compare_channel = compare_channel->next;
				continue;
			}
			// at this point expire_channel and current_channel fts entries are valid
			if ( strcmp(expire_channel->ftsent->fts_name, compare_channel->ftsent->fts_name) >= 0 ) {
				expire_channel = compare_channel;
			}
			compare_channel = compare_channel->next;
		}
		if ( !expire_channel->ftsent ) {
			// no more entries in any channel - we are done
			done = 1;
			continue;
		}

		// flag is file got removed
		file_removed = 0;

		// expire_channel now points to the channel with oldest file
		// do expire
		p = &(expire_channel->ftsent->fts_name[7]);
//	printf("File: %s\n", expire_channel->ftsent->fts_path);

		if ( !size_done ) {
			// expire size-wise if needed
//	printf("	Size expire %llu %llu\n", current_stat->filesize, sizelimit);
			if ( current_stat->filesize > sizelimit ) {
				// need to delete this file
				if ( unlink(expire_channel->ftsent->fts_path) == 0 ) {
					// Update profile stat
					current_stat->filesize 			  -= 512 * expire_channel->ftsent->fts_statp->st_blocks;
					current_stat->numfiles--;

					// Update channel stat
					expire_channel->dirstat->filesize -= 512 * expire_channel->ftsent->fts_statp->st_blocks;
					expire_channel->dirstat->numfiles--;

					// decrement number of files seen in this directory
					expire_channel->ftsent->fts_number--;

					file_removed = 1;
					num_expired++;
				} else {
					LogError( "unlink() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) );
				}
			} else {
				// we are done size-wise
				// time of first file not expired = start time of channel/profile
				expire_channel->dirstat->first = current_stat->first = ISO2UNIX(p);	
				size_done = 1;
			}
		} else if ( !lifetime_done ) {
//	printf("	Time expire \n");
			// expire time-wise if needed
			// this part of the code is executed only when size-wise is already fullfilled
			if ( strcmp(p, expire_timelimit) < 0  ) {
				// need to delete this file
				if ( unlink(expire_channel->ftsent->fts_path) == 0 ) {
					// Update profile stat
					current_stat->filesize -= 512 * expire_channel->ftsent->fts_statp->st_blocks;
					current_stat->numfiles--;

					// Update channel stat
					expire_channel->dirstat->filesize -= 512 * expire_channel->ftsent->fts_statp->st_blocks;
					expire_channel->dirstat->numfiles--;

					// decrement number of files seen in this directory
					expire_channel->ftsent->fts_number--;

					file_removed = 1;
					num_expired++;
				} else {
					LogError( "unlink() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) );
				}
			} else {
				// we are done time-wise
				// time of first file not expired = start time of channel/profile
				expire_channel->dirstat->first = current_stat->first = ISO2UNIX(p);	
				lifetime_done = 1;
			}
		} else 
			// all done
			done = 1;
		if ( timeout ) 
			done = 1;

		// advance fts entry in expire channel to next file, if file was removed
		if ( file_removed ) {
			expire_channel->ftsent = fts_read(expire_channel->fts);
			while ( expire_channel->ftsent ) {
				if ( expire_channel->ftsent->fts_info == FTS_F ) { // entry is a file
					expire_channel->ftsent->fts_number++;
					if ( expire_channel->ftsent->fts_namelen == 19 && 
					 	strncmp(expire_channel->ftsent->fts_name, "nfcapd.", 7) == 0 ) {
						// if ftsent points to next valid file
						char *p = &(expire_channel->ftsent->fts_name[7]);
						// next file is first (oldest) for channel and for profile - update first mark
						expire_channel->dirstat->first = current_stat->first = ISO2UNIX(p);	
						break;
					}
				} else {
	
					switch (expire_channel->ftsent->fts_info) {
						case FTS_D:	// entry is a directory
							// set number of files seen in this directory = 0
							expire_channel->ftsent->fts_number = 0;
							// skip all '.' entries as well as hidden directories
							if ( expire_channel->ftsent->fts_level > 0 && expire_channel->ftsent->fts_name[0] == '.' ) 
								fts_set(expire_channel->fts, expire_channel->ftsent, FTS_SKIP);
							// any valid directory needs to start with a digit ( %Y -> year )
							if ( expire_channel->ftsent->fts_level > 0 && !isdigit(expire_channel->ftsent->fts_name[0]) ) 
								fts_set(expire_channel->fts, expire_channel->ftsent, FTS_SKIP);
							break;
						case FTS_DP:
							// do not delete base data directory ( level == 0 )
							if ( expire_channel->ftsent->fts_number == 0 && expire_channel->ftsent->fts_level > 0 ) {
								// directory is empty and can be deleted
//	printf("Will remove directory %s\n", expire_channel->ftsent->fts_path);
								if ( rmdir(expire_channel->ftsent->fts_path) != 0 ) {
									LogError( "rmdir() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) );
								}
							}
							break;
					}
				}
				// otherwise loop
				expire_channel->ftsent = fts_read(expire_channel->fts);
			} // end advance fts entry
			file_removed = 0;
		}

		if ( expire_channel->ftsent == NULL ) {
			// this channel has no more files now
			expire_channel->dirstat->first 			= expire_channel->dirstat->last;
			if ( expire_channel->dirstat->numfiles ) {	
				// if channel is empty, no files must be reported, but rebuild is done anyway
				LogError( "Inconsitency detected in channel %s. Will rebuild automatically.\n", expire_channel->datadir);
				LogError( "No more files found, but %llu expected.\n", expire_channel->dirstat->numfiles);
			}
			expire_channel->dirstat->numfiles 	= 0;
			expire_channel->dirstat->status		= FORCE_REBUILD;
		}
	} // while ( !done )

	if ( runtime )
		alarm(0);
	if ( timeout ) {
		LogError( "Maximum execution time reached! Interrupt expire.\n");
	}

} // End of ExpireProfile
Example #6
0
void ExpireDir(char *dir, dirstat_t *dirstat, uint64_t maxsize, uint64_t maxlife, uint32_t runtime ) {
FTS 		*fts;
FTSENT 		*ftsent;
uint64_t	sizelimit, num_expired;
int			done, size_done, lifetime_done, dir_files;
char *const path[] = { dir, NULL };
char		*expire_timelimit = NULL;
time_t 		now = time(NULL);

	dir_files = 0;
	if ( dirstat->low_water == 0 )
		dirstat->low_water = 95;

	if ( runtime ) {
		SetupSignalHandler();
		alarm(runtime);
	}

	if ( maxlife ) {
		// build an appropriate string for comparing
		time_t t_expire = now - maxlife;
		
		time_t t_watermark = now - (time_t)((maxlife * dirstat->low_water)/100);

// printf("Expire files before %s", ctime(&t_expire));
		expire_timelimit = strdup(UNIX2ISO(t_watermark));
// printf("down to %s", ctime(&t_watermark));
// printf("Diff: %i\n", t_watermark - t_expire );

		if ( dirstat->last < t_expire && (isatty(STDIN_FILENO) ) ) {
			// this means all files will get expired - are you sure ?
			char *s, s1[32], s2[32];
			time_t	t;
			struct tm *when;

			t = t_expire;
			when = localtime(&t);
			strftime(s1, 31, "%Y-%m-%d %H:%M:%S", when);
			s1[31] = '\0';
			
			t = dirstat->last;
			when = localtime(&t);
			strftime(s2, 31, "%Y-%m-%d %H:%M:%S", when);
			s2[31] = '\0';
			
			printf("Your max lifetime of %s will expire all file before %s\n", ScaleTime(maxlife), s1);
			printf("Your latest files are dated %s. This means all files will be deleted!\n", s2);
			printf("Are you sure? yes/[no] ");
			s = fgets(s1, 31, stdin);
			s1[31] = '\0';
			if ( s && strncasecmp(s1, "yes\n", 31) == 0 ) {
				printf("Ok - you've beeen warned!\n");
			} else {
				printf("Expire canceled!\n");
				return;
			}
		}
	}

	done 		  = 0;
	size_done 	  = maxsize == 0 || dirstat->filesize < maxsize;
	lifetime_done = maxlife == 0 || ( now - dirstat->first ) < maxlife;
	sizelimit = (dirstat->low_water * maxsize)/100;
	num_expired = 0;
	fts = fts_open(path, FTS_LOGICAL,  compare);
	while ( !done && ((ftsent = fts_read(fts)) != NULL) ) {
		if ( ftsent->fts_info == FTS_F ) {
			dir_files++;	// count files in directories
			if ( ftsent->fts_namelen == 19 && strncmp(ftsent->fts_name, "nfcapd.", 7) == 0 ) {
				// nfcapd.200604301200 strlen = 19
				char *s, *p = &(ftsent->fts_name[7]);
	
				// process only nfcapd. files
				// make sure it's really an nfcapd. file and we have 
				// only digits in the rest of the file name
				s = p;
				while ( *s ) {
					if ( *s < '0' || *s > '9' ) 
						break;
					s++;
				}
				// otherwise skip
				if ( *s )
					continue;

				// expire size-wise if needed
				if ( !size_done ) {
					if ( dirstat->filesize > sizelimit ) {
						if ( unlink(ftsent->fts_path) == 0 ) {
							dirstat->filesize -= 512 * ftsent->fts_statp->st_blocks;
							num_expired++;
							dir_files--;
						} else {
							LogError( "unlink() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) );
						}
						continue;	// next file if file was unlinked
					} else {
						dirstat->first = ISO2UNIX(p);	// time of first file not expired
						size_done = 1;
					}
				}

				// expire time-wise if needed
				// this part of the code is executed only when size-wise is fullfilled
				if ( !lifetime_done ) {
					if ( expire_timelimit && strcmp(p, expire_timelimit) < 0  ) {
						if ( unlink(ftsent->fts_path) == 0 ) {
							dirstat->filesize -= 512 * ftsent->fts_statp->st_blocks;
							num_expired++;
							dir_files--;
						} else {
							LogError( "unlink() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) );
						}
						lifetime_done = 0;
					} else {
						dirstat->first = ISO2UNIX(p);	// time of first file not expired
						lifetime_done = 1;
					}
				}
				done = (size_done && lifetime_done) || timeout;

			}
		} else {
			switch (ftsent->fts_info) {
				case FTS_D:
					// set pre-order flag
					dir_files = 0;
					// skip all '.' entries as well as hidden directories
					if ( ftsent->fts_level > 0 && ftsent->fts_name[0] == '.' ) 
						fts_set(fts, ftsent, FTS_SKIP);
					// any valid directory needs to start with a digit ( %Y -> year )
					if ( ftsent->fts_level > 0 && !isdigit(ftsent->fts_name[0]) ) 
						fts_set(fts, ftsent, FTS_SKIP);
					break;
				case FTS_DP:
					// do not delete base data directory ( level == 0 )
					if ( dir_files == 0 && ftsent->fts_level > 0 ) {
						// directory is empty and can be deleted
// printf("Will remove directory %s\n", ftsent->fts_path);
						if ( rmdir(ftsent->fts_path) != 0 ) {
							LogError( "rmdir() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) );
						}
					}
					break;
			}
		}
	}
	fts_close(fts);
	if ( !done ) {
		// all files expired and limits not reached
		// this may be possible, when files get time-wise expired and
		// the time limit is shorter than the latest file
		dirstat->first = dirstat->last;
	}
	if ( runtime )
		alarm(0);
	if ( timeout ) {
		LogError( "Maximum execution time reached! Interrupt expire.\n");
	}
	if ( num_expired > dirstat->numfiles ) {
		LogError( "Error updating stat record: Number of files inconsistent!\n");
		LogError( "Will automatically rebuild this directory next time\n");
		dirstat->numfiles = 0;
		dirstat->status = FORCE_REBUILD;
	} else {
		dirstat->numfiles -= num_expired;
	}
	if ( dirstat->numfiles == 0 ) {
		dirstat->first  = dirstat->last = time(NULL);
		dirstat->status = FORCE_REBUILD;
	}

	free(expire_timelimit);

} // End of ExpireDir
Example #7
0
void RescanDir(char *dir, dirstat_t *dirstat) {
FTS 		*fts;
FTSENT 		*ftsent;
char *const path[] = { dir, NULL };
char		first_timestring[16], last_timestring[16];

	dirstat->filesize = dirstat->numfiles = 0;
	dirstat->first = 0;
	dirstat->last  = 0;
	strncpy(first_timestring, "999999999999", 15);
	strncpy(last_timestring,  "000000000000", 15);
	
	fts = fts_open(path, FTS_LOGICAL,  compare);
	if ( !fts ) {
		LogError( "fts_open() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) );
		return;
	}
	while ( (ftsent = fts_read(fts)) != NULL) {
		if ( ftsent->fts_info == FTS_F && ftsent->fts_namelen == 19 ) {
			// nfcapd.200604301200 strlen = 19
			if ( strncmp(ftsent->fts_name, "nfcapd.", 7) == 0 ) {
				char *s, *p = &(ftsent->fts_name[7]);

				// make sure, we have only digits
				s = p;
				while ( *s ) {
					if ( *s < '0' || *s > '9' ) 
						break;
					s++;
				}
				// otherwise skip
				if ( *s )
					continue;

				if ( strcmp(p, first_timestring) < 0 ) {
					first_timestring[0] = '\0';
					strncat(first_timestring, p, 15);
				}
				if ( strcmp(p, last_timestring) > 0 ) {
					last_timestring[0] = '\0';
					strncat(last_timestring, p, 15);
				}

				dirstat->filesize += 512 * ftsent->fts_statp->st_blocks;
				dirstat->numfiles++;
			}
		} else {
			switch (ftsent->fts_info) {
				case FTS_D:
					// skip all '.' entries as well as hidden directories
					if ( ftsent->fts_level > 0 && ftsent->fts_name[0] == '.' ) 
						fts_set(fts, ftsent, FTS_SKIP);
					// any valid dirctory need to start with a digit ( %Y -> year )
					if ( ftsent->fts_level > 0 && !isdigit(ftsent->fts_name[0]) )
						fts_set(fts, ftsent, FTS_SKIP);
					break;
				case FTS_DP:
					break;
			}
		}
	}
	fts_close(fts);

	// no files means do rebuild next time, otherwise the stat record may not be accurate 
	if ( dirstat->numfiles == 0 ) {
		dirstat->first  = dirstat->last = time(NULL);
		dirstat->status = FORCE_REBUILD;
	} else {
		dirstat->first  = ISO2UNIX(first_timestring);	
		dirstat->last   = ISO2UNIX(last_timestring);	
		dirstat->status = STATFILE_OK;
	}

} // End of RescanDir
Example #8
0
int main( int argc, char **argv ) {
struct stat stat_buff;
char c, *wfile, *rfile, *Rfile, *Mdirs, *ffile, *filter, *timeslot, *DBdir;
char datestr[64];
int ffd, ret, DBinit, AddDB, GenStat, AvStat, output_mode;
unsigned int lastupdate, topN;
data_row *port_table;
time_t	when;
struct tm * t1;

	wfile = rfile = Rfile = Mdirs = ffile = filter = DBdir = timeslot = NULL;
	DBinit = AddDB = GenStat = AvStat = 0;
	lastupdate = output_mode = 0;
	topN = 10;
	while ((c = getopt(argc, argv, "d:hln:pr:st:w:AIM:R:SV")) != EOF) {
		switch (c) {
			case 'h':
				usage(argv[0]);
				exit(0);
				break;
			case 'I':
				DBinit = 1;
				break;
			case 'M':
				Mdirs = strdup(optarg);
				break;
			case 'R':
				Rfile = strdup(optarg);
				break;
			case 'd':
				DBdir = strdup(optarg);
				ret  = stat(DBdir, &stat_buff);
				if ( !(stat_buff.st_mode & S_IFDIR) ) {
					fprintf(stderr, "No such directory: %s\n", DBdir);
					exit(255);
				}
				break;
			case 'l':
				lastupdate = 1;
				break;
			case 'n':
				topN = atoi(optarg);
				if ( topN < 0 ) {
					fprintf(stderr, "TopnN number %i out of range\n", topN);
					exit(255);
				}
				break;
			case 'p':
				output_mode = 1;
				break;
			case 'r':
				rfile = strdup(optarg);
				break;
			case 'w':
				wfile = strdup(optarg);
				break;
			case 's':
				GenStat = 1;
				break;
			case 't':
				timeslot = optarg;
				if ( !ISO2UNIX(timeslot) ) {
					exit(255);
				}
				break;
			case 'A':
				AddDB = 1;
				break;
			case 'S':
				AvStat = 1;
				break;
			default:
				usage(argv[0]);
				exit(0);
		}
	}

	if (argc - optind > 1) {
		usage(argv[0]);
		exit(255);
	} else {
		/* user specified a pcap filter */
		filter = argv[optind];
	}

	openlog(argv[0] , LOG_CONS|LOG_PID, LOG_DAEMON);

	if ( !filter && ffile ) {
		if ( stat(ffile, &stat_buff) ) {
			perror("Can't stat file");
			exit(255);
		}
		filter = (char *)malloc(stat_buff.st_size);
		if ( !filter ) {
			perror("Memory error");
			exit(255);
		}
		ffd = open(ffile, O_RDONLY);
		if ( ffd < 0 ) {
			perror("Can't open file");
			exit(255);
		}
		ret = read(ffd, (void *)filter, stat_buff.st_size);
		if ( ret < 0   ) {
			perror("Error reading file");
			close(ffd);
			exit(255);
		}
		close(ffd);
	}

	if ( !DBdir ) {
		fprintf(stderr, "DB directory required\n");
		exit(255);
	}

	InitStat(DBdir);

	if ( !filter )
		filter = "any";

	Engine = CompileFilter(filter);
	if ( !Engine ) 
		exit(254);
	
	if ( DBinit ) {
		when = time(NULL);
		when -= ((when % 300) + 300);
		InitStatFile(when, NUM_AV_SLOTS);
		if ( !CreateRRDBs(DBdir, when) ) {
			fprintf(stderr, "Init DBs failed\n");
			exit(255);
		}
		fprintf(stderr, "Port DBs initialized.\n");
		exit(0);
	}

	if ( lastupdate ) {
		when = RRD_LastUpdate(DBdir);
		if ( !when )
			exit(255);
		t1 = localtime(&when);
		strftime(datestr, 63, "%b %d %Y %T", t1);
		printf("Last Update: %i, %s\n", (int)when, datestr);
		exit(0);
	}

	port_table = NULL;
	if ( Mdirs || Rfile || rfile ) {
		SetupInputFileSequence(Mdirs, rfile, Rfile);
		port_table = process(filter);
//		Lister(port_table);
		if ( !port_table ) {
			exit(255);
		}
		if ( AddDB ) {
			if ( !timeslot ) {
				fprintf(stderr, "Timeslot required!\n");
				exit(255);
			}
			UpdateStat(port_table, ISO2UNIX(timeslot));
			RRD_StoreDataRow(DBdir, timeslot, port_table);
		}
	}

	if ( AvStat ) {
		port_table = GetStat();
		if ( !port_table ) {
			fprintf(stderr, "Unable to get port table!\n");
			exit(255);
		}
		// DoStat
		Generate_TopN(port_table, topN, NUM_AV_SLOTS, 0, output_mode, wfile);

	} 


	if ( GenStat ) {
		when = ISO2UNIX(timeslot);
		if ( !port_table ) {
			if ( !timeslot ) {
				fprintf(stderr, "Timeslot required!\n");
				exit(255);
			}
			port_table = RRD_GetDataRow(DBdir, when);
		}
		if ( !port_table ) {
			fprintf(stderr, "Unable to get port table!\n");
			exit(255);
		}
		// DoStat
		Generate_TopN(port_table, topN, 1, when, output_mode, wfile);
	}

	CloseStat();

	return 0;
}