
/* $Id: netward.c,v 1.25 2009/03/29 19:36:30 jayrfink Exp $ */

/* netward source file: main and usage. LICENSE: See COPYING for details */

#include "nw.h"

void usage()
{
	printf(PACKAGE " [option][arguments][filter expr]\n"
	  PACKAGE " [-d|--daemon][-I|--interface <dev>]\n"
	  "[-p|--polls <number>][-i|--interval <number>]\n"
				"[-u|--usage][-v|--verbose]\n"
	  "Options:\n"
	  " -c|--config   <file> Specify config file location\n"
	  "                      DEFAULT: %s\n"
	  " -d|--daemon          Go into daemon mode (automatically\n"
	  "                      logs and shuts off verbose)\n"
	  " -I|--interface <dev> Specify the interface to watch\n"
	  " -l|--logfile  <file> Specify logfig file location\n"
	  "                      DEFAULT: %s\n"
	  " -p|--packets   <int> Poll n packets at every check\n"
	  "                      DEFAULT: %i\n"
	  " -i|--interval  <int> Sleep n seconds between polls\n"
	  "                      DEFAULT: %i\n"
	  " -t|--threshold <int> Threshold of packets before alarm is triggered\n"
	  "                      DEFAULT: %i\n"
	  " -u|--usage           Display help\n"
	  " -v|--verbose         Be verbose (implies not daemonized)\n"
	  "Filter:\n"
	  " In pcap form ex: \"not host foo\"\n"
	  " Default: %s\n",
	CFGFILE, LOGFILE, DEFAULT_POLLS, DEFAULT_INTERVAL, DEFAULT_FILTER,
	DEFAULT_THRESHOLD
	);
}

int main(int argc, char *argv[])
{
	int c;                            /* count */
	char *filter;                     /* pcap filter */
	short int interval;               /* Interval between polls in sec. */
	short int npolls;                 /* n polls before interval quit */
	short int dflag;                  /* daemonize flag */
	char nic_cfg_param[MAXBUF];       /* NIC for  cfg file */
	char filter_cfg_param[MAXBUF];    /* Filter for  cfg file */
	char interval_cfg_param[MAXBUF];  /* Interval for  cfg file */
	char polls_cfg_param[MAXBUF];     /* Polls for  cfg file */
	char threshold_cfg_param[MAXBUF]; /* Polls for  cfg file */

	filter = NULL;         /* Initially empty */
	interval = 0;          /* See config.h */
	npolls = 0;            /* Set to -1 loop forever */
	dev = NULL;            /* default to empty (won't work otherwise */
	vflag = 0;             /* Be hush hush */
	dflag = 0;             /* Do not daemonize by default */
	configfile = CFGFILE;  /* Default config file */
	threshold = 0;         /* Default */

	/* Options data structure- see usage() below for details */
	while (1) {
		static struct option long_options[] = {
			{"config", required_argument, 0, 'c'},
			{"daemon", no_argument, 0, 'd'},
			{"interface", required_argument, 0, 'I'},
			{"logfile", required_argument, 0, 'l'},
			{"polls", required_argument, 0, 'p'},
			{"interval", required_argument, 0, 'i'},
			{"threshold", required_argument, 0, 't'},
			{"usage", no_argument, 0, 'u'},
			{"verbose", no_argument, 0, 'v'},
			{0, 0, 0, 0}
		};

		int option_index = 0;
		c = getopt_long(argc, argv, "dI:p:i:t:uv",
				long_options, &option_index);

		if (c == -1)
			break;
		switch (c) {
		case 'c':
			configfile = optarg;
			break;
		case 'd':
			++dflag;
			vflag = 0;
			break;
		case 'I':
			dev = optarg;
			break;
		case 'l':
			logfile = optarg;
			break;
		case 'p':
			if (optarg != NULL && isdigit(*optarg)) {
				npolls = atol(optarg);
				if (npolls < 0) {
					fprintf(stderr,
					  "syntax error: packets polled must be > than 0\n");
					exit(1);
				}
			} else {
				fprintf(stderr, "error: invalid polls number\n");
				exit(1);
			}
			break;
		case 'i':
			if (optarg != NULL && isdigit(*optarg)) {
				interval = atol(optarg);
				if (interval < 0) {
					fprintf(stderr,
						"syntax error: sleep interval must be > than 0\n");
					exit(1);
				}
			} else {
				fprintf(stderr, "error: invalid interval number\n");
				exit(1);
			}
			break;
		case 't':
			if (optarg != NULL && isdigit(*optarg)) {
				threshold = atol(optarg);
				if (threshold < 0) {
					fprintf(stderr,
						"syntax error: threshold must be > than 0\n");
					exit(1);
				}
			} else {
				fprintf(stderr, "error: invalid threshold number\n");
				exit(1);
			}
			break;
		case 'u':
			usage();
			exit(0);
			break;
		case 'v': 
			if (dflag) {
				fprintf(stderr, "error: cannot be verbose and daemonized.\n");
				exit (1);
			}
			++vflag;
			break;
		default:
			usage();
			exit(1);
			break;
		}
	}

	/* Make sure we are  root user */
	if (getuid()) {
		fprintf(stderr, "error: must be root user.\n");
		return 1;
	}
	/* Call utils: get_cfg_param - get config parameters or set them */
	if (!filter) {
		memset(filter_cfg_param, '\0', MAXBUF);
		if ((get_cfg_param("FILTER", filter_cfg_param, configfile)) == 0)
			filter = (char *)filter_cfg_param;
		else    /* utils: copy_argv */
			filter = copy_argv(&argv[optind]);
	}

	if (!filter) /* in config.h */
		filter = DEFAULT_FILTER;

	if (npolls == 0) {
		memset(polls_cfg_param, '\0', MAXBUF);
		if ((get_cfg_param("POLLS", polls_cfg_param, configfile)) == 0) 
			npolls = atoi(polls_cfg_param);
		else
			npolls = DEFAULT_POLLS; /* in config.h */
	}

	if (interval == 0) {
		memset(interval_cfg_param, '\0', MAXBUF);
		if ((get_cfg_param("INTERVAL", interval_cfg_param, configfile)) == 0) 
			interval = atoi(interval_cfg_param);
		else
			interval = DEFAULT_INTERVAL; /* in config.h */
	}

	if (threshold == 0) {
		memset(threshold_cfg_param, '\0', MAXBUF);
		if ((get_cfg_param("THRESHOLD", threshold_cfg_param, configfile)) == 0) 
			threshold = atoi(interval_cfg_param);
		else
			threshold = DEFAULT_THRESHOLD; /* in config.h */
	}

	if (!dev) {
		memset(nic_cfg_param, '\0', MAXBUF);
		if ((get_cfg_param("INTERFACE", nic_cfg_param, configfile)) == 0) 
			dev = (char *)nic_cfg_param;
		 else 
			printf("Interface not found - will try the first one.\n");
	}

	if (dflag)
		if (daemonize() > 0) {
			fprintf(stderr, "Could not daemonize process\n");
			exit (2);
		}

	while(1) {
		pktinit(filter, npolls);
		sleep(interval);
	}

	return 0;
}


