Example #1
0
void parse_command_line_parameters(int argc, char **argv){
	/* parse command line */
	int c;
	while ((c=getopt(argc, argv, "hf:v:")) != -1) {

		switch (c) {

			case 'f':
				config_file = optarg;
				break;

			case 'v':
				msg_setlevel(atoi(optarg));
				break;

			case 'h':
			default:
				/* print usage and quit vermont, if unknow switch */
				usage();
				exit(1);
		}
	}
	if (config_file == NULL)
	{
		usage();
		exit(1);
	}
}
int main(int argc, char *argv[]) {

	int lport = DEFAULT_LISTEN_PORT;
	std::string proto = "udp";

	msg_setlevel(MSG_DEBUG);
	
	signal(SIGINT, sigint);

	if (!(argc == 1 || argc == 2 || argc == 3)) {
		usage();
		return -1;
	}
	
	if (argc == 2)
		proto = argv[1];
	if (argc == 3)
		lport = atoi(argv[2]);

	IpfixReceiver* ipfixReceiver = 0;
	if (proto == "udp") {
		msg(MSG_INFO, "Creating UDP listener on port %i", lport);
		ipfixReceiver = new IpfixReceiverUdpIpV4(lport);
	} else if (proto == "sctp") {
#ifdef SUPPORT_SCTP
		ipfixReceiver = new IpfixReceiverSctpIpV4(lport, "127.0.0.1");
#else
		msg(MSG_FATAL, "testcollector has been compiled without sctp support");
		return -1;
#endif
	} else {
		msg(MSG_FATAL, "Protocol %s is not supported as a transport protocol for IPFIX data", proto.c_str()); 
		return -1;
	}

	IpfixCollector collector(ipfixReceiver);
	ConnectionQueue<IpfixRecord*> queue(100);
	IpfixPrinter printer;

	collector.connectTo(&queue);
	queue.connectTo(&printer);

	printer.start();
	queue.start();
	collector.start();

	msg(MSG_DIALOG, "Hit Ctrl+C to quit");
	pause();
	msg(MSG_DIALOG, "Stopping threads and tidying up.\n");

	msg(MSG_DIALOG, "stopping collector\n");
	collector.shutdown();
	queue.shutdown();
	printer.shutdown();

	return 0;
}
int main(int argc, char *argv[]) {

        int lport = DEFAULT_LISTEN_PORT;

        msg_setlevel(MSG_DEFAULT);

        signal(SIGINT, sigint);

        if(argv[1]) {
                lport=atoi(argv[1]);
        }

	initializeIpfixPrinters();

	initializeIpfixCollectors();

	IpfixPrinter* ipfixPrinter = createIpfixPrinter();
	startIpfixPrinter(ipfixPrinter);

	IpfixCollector* ipfixCollector = createIpfixCollector();
	IpfixReceiver* ipfixReceiver = createIpfixReceiver(UDP_IPV4, lport);
	addIpfixReceiver(ipfixCollector, ipfixReceiver);

	IpfixPacketProcessor* ipfixPacketProcessor = createIpfixPacketProcessor();
	IpfixParser* ipfixParser = createIpfixParser();

	/* (not in this branch of rcvIpfix)
	if (argc > 2) {
		msg(MSG_DIALOG, "Adding %s to list of authorized hosts", argv[2]);
		addIpfixReceiverAuthorizedHost(ipfixReceiver, argv[2]);
		}
	*/

	addIpfixParserCallbacks(ipfixParser, getIpfixPrinterCallbackInfo(ipfixPrinter));
	setIpfixParser(ipfixPacketProcessor, ipfixParser);
	addIpfixPacketProcessor(ipfixCollector, ipfixPacketProcessor);

	startIpfixCollector(ipfixCollector);

	msg(MSG_DIALOG, "Listening on %d. Hit Ctrl+C to quit", lport);
	pause();
	msg(MSG_DIALOG, "Stopping threads and tidying up.");
	
	stopIpfixCollector(ipfixCollector);
	destroyIpfixCollector(ipfixCollector);
 	deinitializeIpfixReceivers();	

	stopIpfixPrinter(ipfixPrinter);
	destroyIpfixPrinter(ipfixPrinter);
	deinitializeIpfixPrinters();

	return 0;
	}
int main(int argc, char *argv[]) {

	int lport = DEFAULT_LISTEN_PORT;

	msg_setlevel(MSG_DEFAULT);

	signal(SIGINT, sigint);

	if(argv[1]) {
		lport=atoi(argv[1]);
	}

	// needs to be a pointer because its freed in d'tor of IpfixCollector
	IpfixReceiverUdpIpV4* ipfixReceiver = new IpfixReceiverUdpIpV4(lport);
	IpfixCollector collector(ipfixReceiver);
	ConnectionQueue<IpfixRecord*> queue(100);
	IpfixPrinter printer;

	collector.connectTo(&queue);
	queue.connectTo(&printer);

	printer.start();
	queue.start();
	collector.start();





	// FIXME: test temporarily deactivated
	/*IpfixParser ipfixParser;
	ipfixParser.addFlowSink(&ipfixPrinter);

	IpfixCollector ipfixCollector;
	ipfixCollector.addIpfixReceiver(&ipfixReceiver);
	ipfixCollector.addIpfixPacketProcessor(&ipfixParser);
	ipfixCollector.start();*/

	msg(MSG_DIALOG, "Listening on %d. Hit Ctrl+C to quit\n", lport);
	pause();
	msg(MSG_DIALOG, "Stopping threads and tidying up.\n");

	collector.shutdown();
	queue.shutdown();
	printer.shutdown();


	return 0;
}
Test::TestResult  BloomFilterTestSuite::execTest()
{
	std::cout << "Running tests on BloomFilter classes" << std::endl;
	msg_init();
	msg_setlevel(100);
	setupGlobalKey();

	std::cout << "Testing BloomFilter..." << std::endl;
	testBloomFilter();
	
	std::cout << "Testing AgeBloomFilter..." << std::endl;
	testAgeBloomFilter();

	std::cout << "Testing CountBloomFilter..." << std::endl;
	testCountBloomFilter();

	std::cout << "All tests on all BloomFilter classes passed" << std::endl;

	return PASSED;
}
Test::TestResult ConnectionFilterTestSuite::execTest()
{
	std::cout << "running tests on ConnectionFilter" << std::endl;
	msg_init();
	msg_setlevel(100);
	captureDevice = pcap_open_offline("data/connectionfiltertest.pcap", errorBuffer);
	if (!captureDevice) {
		ERROR(errorBuffer);
	}

	Packet* p;
	ConnectionFilter connFilter(5, 100, 10, 1000);
	
	// first packet is a udp packet
	p = getNextPacket(captureDevice);
	REQUIRE(connFilter.processPacket(p) == false);

	// process six packets that come from a connection that did not have any syn packet
	p = getNextPacket(captureDevice);
	REQUIRE(connFilter.processPacket(p) == false);
        p = getNextPacket(captureDevice);
        REQUIRE(connFilter.processPacket(p) == false);
        p = getNextPacket(captureDevice);
        REQUIRE(connFilter.processPacket(p) == false);
        p = getNextPacket(captureDevice);
        REQUIRE(connFilter.processPacket(p) == false);
        p = getNextPacket(captureDevice);
        REQUIRE(connFilter.processPacket(p) == false);
        p = getNextPacket(captureDevice);
        REQUIRE(connFilter.processPacket(p) == false);

	// process a valid short 5 packets connection
        p = getNextPacket(captureDevice);
        REQUIRE(connFilter.processPacket(p) == false); // SYN
        p = getNextPacket(captureDevice);
        REQUIRE(connFilter.processPacket(p) == false); // SYN
        p = getNextPacket(captureDevice);
        REQUIRE(connFilter.processPacket(p) == true);
        p = getNextPacket(captureDevice);
        REQUIRE(connFilter.processPacket(p) == false); // FIN
        p = getNextPacket(captureDevice);
        REQUIRE(connFilter.processPacket(p) == false); // RST
	
	// process a valid connection
	// ignore the first syn packet
        p = getNextPacket(captureDevice);
        REQUIRE(connFilter.processPacket(p) == false); // SYN
        p = getNextPacket(captureDevice);
        REQUIRE(connFilter.processPacket(p) == false); // SYN
        p = getNextPacket(captureDevice);
        REQUIRE(connFilter.processPacket(p) == true);
        p = getNextPacket(captureDevice);
        REQUIRE(connFilter.processPacket(p) == true);
        p = getNextPacket(captureDevice);
        REQUIRE(connFilter.processPacket(p) == true);
        p = getNextPacket(captureDevice);
        REQUIRE(connFilter.processPacket(p) == false); // passed export limit
        p = getNextPacket(captureDevice);
        REQUIRE(connFilter.processPacket(p) == false);
        p = getNextPacket(captureDevice);
        REQUIRE(connFilter.processPacket(p) == false); // FIN
        p = getNextPacket(captureDevice);
        REQUIRE(connFilter.processPacket(p) == false); // FIN
	p = getNextPacket(captureDevice);
	REQUIRE(connFilter.processPacket(p) == false); // ACK

	pcap_close(captureDevice);

	std::cout << "All tests on ConnectionFilter passed" << std::endl;

	return PASSED;
}
int main(int argc, char *argv[]) {

	int lport = DEFAULT_LISTEN_PORT;
	std::string proto = "udp";
	std::string certificateChainFile, privateKeyFile, caFile, caPath, peername;

	msg_setlevel(MSG_DEBUG);
	
	signal(SIGINT, sigint);

	int c;

	while (1) {
		static struct option long_options[] = {
			{"help", no_argument, 0, 'h'},
			{"port", required_argument, 0, 'p'},
			{"protocol", required_argument, 0, 'o'},
			{"cert", required_argument, 0, 'c'},
			{"key", required_argument, 0, 'k'},
			{"CAfile", required_argument, 0, 'a'},
			{"CApath", required_argument, 0, 'b'},
			{"peername", required_argument, 0, 'n'},
			{0,0,0,0}
		};

		int option_index = 0;

		c = getopt_long(argc, argv, "hp:", long_options, &option_index);

		if (c==-1) break;
		switch(c) {
			case 'h':
				usage(argv[0]); return -1;
			case 'p':
				char *endptr;
				lport = strtol(optarg,&endptr,10);
				if (*endptr != '\0' || lport <= 0 || lport > (1<<16) - 1) {
					fprintf(stderr, "illegal port number\n");
					usage(argv[0]); return -1;
				}
				break;
			case 'o':
				proto = optarg;
				break;
			case 'c':
				certificateChainFile = optarg;
				break;
			case 'k':
				privateKeyFile = optarg;
				break;
			case 'a':
				caFile = optarg;
				break;
			case 'b':
				caPath = optarg;
				break;
			case 'n':
				peername = optarg;
				break;
			case '?':
				break;
			default:
				abort();
		}
	}

	if (optind != argc) {
		fprintf(stderr,"unrecognized option '%s'\n",argv[optind]);
		usage(argv[0]); return -1;
	}

	IpfixReceiver* ipfixReceiver = 0;
	if (proto == "udp") {
		msg(MSG_INFO, "Creating UDP listener on port %i", lport);
		ipfixReceiver = new IpfixReceiverUdpIpV4(lport);
	} else if (proto == "dtls_over_udp") {
#ifdef SUPPORT_DTLS
		msg(MSG_INFO, "Creating DTLS over UDP listener on port %i", lport);
		ipfixReceiver = new IpfixReceiverDtlsUdpIpV4(lport,"",certificateChainFile,privateKeyFile,caFile,caPath);
#else
		msg(MSG_FATAL, "testcollector has been compiled without dtls/openssl support");
		return -1;
#endif
	} else if (proto == "sctp") {
#ifdef SUPPORT_SCTP
		ipfixReceiver = new IpfixReceiverSctpIpV4(lport, "127.0.0.1");
#else
		msg(MSG_FATAL, "testcollector has been compiled without sctp support");
		return -1;
#endif
	} else {
		msg(MSG_FATAL, "Protocol %s is not supported as a transport protocol for IPFIX data", proto.c_str()); 
		return -1;
	}

	IpfixCollector collector(ipfixReceiver);
	ConnectionQueue<IpfixRecord*> queue(100);
	IpfixPrinter printer;

	collector.connectTo(&queue);
	queue.connectTo(&printer);

	printer.start();
	queue.start();
	collector.start();

	msg(MSG_DIALOG, "Hit Ctrl+C to quit");
	pause();
	msg(MSG_DIALOG, "Stopping threads and tidying up.\n");

	msg(MSG_DIALOG, "Stopping collector\n");
	collector.shutdown();
	queue.shutdown();
	printer.shutdown();

	return 0;
}
Example #8
0
int main(int argc, char** argv)
{
	const char* pcap_file;
	const char* capture_interface;
	const char* tmp;
	int is_live = 0;
	int snaplen = 65535;
	uint32_t packet_pool_size = 1;
	pthread_t worker_id;
	uint32_t conn_no = 0;
	uint32_t conn_max = 0;
	uint32_t flow_timeout = 0;
	int print_stats_enabled = 0;

	if (argc != 2) {
		usage(argv[0]);
		return -1;
	}

	msg_setlevel(MSG_INFO);

	// install signal handler
	if (SIG_ERR == signal(SIGINT, sig_handler)) {
		msg(MSG_ERROR, "Could not install signal handler for SIGINT.");
		return -1;
	}
	if (SIG_ERR == signal(SIGCHLD, sig_chld_handler)) {
		msg(MSG_ERROR, "Could not install signal handler for SIGCHLD");
		return -1;
	}

	struct dumpers dumps;
	dumpers_init(&dumps);

	struct config* conf = config_new(argv[1]);
	if (!conf) {
		msg(MSG_ERROR, "Invalid config. Abort!");
		return 0;
	}

	// check if we should have any output over msg
	// quite mode is necessary when we are dumping to stdout
	tmp = config_get_option(conf, MAIN_NAME, "quiet");
	if (tmp) {
		if (!strcmp(tmp, "yes")) {
			msg_setlevel(-1);
		}
	}
	
	// check if we have a config statement that changes message level
	tmp = config_get_option(conf, MAIN_NAME, "msg_level");
	if (tmp) {
		if (!strcmp(tmp, "fatal")) {
			msg_setlevel(MSG_FATAL);
		} else if (!strcmp(tmp, "error")) {
			msg_setlevel(MSG_ERROR);
		} else if (!strcmp(tmp, "debug")) {
			msg_setlevel(MSG_DEBUG);
		} else if (!strcmp(tmp, "info")) {
			msg_setlevel(MSG_INFO);
		} else if (!strcmp(tmp, "stats")) {
			msg_setlevel(MSG_STATS);
		} else {
			msg(MSG_FATAL, "Unknown msg level ...");
		}
	}
	
	// do we want to periodically output statistics on dropped/received packets?
	tmp = config_get_option(conf, "MAIN_NAME", "packet_stats");
	if (tmp) {
		if (!strcmp(tmp, "yes")) {
			print_stats_enabled = 1;
		}
	}

	msg(MSG_INFO, "%s is initializing ...", argv[2]);

	pcap_file = config_get_option(conf, MAIN_NAME, "pcapfile");
	capture_interface = config_get_option(conf, MAIN_NAME, "interface");

	if (!pcap_file && !capture_interface) {
		msg(MSG_FATAL, "main: Neither \"pcapfile\" nor \"interface\" given in config file.");
		exit(-1);
	} if (pcap_file && capture_interface) {
		msg(MSG_FATAL, "main: Got \'pcapfile\" *and* \"interface\". Please decide whether you want to work on- or offline!");
		exit(-1);
	}

	tmp = config_get_option(conf, MAIN_NAME, "max_packet_size");
	if (tmp) {
		snaplen = atoi(tmp);
	}

	tmp = config_get_option(conf, MAIN_NAME, "packet_pool");
	if (tmp) {
		packet_pool_size = atoi(tmp);
	}

	// init connection pool
	if (!config_get_option(conf, MAIN_NAME, "init_connection_pool")) {
		msg(MSG_ERROR, "main: \"init_connection_pool\" missing in section %s", MAIN_NAME);
		return -1;
	}
	conn_no = atoi(config_get_option(conf, MAIN_NAME, "init_connection_pool"));

	if (!config_get_option(conf, MAIN_NAME, "max_connection_pool")) {
		msg(MSG_ERROR, "main: \"max_connection_pool\" missing in section %s", MAIN_NAME);
		return -1;
	}
	conn_max = atoi(config_get_option(conf, MAIN_NAME, "max_connection_pool"));

	if (!config_get_option(conf, MAIN_NAME, "flow_timeout")) {
		msg(MSG_ERROR, "main: \"flow_timeout\" missing in section %s", MAIN_NAME);
		return -1;
	}
	flow_timeout = atoi(config_get_option(conf, MAIN_NAME, "flow_timeout"));

	connection_init_pool(conn_no, conn_max, flow_timeout);


	struct packet_pool* packet_pool = packet_pool_init(packet_pool_size, snaplen);
	struct thread_data worker_data;
	worker_data.pool = packet_pool;
	worker_data.dumpers = &dumps;

	pcap_t* pfile;
	if (pcap_file) { 
		pfile = open_pcap(pcap_file, 0, snaplen); 
		dumpers_create_all(&dumps, conf, pcap_datalink(pfile), snaplen);
		if (!dumps.count) {
			msg(MSG_FATAL, "Could not configure any modules.");
			return -1;
		}
		if (pthread_create(&worker_id, NULL, worker_thread, &worker_data)) {
			msg(MSG_FATAL, "Could not create worker thread: %s", strerror(errno));
			return -1;
		}
	} else {
		is_live = 1;
		pfile = open_pcap(capture_interface, 1, snaplen);
		dumpers_create_all(&dumps, conf, pcap_datalink(pfile), snaplen);
		if (!dumps.count) {
			msg(MSG_FATAL, "Could not configure any modules.");
			return -1;
		}
		// the dumper creating can take a significant amount of time.
		// We could not read any packets during this initialization phase and 
		// could therefore drop a significant amount of packets (depending on
		// the link speed). We therefore close and reopen the pcap descriptor
		// in order to reset the statistics and get more accurate packet
		// drop statistice (we had to open the pcap interface for retrieving the
		// interface link type which is important for module initialization
		pcap_close(pfile);
		if (pthread_create(&worker_id, NULL, worker_thread, &worker_data)) {
			msg(MSG_FATAL, "Could not create worker thread: %s", strerror(errno));
			return -1;
		}
		pfile = open_pcap(capture_interface, 1, snaplen);
	}
	msg(MSG_INFO, "%s is up and running. Starting to consume packets ...", argv[0]);

	struct pcap_pkthdr pcap_hdr;
	time_t last_stats = 0;
	time_t stats_interval = 10;
	uint64_t captured = 0;
	const unsigned char* data = NULL;
	while (running) {
		if (NULL != (data = pcap_next(pfile, &pcap_hdr))) {
			captured++;
			if (print_stats_enabled) {
				if (pcap_hdr.ts.tv_sec - last_stats > stats_interval && is_live) {
					last_stats = pcap_hdr.ts.tv_sec;
					print_stats(pfile, captured, packet_pool);
				}
			}
			packet_new(packet_pool, &pcap_hdr, data);
		} else {
			if (!is_live)
				running = 0;
		}
	}

	msg(MSG_INFO, "%s finished reading packets ...", argv[0]);

	// TODO: this is a hack! we might need to wake the worker thread
	// because it might be blocked at a mutex waiting for new packets
	// we have to insert a packet in order to wake the thread from the 
	// mutex. Hence, we re-include the last packet into the pool again ...
	// FIXME: The hack can result in a segmentation fault if no packet
	// has been read from the pcap_t ...
	unsigned char* useless = malloc(snaplen);
	packet_new(packet_pool, &pcap_hdr, useless);
	free(useless);
	pthread_join(worker_id, NULL);

	// ok, the second worker is stopped right now
	// we are therefore the only thread that works on the connection pool.
	// lets timeout all active connnections to update the statistics (e.g. for stats_module)
	connection_flush_all_active_conns();

	dumpers_finish(&dumps);
	connection_deinit_pool();
	packet_pool_deinit(packet_pool);
	config_free(conf);

	return 0;
}