/* there is a new code for lnf_filter, however it is experimental so far */ int lnf_filter_init_v1(lnf_filter_t **filterp, char *expr) { lnf_filter_t *filter; filter = malloc(sizeof(lnf_filter_t)); if (filter == NULL) { return LNF_ERR_NOMEM; } #ifdef LNF_THREADS pthread_mutex_lock(&lnf_nfdump_filter_mutex); #endif filter->v2filter = 0; /* nitialised as V1 - nfdump filter */ filter->engine = CompileFilter(expr); #ifdef LNF_THREADS pthread_mutex_unlock(&lnf_nfdump_filter_mutex); #endif if ( !filter->engine ) { free(filter); return LNF_ERR_FILTER; } *filterp = filter; return LNF_OK; }
int main( int argc, char **argv ) { struct stat stat_buff; stat_record_t sum_stat; printer_t print_header, print_record; nfprof_t profile_data; char *rfile, *Rfile, *Mdirs, *wfile, *ffile, *filter, *tstring, *stat_type; char *byte_limit_string, *packet_limit_string, *print_format, *record_header; char *print_order, *query_file, *UnCompress_file, *nameserver, *aggr_fmt; int c, ffd, ret, element_stat, fdump; int i, user_format, quiet, flow_stat, topN, aggregate, aggregate_mask, bidir; int print_stat, syntax_only, date_sorted, do_tag, compress, do_xstat; int plain_numbers, GuessDir, pipe_output, csv_output; time_t t_start, t_end; uint32_t limitflows; char Ident[IDENTLEN]; rfile = Rfile = Mdirs = wfile = ffile = filter = tstring = stat_type = NULL; byte_limit_string = packet_limit_string = NULL; fdump = aggregate = 0; aggregate_mask = 0; bidir = 0; t_start = t_end = 0; syntax_only = 0; topN = -1; flow_stat = 0; print_stat = 0; element_stat = 0; do_xstat = 0; limitflows = 0; date_sorted = 0; total_bytes = 0; total_flows = 0; skipped_blocks = 0; do_tag = 0; quiet = 0; user_format = 0; compress = 0; plain_numbers = 0; pipe_output = 0; csv_output = 0; is_anonymized = 0; GuessDir = 0; nameserver = NULL; print_format = NULL; print_header = NULL; print_record = NULL; print_order = NULL; query_file = NULL; UnCompress_file = NULL; aggr_fmt = NULL; record_header = NULL; Ident[0] = '\0'; while ((c = getopt(argc, argv, "6aA:Bbc:D:E:s:hHn:i:j:f:qzr:v:w:K:M:NImO:R:XZt:TVv:x:l:L:o:")) != EOF) { switch (c) { case 'h': usage(argv[0]); exit(0); break; case 'a': aggregate = 1; break; case 'A': if ( !ParseAggregateMask(optarg, &aggr_fmt ) ) { exit(255); } aggregate_mask = 1; break; case 'B': GuessDir = 1; case 'b': if ( !SetBidirAggregation() ) { exit(255); } bidir = 1; // implies aggregate = 1; break; case 'D': nameserver = optarg; if ( !set_nameserver(nameserver) ) { exit(255); } break; case 'E': query_file = optarg; if ( !InitExporterList() ) { exit(255); } PrintExporters(query_file); exit(0); break; case 'X': fdump = 1; break; case 'Z': syntax_only = 1; break; case 'q': quiet = 1; break; case 'z': compress = 1; break; case 'c': limitflows = atoi(optarg); if ( !limitflows ) { LogError("Option -c needs a number > 0\n"); exit(255); } break; case 's': stat_type = optarg; if ( !SetStat(stat_type, &element_stat, &flow_stat) ) { exit(255); } break; case 'V': { char *e1, *e2; e1 = ""; e2 = ""; #ifdef NSEL e1 = "NSEL-NEL"; #endif printf("%s: Version: %s%s%s\n",argv[0], e1, e2, nfdump_version); exit(0); } break; case 'l': packet_limit_string = optarg; break; case 'K': LogError("*** Anonymisation moved! Use nfanon to anonymise flows!\n"); exit(255); break; case 'H': do_xstat = 1; break; case 'L': byte_limit_string = optarg; break; case 'N': plain_numbers = 1; break; case 'f': ffile = optarg; break; case 't': tstring = optarg; break; case 'r': rfile = optarg; if ( strcmp(rfile, "-") == 0 ) rfile = NULL; break; case 'm': print_order = "tstart"; Parse_PrintOrder(print_order); date_sorted = 1; LogError("Option -m depricated. Use '-O tstart' instead\n"); break; case 'M': Mdirs = optarg; break; case 'I': print_stat++; break; case 'o': // output mode print_format = optarg; break; case 'O': { // stat order by int ret; print_order = optarg; ret = Parse_PrintOrder(print_order); if ( ret < 0 ) { LogError("Unknown print order '%s'\n", print_order); exit(255); } date_sorted = ret == 6; // index into order_mode } break; case 'R': Rfile = optarg; break; case 'w': wfile = optarg; break; case 'n': topN = atoi(optarg); if ( topN < 0 ) { LogError("TopnN number %i out of range\n", topN); exit(255); } break; case 'T': do_tag = 1; break; case 'i': strncpy(Ident, optarg, IDENT_SIZE); Ident[IDENT_SIZE - 1] = 0; if ( strchr(Ident, ' ') ) { LogError("Ident must not contain spaces\n"); exit(255); } break; case 'j': UnCompress_file = optarg; UnCompressFile(UnCompress_file); exit(0); break; case 'x': query_file = optarg; InitExtensionMaps(NO_EXTENSION_LIST); DumpExMaps(query_file); exit(0); break; case 'v': query_file = optarg; QueryFile(query_file); exit(0); break; case '6': // print long IPv6 addr Setv6Mode(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]; FilterFilename = NULL; } // Change Ident only if ( rfile && strlen(Ident) > 0 ) { ChangeIdent(rfile, Ident); exit(0); } if ( (element_stat || flow_stat) && (topN == -1) ) topN = 10; if ( topN < 0 ) topN = 0; if ( (element_stat && !flow_stat) && aggregate_mask ) { LogError("Warning: Aggregation ignored for element statistics\n"); aggregate_mask = 0; } if ( !flow_stat && aggregate_mask ) { aggregate = 1; } if ( rfile && Rfile ) { LogError("-r and -R are mutually exclusive. Plase specify either -r or -R\n"); exit(255); } if ( Mdirs && !(rfile || Rfile) ) { LogError("-M needs either -r or -R to specify the file or file list. Add '-R .' for all files in the directories.\n"); exit(255); } extension_map_list = InitExtensionMaps(NEEDS_EXTENSION_LIST); if ( !InitExporterList() ) { exit(255); } SetupInputFileSequence(Mdirs, rfile, Rfile); if ( print_stat ) { nffile_t *nffile; if ( !rfile && !Rfile && !Mdirs) { LogError("Expect data file(s).\n"); exit(255); } memset((void *)&sum_stat, 0, sizeof(stat_record_t)); sum_stat.first_seen = 0x7fffffff; sum_stat.msec_first = 999; nffile = GetNextFile(NULL, 0, 0); if ( !nffile ) { LogError("Error open file: %s\n", strerror(errno)); exit(250); } while ( nffile && nffile != EMPTY_LIST ) { SumStatRecords(&sum_stat, nffile->stat_record); nffile = GetNextFile(nffile, 0, 0); } PrintStat(&sum_stat); exit(0); } // handle print mode if ( !print_format ) { // automatically select an appropriate output format for custom aggregation // aggr_fmt is compiled by ParseAggregateMask if ( aggr_fmt ) { int len = strlen(AggrPrependFmt) + strlen(aggr_fmt) + strlen(AggrAppendFmt) + 7; // +7 for 'fmt:', 2 spaces and '\0' print_format = malloc(len); if ( !print_format ) { LogError("malloc() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) ); exit(255); } snprintf(print_format, len, "fmt:%s %s %s",AggrPrependFmt, aggr_fmt, AggrAppendFmt ); print_format[len-1] = '\0'; } else if ( bidir ) { print_format = "biline"; } else print_format = DefaultMode; } if ( strncasecmp(print_format, "fmt:", 4) == 0 ) { // special user defined output format char *format = &print_format[4]; if ( strlen(format) ) { if ( !ParseOutputFormat(format, plain_numbers, printmap) ) exit(255); print_record = format_special; record_header = get_record_header(); user_format = 1; } else { LogError("Missing format description for user defined output format!\n"); exit(255); } } else { // predefined output format // Check for long_v6 mode i = strlen(print_format); if ( i > 2 ) { if ( print_format[i-1] == '6' ) { Setv6Mode(1); print_format[i-1] = '\0'; } else Setv6Mode(0); } i = 0; while ( printmap[i].printmode ) { if ( strncasecmp(print_format, printmap[i].printmode, MAXMODELEN) == 0 ) { if ( printmap[i].Format ) { if ( !ParseOutputFormat(printmap[i].Format, plain_numbers, printmap) ) exit(255); // predefined custom format print_record = printmap[i].func; record_header = get_record_header(); user_format = 1; } else { // To support the pipe output format for element stats - check for pipe, and remember this if ( strncasecmp(print_format, "pipe", MAXMODELEN) == 0 ) { pipe_output = 1; } if ( strncasecmp(print_format, "csv", MAXMODELEN) == 0 ) { csv_output = 1; set_record_header(); record_header = get_record_header(); } // predefined static format print_record = printmap[i].func; user_format = 0; } break; } i++; } } if ( !print_record ) { LogError("Unknown output mode '%s'\n", print_format); exit(255); } // this is the only case, where headers are printed. if ( strncasecmp(print_format, "raw", 16) == 0 ) print_header = format_file_block_header; if ( aggregate && (flow_stat || element_stat) ) { aggregate = 0; LogError("Command line switch -s overwrites -a\n"); } if ( !filter && ffile ) { if ( stat(ffile, &stat_buff) ) { LogError("Can't stat filter file '%s': %s\n", ffile, strerror(errno)); exit(255); } filter = (char *)malloc(stat_buff.st_size+1); if ( !filter ) { LogError("malloc() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) ); exit(255); } ffd = open(ffile, O_RDONLY); if ( ffd < 0 ) { LogError("Can't open filter file '%s': %s\n", ffile, strerror(errno)); exit(255); } ret = read(ffd, (void *)filter, stat_buff.st_size); if ( ret < 0 ) { perror("Error reading filter file"); close(ffd); exit(255); } total_bytes += ret; filter[stat_buff.st_size] = 0; close(ffd); FilterFilename = ffile; } // if no filter is given, set the default ip filter which passes through every flow if ( !filter || strlen(filter) == 0 ) filter = "any"; Engine = CompileFilter(filter); if ( !Engine ) exit(254); if ( fdump ) { printf("StartNode: %i Engine: %s\n", Engine->StartNode, Engine->Extended ? "Extended" : "Fast"); DumpList(Engine); exit(0); } if ( syntax_only ) exit(0); if ( print_order && flow_stat ) { printf("-s record and -O (-m) are mutually exclusive options\n"); exit(255); } if ((aggregate || flow_stat || print_order) && !Init_FlowTable() ) exit(250); if (element_stat && !Init_StatTable(HashBits, NumPrealloc) ) exit(250); SetLimits(element_stat || aggregate || flow_stat, packet_limit_string, byte_limit_string); if ( tstring ) { if ( !ScanTimeFrame(tstring, &t_start, &t_end) ) exit(255); } if ( !(flow_stat || element_stat || wfile || quiet ) && record_header ) { if ( user_format ) { printf("%s\n", record_header); } else { // static format - no static format with header any more, but keep code anyway if ( Getv6Mode() ) { printf("%s\n", record_header); } else printf("%s\n", record_header); } } nfprof_start(&profile_data); sum_stat = process_data(wfile, element_stat, aggregate || flow_stat, print_order != NULL, print_header, print_record, t_start, t_end, limitflows, do_tag, compress, do_xstat); nfprof_end(&profile_data, total_flows); if ( total_bytes == 0 ) { printf("No matched flows\n"); exit(0); } if (aggregate || print_order) { if ( wfile ) { nffile_t *nffile = OpenNewFile(wfile, NULL, compress, is_anonymized, NULL); if ( !nffile ) exit(255); if ( ExportFlowTable(nffile, aggregate, bidir, date_sorted, extension_map_list) ) { CloseUpdateFile(nffile, Ident ); } else { CloseFile(nffile); unlink(wfile); } DisposeFile(nffile); } else { PrintFlowTable(print_record, topN, do_tag, GuessDir, extension_map_list); } } if (flow_stat) { PrintFlowStat(record_header, print_record, topN, do_tag, quiet, csv_output, extension_map_list); #ifdef DEVEL printf("Loopcnt: %u\n", loopcnt); #endif } if (element_stat) { PrintElementStat(&sum_stat, plain_numbers, record_header, print_record, topN, do_tag, quiet, pipe_output, csv_output); } if ( !quiet ) { if ( csv_output ) { PrintSummary(&sum_stat, plain_numbers, csv_output); } else if ( !wfile ) { if (is_anonymized) printf("IP addresses anonymised\n"); PrintSummary(&sum_stat, plain_numbers, csv_output); if ( t_last_flow == 0 ) { // in case of a pre 1.6.6 collected and empty flow file printf("Time window: <unknown>\n"); } else { printf("Time window: %s\n", TimeString(t_first_flow, t_last_flow)); } printf("Total flows processed: %u, Blocks skipped: %u, Bytes read: %llu\n", total_flows, skipped_blocks, (unsigned long long)total_bytes); nfprof_print(&profile_data, stdout); } } Dispose_FlowTable(); Dispose_StatTable(); FreeExtensionMaps(extension_map_list); #ifdef DEVEL if ( hash_hit || hash_miss ) printf("Hash hit: %i, miss: %i, skip: %i, ratio: %5.3f\n", hash_hit, hash_miss, hash_skip, (float)hash_hit/((float)(hash_hit+hash_miss))); #endif return 0; }
int main( int argc, char **argv ) { struct stat stat_buff; char *rfile, *ffile, *filter, *tstring; int c, confirm, ffd, ret, blast, netflow_version; unsigned int delay, count, sockbuff_size; time_t t_start, t_end; rfile = ffile = filter = tstring = NULL; t_start = t_end = 0; peer.hostname = NULL; peer.port = DEFAULTCISCOPORT; peer.mcast = 0; peer.family = AF_UNSPEC; peer.sockfd = 0; delay = 1; count = 0xFFFFFFFF; sockbuff_size = 0; netflow_version = 5; 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) { switch (c) { case 'h': usage(argv[0]); exit(0); break; case 'B': blast = 1; break; case 'V': printf("%s: Version: %s\n",argv[0], nfdump_version); exit(0); break; case 'Y': confirm = 1; break; case 'H': case 'i': // compatibility with old version peer.hostname = strdup(optarg); peer.mcast = 0; break; case 'j': if ( peer.hostname == NULL ) { peer.hostname = strdup(optarg); peer.mcast = 1; } else { LogError("ERROR, -H(-i) and -j are mutually exclusive!!\n"); exit(255); } break; case 'K': LogError("*** Anonymization moved! Use nfanon to anonymize flows first!\n"); exit(255); break; case 'L': if ( !InitLog(argv[0], optarg) ) exit(255); break; case 'p': peer.port = strdup(optarg); break; case 'd': delay = atoi(optarg); break; case 'v': netflow_version = atoi(optarg); if ( netflow_version != 5 && netflow_version != 9 ) { LogError("Invalid netflow version: %s. Accept only 5 or 9!\n", optarg); exit(255); } break; case 'c': count = atoi(optarg); break; case 'b': sockbuff_size = atoi(optarg); break; case 'f': ffile = optarg; break; case 't': tstring = optarg; break; case 'r': rfile = optarg; break; case '4': if ( peer.family == AF_UNSPEC ) peer.family = AF_INET; else { LogError("ERROR, Accepts only one protocol IPv4 or IPv6!\n"); exit(255); } break; case '6': if ( peer.family == AF_UNSPEC ) peer.family = AF_INET6; else { LogError("ERROR, Accepts only one protocol IPv4 or IPv6!\n"); exit(255); } 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]; } if ( peer.hostname == NULL ) peer.hostname = DEFAULTHOSTNAME; 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 ( !filter ) filter = "any"; Engine = CompileFilter(filter); if ( !Engine ) exit(254); if ( peer.mcast ) peer.sockfd = Multicast_send_socket (peer.hostname, peer.port, peer.family, sockbuff_size, &peer.addr, &peer.addrlen ); else peer.sockfd = Unicast_send_socket (peer.hostname, peer.port, peer.family, sockbuff_size, &peer.addr, &peer.addrlen ); if ( peer.sockfd <= 0 ) { exit(255); } if ( blast ) { send_blast(delay ); exit(0); } extension_map_list = InitExtensionMaps(NEEDS_EXTENSION_LIST); SetupInputFileSequence(NULL,rfile, NULL); if ( tstring ) { if ( !ScanTimeFrame(tstring, &t_start, &t_end) ) exit(255); } send_data(rfile, t_start, t_end, count, delay, confirm, netflow_version); FreeExtensionMaps(extension_map_list); return 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
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; }