示例#1
0
int main( int argc, char **argv ) {
char 		*rfile, *Rfile, *Mdirs;
int			c;

	rfile = Rfile = Mdirs = NULL;
	while ((c = getopt(argc, argv, "L:r:M:R:")) != EOF) {
		switch (c) {
			case 'h':
				usage(argv[0]);
				exit(0);
				break;
				break;
			case 'L':
				if ( !InitLog("argv[0]", optarg) )
					exit(255);
				break;
			case 'r':
				rfile = optarg;
				if ( strcmp(rfile, "-") == 0 )
					rfile = NULL;
				break;
			case 'M':
				Mdirs = optarg;
				break;
			case 'R':
				Rfile = optarg;
				break;
			default:
				usage(argv[0]);
				exit(0);
		}
	}

	if ( rfile && Rfile ) {
		fprintf(stderr, "-r and -R are mutually exclusive. Please specify either -r or -R\n");
		exit(255);
	}
	if ( Mdirs && !(rfile || Rfile) ) {
		fprintf(stderr, "-M needs either -r or -R to specify the file or file list. Add '-R .' for all files in the directories.\n");
		exit(255);
	}

	InitExtensionMaps(&extension_map_list);

	SetupInputFileSequence(Mdirs, rfile, Rfile);

	process_data();


	return 0;
}
示例#2
0
文件: nfx.c 项目: icsecurity/fan
void
FreeExtensionMaps (extension_map_list_t * extension_map_list)
{
  int i;

  if (extension_map_list == NULL)
    return;

  // free all maps
  for (i = 0; i <= extension_map_list->max_used; i++)
    {
      if (extension_map_list->slot[i])
	{
	  if (extension_map_list->slot[i]->map)
	    {
	      free (extension_map_list->slot[i]->map);
	      extension_map_list->slot[i]->map = NULL;
	    }
	  free (extension_map_list->slot[i]);
	  extension_map_list->slot[i] = NULL;
	}

    }

  // free all paged maps
  for (i = 0; i < extension_map_list->next_free; i++)
    {
      if (extension_map_list->page[i])
	{
	  if (extension_map_list->page[i]->map)
	    {
	      free (extension_map_list->page[i]->map);
	      extension_map_list->page[i]->map = NULL;
	    }
	  free (extension_map_list->page[i]);
	  extension_map_list->page[i] = NULL;
	}
    }

  InitExtensionMaps (extension_map_list);

}				// End of FreeExtensionMaps
示例#3
0
文件: nfdump.c 项目: gitpan/libnf
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;
}
示例#4
0
文件: nfreplay.c 项目: phaag/nfdump
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;
}
示例#5
0
int main(int argc, char **argv) {
 
char	*bindhost, *filter, *datadir, pidstr[32], *launch_process;
char	*userid, *groupid, *checkptr, *listenport, *mcastgroup, *extension_tags;
char	*Ident, *dynsrcdir, pidfile[MAXPATHLEN];
struct stat fstat;
packet_function_t receive_packet;
send_peer_t  peer;
FlowSource_t *fs;
struct sigaction act;
int		family, bufflen;
time_t 	twin, t_start;
int		sock, synctime, do_daemonize, expire, report_sequence, do_xstat;
int		subdir_index, sampling_rate, compress;
int		c;
#ifdef PCAP
char	*pcap_file;
 
	pcap_file		= NULL;
#endif

	receive_packet 	= recvfrom;
	verbose = synctime = do_daemonize = 0;
	bufflen  		= 0;
	family			= AF_UNSPEC;
	launcher_pid	= 0;
	launcher_alive	= 0;
	report_sequence	= 0;
	listenport		= DEFAULTCISCOPORT;
	bindhost 		= NULL;
	mcastgroup		= NULL;
	pidfile[0]		= 0;
	filter   		= NULL;
	launch_process	= NULL;
	userid 			= groupid = NULL;
	twin	 		= TIME_WINDOW;
	datadir	 		= NULL;
	subdir_index	= 0;
	expire			= 0;
	sampling_rate	= 1;
	compress		= 0;
	do_xstat		= 0;
	memset((void *)&peer, 0, sizeof(send_peer_t));
	peer.family		= AF_UNSPEC;
	Ident			= "none";
	FlowSource		= NULL;
	extension_tags	= DefaultExtensions;
	dynsrcdir		= NULL;

	while ((c = getopt(argc, argv, "46ef:whEVI:DB:b:j:l:M:n:p:P:R:S:s:T:t:x:Xru:g:z")) != EOF) {
		switch (c) {
			case 'h':
				usage(argv[0]);
				exit(0);
				break;
			case 'u':
				userid  = optarg;
				break;
			case 'g':
				groupid  = optarg;
				break;
			case 'e':
				expire = 1;
				break;
			case 'f': {
#ifdef PCAP
				struct stat	fstat;
				pcap_file = optarg;
				stat(pcap_file, &fstat);
				if ( !S_ISREG(fstat.st_mode) ) {
					fprintf(stderr, "Not a regular file: %s\n", pcap_file);
					exit(254);
				}
#else
				fprintf(stderr, "PCAP reader not compiled! Option ignored!\n");
#endif
				} break;
			case 'E':
				verbose = 1;
				Setv6Mode(1);
				break;
			case 'V':
				printf("%s: Version: %s\n",argv[0], nfdump_version);
				exit(0);
				break;
			case 'X':
				do_xstat = 1;
				break;
			case 'D':
				do_daemonize = 1;
				break;
			case 'I':
				Ident = strdup(optarg);
				break;
			case 'M':
				dynsrcdir = strdup(optarg);
				if ( strlen(dynsrcdir) > MAXPATHLEN ) {
					fprintf(stderr, "ERROR: Path too long!\n");
					exit(255);
				}
				if ( stat(dynsrcdir, &fstat) < 0 ) {
					fprintf(stderr, "stat() failed on %s: %s\n", dynsrcdir, strerror(errno));
					exit(255);
				}
				if ( !(fstat.st_mode & S_IFDIR) ) {
					fprintf(stderr, "No such directory: %s\n", dynsrcdir);
					break;
				}
				if ( !SetDynamicSourcesDir(&FlowSource, dynsrcdir) ) {
					fprintf(stderr, "-l, -M and -n are mutually exclusive\n");
					break;
				}
				break;
			case 'n':
				if ( AddFlowSource(&FlowSource, optarg) != 1 ) 
					exit(255);
				break;
			case 'w':
				synctime = 1;
				break;
			case 'B':
				bufflen = strtol(optarg, &checkptr, 10);
				if ( (checkptr != NULL && *checkptr == 0) && bufflen > 0 )
					break;
				fprintf(stderr,"Argument error for -B\n");
				exit(255);
			case 'b':
				bindhost = optarg;
				break;
			case 'j':
				mcastgroup = optarg;
				break;
			case 'p':
				listenport = optarg;
				break;
			case 'P':
				if ( optarg[0] == '/' ) { 	// absolute path given
					strncpy(pidfile, optarg, MAXPATHLEN-1);
				} else {					// path relative to current working directory
					char tmp[MAXPATHLEN];
					if ( !getcwd(tmp, MAXPATHLEN-1) ) {
						fprintf(stderr, "Failed to get current working directory: %s\n", strerror(errno));
						exit(255);
					}
					tmp[MAXPATHLEN-1] = 0;
					snprintf(pidfile, MAXPATHLEN - 1 - strlen(tmp), "%s/%s", tmp, optarg);
				}
				// pidfile now absolute path
				pidfile[MAXPATHLEN-1] = 0;
				break;
			case 'R': {
				char *p = strchr(optarg, '/');
				if ( p ) { 
					*p++ = '\0';
					peer.port = strdup(p);
				} else {
					peer.port = DEFAULTCISCOPORT;
				}
				peer.hostname = strdup(optarg);

				break; }
			case 'r':
				report_sequence = 1;
				break;
			case 's':
				// a negative sampling rate is set as the overwrite sampling rate
				sampling_rate = (int)strtol(optarg, (char **)NULL, 10);
				if ( (sampling_rate == 0 ) ||
					 (sampling_rate < 0 && sampling_rate < -10000000) ||
					 (sampling_rate > 0 && sampling_rate > 10000000) ) {
					fprintf(stderr, "Invalid sampling rate: %s\n", optarg);
					exit(255);
				} 
				break;
			case 'T': {
				size_t len = strlen(optarg);
				extension_tags = optarg;
				if ( len == 0 || len > 128 ) {
					fprintf(stderr, "Extension length error. Unexpected option '%s'\n", extension_tags);
					exit(255);
				}
				break; }
			case 'l':
				datadir = optarg;
				if ( strlen(datadir) > MAXPATHLEN ) {
					fprintf(stderr, "ERROR: Path too long!\n");
					exit(255);
				}
				if ( stat(datadir, &fstat) < 0 ) {
					fprintf(stderr, "stat() failed on %s: %s\n", datadir, strerror(errno));
					exit(255);
				}
				if ( !(fstat.st_mode & S_IFDIR) ) {
					fprintf(stderr, "No such directory: %s\n", datadir);
					break;
				}
				break;
			case 'S':
				subdir_index = atoi(optarg);
				break;
			case 't':
				twin = atoi(optarg);
				if ( twin <= 0 ) {
					fprintf(stderr, "ERROR: time frame <= 0\n");
					exit(255);
				}
				if (twin < 10) {
					fprintf(stderr, "WARNING, Very small time frame - < 10s!\n");
				}
				break;
			case 'x':
				launch_process = optarg;
				break;
			case 'z':
				compress = 1;
				break;
			case '4':
				if ( family == AF_UNSPEC )
					family = AF_INET;
				else {
					fprintf(stderr, "ERROR, Accepts only one protocol IPv4 or IPv6!\n");
					exit(255);
				}
				break;
			case '6':
				if ( family == AF_UNSPEC )
					family = AF_INET6;
				else {
					fprintf(stderr, "ERROR, Accepts only one protocol IPv4 or IPv6!\n");
					exit(255);
				}
				break;
			default:
				usage(argv[0]);
				exit(255);
		}
	}
	
	if ( FlowSource == NULL && datadir == NULL && dynsrcdir == NULL ) {
		fprintf(stderr, "ERROR, Missing -n (-l/-I) or -M source definitions\n");
		exit(255);
	}
	if ( FlowSource == NULL && datadir != NULL && !AddDefaultFlowSource(&FlowSource, Ident, datadir) ) {
		fprintf(stderr, "Failed to add default data collector directory\n");
		exit(255);
	}

	if ( bindhost && mcastgroup ) {
		fprintf(stderr, "ERROR, -b and -j are mutually exclusive!!\n");
		exit(255);
	}

	if ( do_daemonize && !InitLog(argv[0], SYSLOG_FACILITY)) {
		exit(255);
	}

	InitExtensionMaps(NO_EXTENSION_LIST);
	SetupExtensionDescriptors(strdup(extension_tags));

	// Debug code to read from pcap file
#ifdef PCAP
	sock = 0;
	if ( pcap_file ) {
		printf("Setup pcap reader\n");
		setup_packethandler(pcap_file, NULL);
		receive_packet 	= NextPacket;
	} else 
#endif
	if ( mcastgroup ) 
		sock = Multicast_receive_socket (mcastgroup, listenport, family, bufflen);
	else 
		sock = Unicast_receive_socket(bindhost, listenport, family, bufflen );

	if ( sock == -1 ) {
		fprintf(stderr,"Terminated due to errors.\n");
		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 )
			exit(255);
		LogInfo("Replay flows to host: %s port: %s", peer.hostname, peer.port);
	}

	if ( sampling_rate < 0 ) {
		default_sampling = -sampling_rate;
		overwrite_sampling = default_sampling;
	} else {
		default_sampling = sampling_rate;
	}

	SetPriv(userid, groupid);

	if ( subdir_index && !InitHierPath(subdir_index) ) {
		close(sock);
		exit(255);
	}

	// check if pid file exists and if so, if a process with registered pid is running
	if ( strlen(pidfile) ) {
		int pidf;
		pidf = open(pidfile, O_RDONLY, 0);
		if ( pidf > 0 ) {
			// pid file exists
			char s[32];
			ssize_t len;
			len = read(pidf, (void *)s, 31);
			close(pidf);
			s[31] = '\0';
			if ( len < 0 ) {
				fprintf(stderr, "read() error existing pid file: %s\n", strerror(errno));
				exit(255);
			} else {
				unsigned long pid = atol(s);
				if ( pid == 0 ) {
					// garbage - use this file
					unlink(pidfile);
				} else {
					if ( kill(pid, 0) == 0 ) {
						// process exists
						fprintf(stderr, "A process with pid %lu registered in pidfile %s is already running!\n", 
							pid, strerror(errno));
						exit(255);
					} else {
						// no such process - use this file
						unlink(pidfile);
					}
				}
			}
		} else {
			if ( errno != ENOENT ) {
				fprintf(stderr, "open() error existing pid file: %s\n", strerror(errno));
				exit(255);
			} // else errno == ENOENT - no file - this is fine
		}
	}

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


	t_start = time(NULL);
	if ( synctime )
		t_start = t_start - ( t_start % twin);

	if ( do_daemonize ) {
		verbose = 0;
		daemonize();
	}
	if (strlen(pidfile)) {
		pid_t pid = getpid();
		int pidf  = open(pidfile, O_RDWR|O_TRUNC|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
		if ( pidf == -1 ) {
			LogError("Error opening pid file: '%s' %s", pidfile, strerror(errno));
			close(sock);
			exit(255);
		}
		snprintf(pidstr,31,"%lu\n", (unsigned long)pid);
		if ( write(pidf, pidstr, strlen(pidstr)) <= 0 ) {
			LogError("Error write pid file: '%s' %s", pidfile, strerror(errno));
		}
		close(pidf);
	}

	done = 0;
	if ( launch_process || expire ) {
		// for efficiency reason, the process collecting the data
		// and the process launching processes, when a new file becomes
		// available are separated. Communication is done using signals
		// as well as shared memory
		// prepare shared memory
		shmem = mmap(0, sizeof(srecord_t), PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
		if ( shmem == (caddr_t)-1 ) {
			LogError("mmap() error: %s", strerror(errno));
			close(sock);
			exit(255);
		}

		launcher_pid = fork();
		switch (launcher_pid) {
			case 0:
				// child
				close(sock);
				launcher((char *)shmem, FlowSource, launch_process, expire);
				_exit(0);
				break;
			case -1:
				LogError("fork() error: %s", strerror(errno));
				if ( strlen(pidfile) )
					unlink(pidfile);
				exit(255);
				break;
			default:
				// parent
			launcher_alive = 1;
			LogInfo("Launcher[%i] forked", launcher_pid);
		}
	}

	fs = FlowSource;
	while ( fs ) {
		if ( InitBookkeeper(&fs->bookkeeper, fs->datadir, getpid(), launcher_pid) != BOOKKEEPER_OK ) {
			LogError("initialize bookkeeper failed.");

			// release all already allocated bookkeepers
			fs = FlowSource;
			while ( fs && fs->bookkeeper ) {
				ReleaseBookkeeper(fs->bookkeeper, DESTROY_BOOKKEEPER);
				fs = fs->next;
			}
			close(sock);
			if ( launcher_pid )
				kill_launcher(launcher_pid);
			if ( strlen(pidfile) )
				unlink(pidfile);
			exit(255);
		}

		// Init the extension map list
		if ( !InitExtensionMapList(fs) ) {
			// error message goes to syslog
			exit(255);
		}

		fs = fs->next;
	}

	/* Signal handling */
	memset((void *)&act,0,sizeof(struct sigaction));
	act.sa_handler = IntHandler;
	sigemptyset(&act.sa_mask);
	act.sa_flags = 0;
	sigaction(SIGTERM, &act, NULL);
	sigaction(SIGINT, &act, NULL);
	sigaction(SIGHUP, &act, NULL);
	sigaction(SIGALRM, &act, NULL);
	sigaction(SIGCHLD, &act, NULL);

	LogInfo("Startup.");
	run(receive_packet, sock, peer, twin, t_start, report_sequence, subdir_index, compress, do_xstat);
	close(sock);
	kill_launcher(launcher_pid);

	fs = FlowSource;
	while ( fs && fs->bookkeeper ) {
		dirstat_t 	*dirstat;
		// if we do not auto expire and there is a stat file, update the stats before we leave
		if ( expire == 0 && ReadStatInfo(fs->datadir, &dirstat, LOCK_IF_EXISTS) == STATFILE_OK ) {
			UpdateBookStat(dirstat, fs->bookkeeper);
			WriteStatInfo(dirstat);
			LogInfo("Updating statinfo in directory '%s'", datadir);
		}

		ReleaseBookkeeper(fs->bookkeeper, DESTROY_BOOKKEEPER);
		fs = fs->next;
	}

	LogInfo("Terminating nfcapd.");
	EndLog();

	if ( strlen(pidfile) )
		unlink(pidfile);

	return 0;

} /* End of main */
示例#6
0
文件: libnf.c 项目: Lukas955/nf-tools
/* only simple wrapper to nfdump function */
int lnf_open(lnf_file_t **lnf_filep, const char * filename, unsigned int flags, const char * ident) {
	int i;
	lnf_file_t *lnf_file;

	lnf_file = malloc(sizeof(lnf_file_t));
	
	if (lnf_file == NULL) {
		return LNF_ERR_NOMEM;
	}


	lnf_file->flags = flags;
	/* open file in either read only or write only mode */
#ifdef LNF_THREADS
   	pthread_mutex_lock(&lnf_nfdump_filter_mutex);
#endif
	if (flags & LNF_APPEND) {

		lnf_file->nffile = AppendFile((char *)filename);

	} else if (flags & LNF_WRITE) {

		lnf_file->nffile = OpenNewFile((char *)filename, NULL, flags & LNF_COMP, 
								flags & LNF_ANON, (char *)ident);

	} else {

		lnf_file->nffile = OpenFile((char *)filename, NULL);

	}
#ifdef LNF_THREADS
   	pthread_mutex_unlock(&lnf_nfdump_filter_mutex);
#endif

	if (lnf_file->nffile == NULL) {
		free(lnf_file);
		return LNF_ERR_OTHER;;
	}

	lnf_file->blk_record_remains = 0;
	lnf_file->processed_blocks  = 0;
	lnf_file->processed_bytes  = 0;
	lnf_file->skipped_blocks  = 0;
#ifdef LNF_THREADS
    pthread_mutex_lock(&lnf_nfdump_filter_mutex);
#endif
	lnf_file->extension_map_list = InitExtensionMaps(NEEDS_EXTENSION_LIST);

	lnf_file->lnf_map_list = NULL;

	i = 1;
	lnf_file->max_num_extensions = 0;
	while ( extension_descriptor[i++].id )
		lnf_file->max_num_extensions++;

#ifdef LNF_THREADS
    pthread_mutex_unlock(&lnf_nfdump_filter_mutex);
#endif

	*lnf_filep = lnf_file;

	return LNF_OK;
}
示例#7
0
int main(int argc, char **argv)
{
      uint16_t duration_block = 0;
	char *rfile= NULL, *Rfile= NULL, *Mdirs= NULL,*duration = NULL;
	time_t startTime =0 , endTime=0;
	struct tm st,et;
	char *out_file = "./out_txt";
	int outfd[] = {0,0,0,0};
	int c = 0;

	rfile = Rfile = Mdirs = NULL;
	while ((c = getopt(argc, argv, "L:r:M:R:s:e:d:b:K:B:Y:H:S:a:t:O:")) != EOF) {
		switch (c) {
		case 'h':
			usage(argv[0]);
			exit(0);
		break;
		case 'L':
			if (!InitLog("argv[0]", optarg))
				exit(255);
		break;
		case 'r':
			rfile = optarg;
			if (strcmp(rfile, "-") == 0)
				rfile = NULL;
		break;
		case 'M':
			Mdirs = optarg;
		break;
		case 'R':
			Rfile = optarg;
		break;
		case 's':
		      memset(&st,0,sizeof(struct tm));
	            setenv("TZ", "CEST-2", 1);
		      //setenv("TZ", "GMT0", 1);
		      tzset();
		      strptime(optarg, "%Y-%m-%d %H:%M:%S", &st);
			startTime = mktime(&st);
		break;
		case 'e':
		      memset(&et,0,sizeof(struct tm));
                  setenv("TZ", "CEST-2", 1);
		      //setenv("TZ", "GMT0", 1);
                  tzset();
                  strptime(optarg,"%Y-%m-%d %H:%M:%S", &et);
			endTime = mktime(&et);
		break;
		case 'b':
			blksize = (uint32_t) strtol( optarg,NULL,10);
		break;
		case 'd':
		      duration_block = 1;
		      duration = optarg;
		break;
		case 'K':
		    set_stat_func(KULLBACK_ENTROPY);
		    set_stat_params((uint16_t) strtol( optarg,NULL,10));
		    nf_stat = KULLBACK_ENTROPY;
		break;
		case 'B':
		   set_stat_func(BASIC_STATS);
               set_stat_params((uint16_t) strtol( optarg,NULL,10));
               nf_stat = BASIC_STATS;
		break;
		case 'Y':
		   set_stat_func(RENYI);
               set_stat_params((uint16_t) strtol( optarg,NULL,10));
               nf_stat = RENYI;
		break;
		case 'H':
               set_stat_func(HISTO_STATS);
               set_stat_params((uint16_t) strtol( optarg,NULL,10));
               nf_stat = HISTO_STATS;
		break;
		case 'S':
		   set_stat_func(SORT);
               set_stat_params((uint16_t) strtol( optarg,NULL,10));
               nf_stat = SORT;
		break;
		case 'a':
		   alpha =  atof(optarg);
		break;
		case 't':
		   threshold = atof(optarg);
		   break;
		case 'O':
		   out_file = optarg;
		break;
		default:
			usage(argv[0]);
			exit(0);
		}
	}

	if (rfile && Rfile) {
		fprintf(stderr,
				"-r and -R are mutually exclusive. Please specify either -r or -R\n");
		exit(255);
	}
	if (Mdirs && !(rfile || Rfile)) {
		fprintf(stderr,
				"-M needs either -r or -R to specify the file or file list. Add '-R .' for all files in the directories.\n");
		exit(255);
	}
	if(duration_block != 0) {
	      endTime = startTime;
	      endTime += strtol(duration,NULL,10)*blksize;
            printf("startime: %d\toutfile endtime:%d\n",startTime,endTime);
	}



	init_file_out(nf_stat,outfd,out_file);
	InitExtensionMaps(&extension_map_list);
	SetupInputFileSequence(Mdirs, rfile, Rfile, startTime, endTime);
      sortAndProcessData(startTime,endTime,outfd);

	if(outfd[0] > 0) close(outfd[0]);
      if(outfd[1] > 0) close(outfd[1]);
      if(outfd[2] > 0) close(outfd[2]);
      if(outfd[3] > 0) close(outfd[3]);

      return 0;
}
示例#8
0
文件: nfpcapd.c 项目: jmagudo/nfdump
int main(int argc, char *argv[]) {
sigset_t			signal_set;
struct sigaction	sa;
int c, snaplen, err, do_daemonize;
int subdir_index, compress, expire, cache_size;
FlowSource_t	*fs;
dirstat_t 		*dirstat;
time_t 			t_win;
char 			*device, *pcapfile, *filter, *datadir, *pcap_datadir, *extension_tags, pidfile[MAXPATHLEN], pidstr[32];
char			*Ident, *userid, *groupid;
pcap_dev_t 		*pcap_dev;
p_packet_thread_args_t *p_packet_thread_args;
p_flow_thread_args_t *p_flow_thread_args;

	snaplen			= 100;
	do_daemonize	= 0;
	launcher_pid	= 0;
	device			= NULL;
	pcapfile		= NULL;
	filter			= NULL;
	pidfile[0]		= '\0';
	t_win			= TIME_WINDOW;
	datadir			= DEFAULT_DIR;
	pcap_datadir	= NULL;
	userid			= groupid = NULL;
	Ident			= "none";
	fs				= NULL;
	extension_tags	= DefaultExtensions;
	subdir_index	= 0;
	compress		= NOT_COMPRESSED;
	verbose			= 0;
	expire			= 0;
	cache_size		= 0;
	while ((c = getopt(argc, argv, "B:DEI:g:hi:j:r:s:l:p:P:t:u:S:T:e:Vz")) != EOF) {
		switch (c) {
			struct stat fstat;
			case 'h':
				usage(argv[0]);
				exit(0);
				break;
			case 'u':
				userid  = optarg;
				break;
			case 'g':
				groupid  = optarg;
				break;
			case 'D':
				do_daemonize = 1;
				break;
			case 'B':
				cache_size = atoi(optarg);
				if (cache_size <= 0) {
					LogError("ERROR: Cache size must not be < 0");
					exit(EXIT_FAILURE);
				}
				break;
			case 'I':
				Ident = strdup(optarg);
				break;
			case 'i':
				device = optarg;
				break;
			case 'l':
				datadir = optarg;
				err  = stat(datadir, &fstat);
				if (!(fstat.st_mode & S_IFDIR)) {
					LogError("No such directory: " "'%s'", datadir);
					break;
				}
				break;
			case 'p':
				pcap_datadir = optarg;
				err  = stat(pcap_datadir, &fstat);
				if (!(fstat.st_mode & S_IFDIR)) {
					LogError("No such directory: " "'%s'", pcap_datadir);
					break;
				}
				break;
			case 'r': {
				struct stat stat_buf;
				pcapfile = optarg;
				if ( stat(pcapfile, &stat_buf) ) {
					LogError("Can't stat '%s': %s", pcapfile, strerror(errno));
					exit(EXIT_FAILURE);
				}
				if (!S_ISREG(stat_buf.st_mode) ) {
					LogError("'%s' is not a file", pcapfile);
					exit(EXIT_FAILURE);
				}
				} break;
			case 's':
				snaplen = atoi(optarg);
				if (snaplen < 14 + 20 + 20) { // ethernet, IP , TCP, no payload
					LogError("ERROR:, snaplen < sizeof IPv4 - Need 54 bytes for TCP/IPv4");
					exit(EXIT_FAILURE);
				}
				break;
			case 't':
				t_win = atoi(optarg);
				if (t_win < 60) {
					LogError("WARNING, very small time frame (< 60)!");
				}
				if (t_win <= 0) {
					LogError("ERROR: time frame too small (<= 0)");
					exit(EXIT_FAILURE);
				}
				break;
			case 'j':
				if ( compress ) {
					LogError("Use either -z for LZO or -j for BZ2 compression, but not both\n");
					exit(255);
				}
				compress = BZ2_COMPRESSED;
				break;
			case 'z':
				if ( compress ) {
					LogError("Use either -z for LZO or -j for BZ2 compression, but not both\n");
					exit(255);
				}
				compress = LZO_COMPRESSED;
				break;
			case 'P':
				if ( optarg[0] == '/' ) { 	// absolute path given
					strncpy(pidfile, optarg, MAXPATHLEN-1);
				} else {					// path relative to current working directory
					char tmp[MAXPATHLEN];
					if ( !getcwd(tmp, MAXPATHLEN-1) ) {
						fprintf(stderr, "Failed to get current working directory: %s\n", strerror(errno));
						exit(255);
					}
					tmp[MAXPATHLEN-1] = 0;
					snprintf(pidfile, MAXPATHLEN - 1 - strlen(tmp), "%s/%s", tmp, optarg);
				}
				// pidfile now absolute path
				pidfile[MAXPATHLEN-1] = 0;
				break;
			case 'S':
				subdir_index = atoi(optarg);
				break;
			case 'T': {
				size_t len = strlen(optarg);
				extension_tags = optarg;
				if ( len == 0 || len > 128 ) {
					fprintf(stderr, "Extension length error. Unexpected option '%s'\n", extension_tags);
					exit(255);
				}
				break; }
			case 'E':
				verbose = 1;
				Setv6Mode(1);
				break;
			case 'V':
				printf("%s: Version: %s\n",argv[0], nfdump_version);
				exit(0);
				break;
			default:
				usage(argv[0]);
				exit(EXIT_FAILURE);
		}
	}

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

	if ( fs == NULL && datadir != NULL && !AddDefaultFlowSource(&fs, Ident, datadir) ) {
		fprintf(stderr, "Failed to add default data collector directory\n");
		exit(255);
	}

	if ( device && pcapfile ) {
		LogError("Specify either a device or a pcapfile, but not both");
		exit(EXIT_FAILURE);
	}

	if ( !device && !pcapfile ) {
		LogError("Specify either a device or a pcapfile to read packets from");
		exit(EXIT_FAILURE);
	}

	
	if ( !Init_FlowTree(cache_size)) {
		LogError("Init_FlowTree() failed.");
		exit(EXIT_FAILURE);
	}

	InitExtensionMaps(NO_EXTENSION_LIST);
	SetupExtensionDescriptors(strdup(extension_tags));

	if ( pcapfile ) {
		pcap_dev = setup_pcap_file(pcapfile, filter, snaplen);
	} else {
		pcap_dev = setup_pcap_live(device, filter, snaplen);
	}
	if (!pcap_dev) {
		exit(EXIT_FAILURE);
	}

	SetPriv(userid, groupid);

	if ( subdir_index && !InitHierPath(subdir_index) ) {
		pcap_close(pcap_dev->handle);
		exit(255);
	}

	if ( do_daemonize && !InitLog(argv[0], SYSLOG_FACILITY)) {
		pcap_close(pcap_dev->handle);
		exit(255);
	}

	// check if pid file exists and if so, if a process with registered pid is running
	if ( strlen(pidfile) ) {
		int pidf;
		pidf = open(pidfile, O_RDONLY, 0);
		if ( pidf > 0 ) {
			// pid file exists
			char s[32];
			ssize_t len;
			len = read(pidf, (void *)s, 31);
			close(pidf);
			s[31] = '\0';
			if ( len < 0 ) {
				fprintf(stderr, "read() error existing pid file: %s\n", strerror(errno));
				pcap_close(pcap_dev->handle);
				exit(255);
			} else {
				unsigned long pid = atol(s);
				if ( pid == 0 ) {
					// garbage - use this file
					unlink(pidfile);
				} else {
					if ( kill(pid, 0) == 0 ) {
						// process exists
						fprintf(stderr, "A process with pid %lu registered in pidfile %s is already running!\n", 
							pid, strerror(errno));
						pcap_close(pcap_dev->handle);
						exit(255);
					} else {
						// no such process - use this file
						unlink(pidfile);
					}
				}
			}
		} else {
			if ( errno != ENOENT ) {
				fprintf(stderr, "open() error existing pid file: %s\n", strerror(errno));
				pcap_close(pcap_dev->handle);
				exit(255);
			} // else errno == ENOENT - no file - this is fine
		}
	}

	if ( do_daemonize ) {
		verbose = 0;
		daemonize();
	}

	if (strlen(pidfile)) {
		pid_t pid = getpid();
		int pidf  = open(pidfile, O_RDWR|O_TRUNC|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
		if ( pidf == -1 ) {
			LogError("Error opening pid file: '%s' %s", pidfile, strerror(errno));
			pcap_close(pcap_dev->handle);
			exit(255);
		}
		snprintf(pidstr,31,"%lu\n", (unsigned long)pid);
		if ( write(pidf, pidstr, strlen(pidstr)) <= 0 ) {
			LogError("Error write pid file: '%s' %s", pidfile, strerror(errno));
		}
		close(pidf);
	}

	if ( InitBookkeeper(&fs->bookkeeper, fs->datadir, getpid(), launcher_pid) != BOOKKEEPER_OK ) {
			LogError("initialize bookkeeper failed.");
			pcap_close(pcap_dev->handle);
			exit(255);
	}

	// Init the extension map list
	if ( !InitExtensionMapList(fs) ) {
		// error message goes to syslog
		pcap_close(pcap_dev->handle);
		exit(255);
	}

	IPFragTree_init();

	LogInfo("Startup.");
	// prepare signal mask for all threads
	// block signals, as they are handled by the main thread
	// mask is inherited by all threads
	sigemptyset(&signal_set);
	sigaddset(&signal_set, SIGINT);
	sigaddset(&signal_set, SIGHUP);
	sigaddset(&signal_set, SIGTERM);
	sigaddset(&signal_set, SIGUSR1);
	sigaddset(&signal_set, SIGPIPE);
	pthread_sigmask(SIG_BLOCK, &signal_set, NULL);

	// for USR2 set a signal handler, which interrupts blocking
	// system calls - and signals done event
	// handler applies for all threads in a process
	sa.sa_handler = Interrupt_handler;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	sigaction(SIGPIPE, &sa, NULL);
	sigaction(SIGUSR2, &sa, NULL);

	// key for each thread
	err = pthread_key_create(&buffer_key, NULL);
	if ( err ) {
		LogError("pthread_key() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) );
		exit(255);
	}

	// prepare flow thread args
	p_flow_thread_args = (p_flow_thread_args_t *)malloc(sizeof(p_flow_thread_args_t));
	if ( !p_flow_thread_args ) {
		LogError("malloc() error in %s line %d: %s\n", 
			__FILE__, __LINE__, strerror(errno) );
		exit(255);
	}	
	p_flow_thread_args->fs 	   	   = fs;
	p_flow_thread_args->t_win 	   = t_win;
	p_flow_thread_args->compress   = compress;
	p_flow_thread_args->subdir_index = subdir_index;
	p_flow_thread_args->parent	   = pthread_self();
	p_flow_thread_args->NodeList   = NewNodeList();

	err = 0;
	err = pthread_create(&p_flow_thread_args->tid, NULL, p_flow_thread, (void *)p_flow_thread_args);
	if ( err ) {
		LogError("pthread_create() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) );
		exit(255);
	}
	dbg_printf("Started flow thread[%lu]\n", (long unsigned)p_flow_thread_args->tid);

	// prepare packet thread args
	p_packet_thread_args = (p_packet_thread_args_t *)malloc(sizeof(p_packet_thread_args_t));
	if ( !p_packet_thread_args ) {
		LogError("malloc() error in %s line %d: %s\n", 
			__FILE__, __LINE__, strerror(errno) );
		exit(255);
	}	
	p_packet_thread_args->pcap_dev 	   = pcap_dev;
	p_packet_thread_args->t_win 	   = t_win;
	p_packet_thread_args->subdir_index = subdir_index;
	p_packet_thread_args->pcap_datadir = pcap_datadir;
	p_packet_thread_args->live 	   	   = device != NULL;
	p_packet_thread_args->parent	   = pthread_self();
	p_packet_thread_args->NodeList	   = p_flow_thread_args->NodeList;

	err = pthread_create(&p_packet_thread_args->tid, NULL, p_packet_thread, (void *)p_packet_thread_args);
	if ( err ) {
		LogError("pthread_create() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) );
		exit(255);
	}
	dbg_printf("Started packet thread[%lu]\n", (long unsigned)p_packet_thread_args->tid);

	// Wait till done
	WaitDone();

	dbg_printf("Signal packet thread to terminate\n");
	SignalThreadTerminate((thread_info_t *)p_packet_thread_args, NULL);

	dbg_printf("Signal flow thread to terminate\n");
	SignalThreadTerminate((thread_info_t *)p_flow_thread_args, &p_packet_thread_args->NodeList->c_list);

	// free arg list
	free((void *)p_packet_thread_args);
	free((void *)p_flow_thread_args);

	LogInfo("Terminating nfpcapd.");

	if ( expire == 0 && ReadStatInfo(fs->datadir, &dirstat, LOCK_IF_EXISTS) == STATFILE_OK ) {
		UpdateBookStat(dirstat, fs->bookkeeper);
		WriteStatInfo(dirstat);
		LogInfo("Updating statinfo in directory '%s'", datadir);
	}

	ReleaseBookkeeper(fs->bookkeeper, DESTROY_BOOKKEEPER);
	pcap_close(pcap_dev->handle);

	if ( strlen(pidfile) )
		unlink(pidfile);

	EndLog();

	exit(EXIT_SUCCESS);
} /* End of main */
示例#9
0
int main( int argc, char **argv ) {
unsigned int		num_channels, compress;
struct stat stat_buf;
profile_param_info_t *profile_list;
char *rfile, *ffile, *filename, *Mdirs, *tstring;
char	*profile_datadir, *profile_statdir, *nameserver;
int c, syntax_only, subdir_index, stdin_profile_params, do_xstat;
time_t tslot;

	tstring 		= NULL;
	profile_datadir = NULL;
	profile_statdir = NULL;
	Mdirs 			= NULL;
	tslot 			= 0;
	syntax_only	    = 0;
	do_xstat	    = 0;
	compress		= 0;
	subdir_index	= 0;
	profile_list	= NULL;
	nameserver		= NULL;
	stdin_profile_params = 0;
	is_anonymized	= 0;

	strncpy(Ident, "none", IDENTLEN);
	Ident[IDENTLEN-1] = '\0';

	// default file names
	ffile = "filter.txt";
	rfile = NULL;
	while ((c = getopt(argc, argv, "D:HIL:p:P:hf:r:n:M:S:t:VzZ")) != EOF) {
		switch (c) {
			case 'h':
				usage(argv[0]);
				exit(0);
				break;
			case 'D':
				nameserver = optarg;
				if ( !set_nameserver(nameserver) ) {
					exit(255);
				}
				break;
			case 'I':
				stdin_profile_params = 1;
				break;
			case 'H':
				do_xstat = 1;
				break;
			case 'L':
				if ( !InitLog("nfprofile", optarg) )
					exit(255);
				break;
			case 'Z':
				syntax_only = 1;
				break;
			case 'p':
				profile_datadir = optarg;
				break;
			case 'P':
				profile_statdir = optarg;
				break;
			case 'S':
				subdir_index = atoi(optarg);
				break;
			case 'V':
				printf("%s: Version: %s\n",argv[0], nfdump_version);
				exit(0);
				break;
			case 'f':
				ffile = optarg;
				break;
			case 't':
				tslot = atoi(optarg);
				break;
			case 'M':
				Mdirs = optarg;
				break;
			case 'r':
				rfile = optarg;
				break;
			case 'z':
				compress = 1;
				break;
			default:
				usage(argv[0]);
				exit(0);
		}
	}

	if ( subdir_index && !InitHierPath(subdir_index) ) {
		exit(255);
	}

	if ( !profile_datadir ) {
		LogError("Profile data directory required!\n");
		exit(255);
	}

	if ( !profile_statdir ) {
		profile_statdir = profile_datadir;
	}

	if ( stat(profile_datadir, &stat_buf) || !S_ISDIR(stat_buf.st_mode) ) {
		LogError("'%s' not a directory\n", profile_datadir);
		exit(255);
	}

	if ( stdin_profile_params ) {
		profile_list = ParseParams(profile_datadir);
		if ( !profile_list ) {
			exit(254);
		}
	}

	if ( syntax_only ) {
		filename = NULL;
		rfile = NULL;
	} else {
		char *p;
		if ( rfile == NULL ) {
			LogError("-r filename required!\n");
			exit(255);
		}
		p = strrchr(rfile, '/');
		filename = p == NULL ? rfile : ++p;
		if ( strlen(filename) == 0 ) {
			LogError("Filename error: zero length filename\n");
			exit(254);
		}
	} 

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

	num_channels = InitChannels(profile_datadir, profile_statdir, profile_list, ffile, filename, subdir_index, syntax_only, compress, do_xstat);

	// nothing to do
	if ( num_channels == 0 ) {
		LogInfo("No channels to process.\n");
		return 0;
	}

	if ( syntax_only ) {
		printf("Syntax check done.\n");
		return 0;
	}

	if ( !rfile ) {
		LogError("Input file (-r) required!\n");
		exit(255);
	}

	extension_map_list = InitExtensionMaps(NEEDS_EXTENSION_LIST);
	if ( !InitExporterList() ) {
		exit(255);
	}

	SetupInputFileSequence(Mdirs,rfile, NULL);

	process_data(GetChannelInfoList(), num_channels, tslot, do_xstat);

	CloseChannels(tslot, compress);

	FreeExtensionMaps(extension_map_list);

	return 0;
}
示例#10
0
文件: ft2nfdump.c 项目: phaag/nfdump
extension_info_t *GenExtensionMap(struct ftio *ftio) {
extension_info_t *extension_info;
int	i;

   	if (ftio_check_xfield(ftio, FT_XFIELD_DPKTS |
		FT_XFIELD_DOCTETS | FT_XFIELD_FIRST | FT_XFIELD_LAST | 
		FT_XFIELD_SRCADDR | FT_XFIELD_DSTADDR |
		FT_XFIELD_SRCPORT | FT_XFIELD_DSTPORT | 
		FT_XFIELD_UNIX_SECS | FT_XFIELD_UNIX_NSECS | FT_XFIELD_SYSUPTIME |
		FT_XFIELD_TOS | FT_XFIELD_TCP_FLAGS | FT_XFIELD_PROT)) {
		fprintf(stderr,"Flow-tools record missing required fields.");
		return NULL;
	}

	InitExtensionMaps(NO_EXTENSION_LIST);
	extension_info = (extension_info_t *)malloc(sizeof(extension_info_t));
	if ( !extension_info  ) {
		fprintf(stderr, "malloc() error in %s line %d: %s\n", __FILE__, __LINE__, strerror (errno));
		return NULL;
	}
	memset((void *)extension_info, 0, sizeof(extension_info_t));

	extension_info->map  = (extension_map_t *)malloc(sizeof(extension_map_t) + Max_num_extensions * sizeof(uint16_t));
	if ( !extension_info->map  ) {
		fprintf(stderr, "malloc() error in %s line %d: %s\n", __FILE__, __LINE__, strerror (errno));
		return NULL;
	}

	i = 0;
	extension_info->map->type 		= ExtensionMapType;
	extension_info->map->map_id 	= 0;

   	if ( !ftio_check_xfield(ftio, FT_XFIELD_INPUT | FT_XFIELD_OUTPUT )) {
		extension_info->map->ex_id[i++] = EX_IO_SNMP_2;
	}

   	if (!ftio_check_xfield(ftio, FT_XFIELD_SRC_AS | FT_XFIELD_DST_AS)) {
		extension_info->map->ex_id[i++] = EX_AS_2;
	}

   	if (!ftio_check_xfield(ftio, FT_XFIELD_SRC_MASK | FT_XFIELD_DST_MASK)) {
		extension_info->map->ex_id[i++] = EX_MULIPLE;
	}

   	if (!ftio_check_xfield(ftio, FT_XFIELD_NEXTHOP )) {
		extension_info->map->ex_id[i++] = EX_NEXT_HOP_v4;
	}

   	if (!ftio_check_xfield(ftio, FT_XFIELD_EXADDR )) {
		extension_info->map->ex_id[i++] = EX_ROUTER_IP_v4;
	}

   	if (!ftio_check_xfield(ftio, FT_XFIELD_ENGINE_TYPE )) {
		extension_info->map->ex_id[i++] = EX_ROUTER_ID;
	}

	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++;
	}

	return extension_info;

} // End of GenExtensionMap