/* NHRP daemon main functions
 * Copyright (c) 2014-2015 Timo Teräs
 *
 * This file is free software: you may copy, redistribute and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 */

#include <unistd.h>
#include <libgen.h>

#include "zebra.h"
#include "privs.h"
#include "getopt.h"
#include "thread.h"
#include "sigevent.h"
#include "version.h"
#include "log.h"
#include "memory.h"
#include "command.h"

#include "nhrpd.h"
#include "netlink.h"

unsigned int debug_flags = 0;

struct thread_master *master;
struct timeval current_time;
static const char *pid_file = PATH_NHRPD_PID;
static char config_default[] = SYSCONFDIR NHRP_DEFAULT_CONFIG;
static char *config_file = NULL;
static char *vty_addr = NULL;
static int vty_port = NHRP_VTY_PORT;
static int do_daemonise = 0;

/* nhrpd options. */
struct option longopts[] = {
	{ "daemon",      no_argument,       NULL, 'd'},
	{ "config_file", required_argument, NULL, 'f'},
	{ "pid_file",    required_argument, NULL, 'i'},
	{ "socket",      required_argument, NULL, 'z'},
	{ "help",        no_argument,       NULL, 'h'},
	{ "vty_addr",    required_argument, NULL, 'A'},
	{ "vty_port",    required_argument, NULL, 'P'},
	{ "user",        required_argument, NULL, 'u'},
	{ "group",       required_argument, NULL, 'g'},
	{ "version",     no_argument,       NULL, 'v'},
	{ 0 }
};

/* nhrpd privileges */
static zebra_capabilities_t _caps_p [] = {
	ZCAP_NET_RAW,
	ZCAP_NET_ADMIN,
	ZCAP_DAC_OVERRIDE,	/* for now needed to write to /proc/sys/net/ipv4/<if>/send_redirect */
};

static struct zebra_privs_t nhrpd_privs = {
#ifdef QUAGGA_USER
	.user = QUAGGA_USER,
#endif
#ifdef QUAGGA_GROUP
	.group = QUAGGA_GROUP,
#endif
#ifdef VTY_GROUP
	.vty_group = VTY_GROUP,
#endif
	.caps_p = _caps_p,
	.cap_num_p = ZEBRA_NUM_OF(_caps_p),
};

static void usage(const char *progname, int status)
{
	if (status != 0)
		fprintf(stderr, "Try `%s --help' for more information.\n", progname);
	else
		printf(
"Usage : %s [OPTION...]\n\
Daemon which manages NHRP protocol.\n\n\
-d, --daemon       Runs in daemon mode\n\
-f, --config_file  Set configuration file name\n\
-i, --pid_file     Set process identifier file name\n\
-z, --socket       Set path of zebra socket\n\
-A, --vty_addr     Set vty's bind address\n\
-P, --vty_port     Set vty's port number\n\
-u, --user         User to run as\n\
-g, --group        Group to run as\n\
-v, --version      Print program version\n\
-h, --help         Display this help and exit\n\
\n\
Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);

	exit(status);
}

static void parse_arguments(const char *progname, int argc, char **argv)
{
	int opt;

	while (1) {
		opt = getopt_long(argc, argv, "df:i:z:hA:P:u:g:v", longopts, 0);
		if(opt < 0) break;

		switch (opt) {
		case 0:
			break;
		case 'd':
			do_daemonise = -1;
			break;
		case 'f':
			config_file = optarg;
			break;
		case 'i':
			pid_file = optarg;
			break;
		case 'z':
			zclient_serv_path_set(optarg);
			break;
		case 'A':
			vty_addr = optarg;
			break;
		case 'P':
			vty_port = atoi (optarg);
			if (vty_port <= 0 || vty_port > 0xffff)
				vty_port = NHRP_VTY_PORT;
			break;
		case 'u':
			nhrpd_privs.user = optarg;
			break;
		case 'g':
			nhrpd_privs.group = optarg;
			break;
		case 'v':
			print_version(progname);
			exit(0);
			break;
		case 'h':
			usage(progname, 0);
			break;
		default:
			usage(progname, 1);
			break;
		}
	}
}

static void nhrp_sigusr1(void)
{
	zlog_rotate(NULL);
}

static void nhrp_request_stop(void)
{
	debugf(NHRP_DEBUG_COMMON, "Exiting...");

	nhrp_shortcut_terminate();
	nhrp_nhs_terminate();
	nhrp_zebra_terminate();
	vici_terminate();
	evmgr_terminate();
	nhrp_vc_terminate();
	vrf_terminate();
	/* memory_terminate(); */
	/* vty_terminate(); */
	cmd_terminate();
	/* signal_terminate(); */
	zprivs_terminate(&nhrpd_privs);

	debugf(NHRP_DEBUG_COMMON, "Remove pid file.");
	if (pid_file) unlink(pid_file);
	debugf(NHRP_DEBUG_COMMON, "Done.");

	closezlog(zlog_default);

	exit(0);
}

static struct quagga_signal_t sighandlers[] = {
	{ .signal = SIGUSR1, .handler = &nhrp_sigusr1, },
	{ .signal = SIGINT,  .handler = &nhrp_request_stop, },
	{ .signal = SIGTERM, .handler = &nhrp_request_stop, },
};

int main(int argc, char **argv)
{
	struct thread thread;
	const char *progname;

	/* Set umask before anything for security */
	umask(0027);
	progname = basename(argv[0]);
	zlog_default = openzlog(progname, ZLOG_NHRP, LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
	zlog_set_level(NULL, ZLOG_DEST_STDOUT, LOG_WARNING);

	parse_arguments(progname, argc, argv);

	/* Library inits. */
	master = thread_master_create();
	zprivs_init(&nhrpd_privs);
	signal_init(master, array_size(sighandlers), sighandlers);
	cmd_init(1);
	vty_init(master);
	memory_init();
	nhrp_interface_init();
	vrf_init();
	resolver_init();

	/* Run with elevated capabilities, as for all netlink activity
	 * we need privileges anyway. */
	nhrpd_privs.change(ZPRIVS_RAISE);

	netlink_init();
	evmgr_init();
	nhrp_vc_init();
	nhrp_packet_init();
	vici_init();
	nhrp_zebra_init();
	nhrp_shortcut_init();

	nhrp_config_init();

	/* Get zebra configuration file. */
	zlog_set_level(NULL, ZLOG_DEST_STDOUT, do_daemonise ? ZLOG_DISABLED : LOG_DEBUG);
	vty_read_config(config_file, config_default);

	if (do_daemonise && daemon(0, 0) < 0) {
		zlog_err("daemonise: %s", safe_strerror(errno));
		exit (1);
	}

	/* write pid file */
	if (pid_output(pid_file) < 0) {
		zlog_err("error while writing pidfile");
		exit (1);
	}

	/* Create VTY socket */
	vty_serv_sock(vty_addr, vty_port, NHRP_VTYSH_PATH);
	zlog_notice("nhrpd starting: vty@%d", vty_port);

	/* Main loop */
	while (thread_fetch(master, &thread))
		thread_call(&thread);

	return 0;
}
