/* 
 * dhcpcd - DHCP client daemon
 * Copyright 2006-2008 Roy Marples <roy@marples.name>
 * All rights reserved

 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <sys/stat.h>
#include <sys/wait.h>

#include <netinet/in.h>
#include <arpa/inet.h>

#include <ctype.h>
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>

#include "config.h"
#include "common.h"
#include "configure.h"
#include "dhcp.h"
#include "dhcpcd.h"
#include "logger.h"
#include "net.h"
#include "signals.h"

#define DEFAULT_PATH	"PATH=/usr/bin:/usr/sbin:/bin:/sbin"


static int
exec_script(char *const *argv, char *const *env)
{
	pid_t pid;
	sigset_t full;
	sigset_t old;

	/* OK, we need to block signals */
	sigfillset(&full);
	sigprocmask(SIG_SETMASK, &full, &old);
	signal_reset();

	switch (pid = vfork()) {
	case -1:
		logger(LOG_ERR, "vfork: %s", strerror(errno));
		break;
	case 0:
		sigprocmask(SIG_SETMASK, &old, NULL);
		execve(argv[0], argv, env);
		logger(LOG_ERR, "%s: %s", argv[0], strerror(errno));
		_exit(127);
		/* NOTREACHED */
	}

	/* Restore our signals */
	signal_setup();
	sigprocmask(SIG_SETMASK, &old, NULL);
	return pid;
}

int
run_script(const struct options *options, const char *iface,
           const char *reason,
           const struct dhcp_message *dhcpn, const struct dhcp_message *dhcpo)
{
	char *const argv[2] = { UNCONST(options->script), NULL };
	char **env = NULL, **ep;
	char *path;
	ssize_t e, elen;
	pid_t pid;
	int status = 0;

	logger(LOG_DEBUG, "executing `%s', reason %s", options->script, reason);

	/* Make our env */
	elen = 5;
	env = xmalloc(sizeof(char *) * (elen + 1));
	path = getenv("PATH");
	if (path) {
		e = strlen("PATH") + strlen(path) + 2;
		env[0] = xmalloc(e);
		snprintf(env[0], e, "PATH=%s", path);
	} else
		env[0] = xstrdup(DEFAULT_PATH);
	e = strlen("interface") + strlen(iface) + 2;
	env[1] = xmalloc(e);
	snprintf(env[1], e, "interface=%s", iface);
	e = strlen("reason") + strlen(reason) + 2;
	env[2] = xmalloc(e);
	snprintf(env[2], e, "reason=%s", reason);
	e = 20;
	env[3] = xmalloc(e);
	snprintf(env[3], e, "pid=%d", getpid());
	env[4] = xmalloc(e);
	snprintf(env[4], e, "metric=%d", options->metric);
	if (dhcpo) {
		e = configure_env(NULL, NULL, dhcpo, options);
		if (e > 0) {
			env = xrealloc(env, sizeof(char *) * (elen + e + 1));
			elen += configure_env(env + elen, "old", dhcpo, options);
		}
	}
	if (dhcpn) {
		e = configure_env(NULL, NULL, dhcpn, options);
		if (e > 0) {
			env = xrealloc(env, sizeof(char *) * (elen + e + 1));
			elen += configure_env(env + elen, "new", dhcpn, options);
		}
	}
	/* Add our base environment */
	if (options->environ) {
		e = 0;
		while (options->environ[e++])
			;
		env = xrealloc(env, sizeof(char *) * (elen + e + 1));
		e = 0;
		while (options->environ[e]) {
			env[elen + e] = xstrdup(options->environ[e]);
			e++;
		}
		elen += e;
	}
	env[elen] = '\0';

	pid = exec_script(argv, env);
	if (pid == -1)
		status = -1;
	else if (pid != 0) {
		/* Wait for the script to finish */
		while (waitpid(pid, &status, 0) == -1) {
			if (errno != EINTR) {
				logger(LOG_ERR, "waitpid: %s", strerror(errno));
				status = -1;
				break;
			}
		}
	}

	/* Cleanup */
	ep = env;
	while (*ep)
		free(*ep++);
	free(env);
	return status;
}

static struct rt *
reverse_routes(struct rt *routes)
{
	struct rt *rt;
	struct rt *rtn = NULL;
	
	while (routes) {
		rt = routes->next;
		routes->next = rtn;
		rtn = routes;
		routes = rt;
	}
	return rtn;
}

static int
delete_route(const char *iface, struct rt *rt, int metric)
{
	char *addr;
	int retval;

	addr = xstrdup(inet_ntoa(rt->dest));
	logger(LOG_DEBUG, "deleting route %s/%d via %s",
	       addr, inet_ntocidr(rt->net), inet_ntoa(rt->gate));
	free(addr);
	retval = del_route(iface, &rt->dest, &rt->net, &rt->gate, metric);
	if (retval != 0 && errno != ENOENT && errno != ESRCH)
		logger(LOG_ERR," del_route: %s", strerror(errno));
	return retval;
}

static int
delete_routes(struct interface *iface, int metric)
{
	struct rt *rt;
	struct rt *rtn;
	int retval = 0;

	rt = reverse_routes(iface->routes);
	while (rt) {
		rtn = rt->next;
		retval += delete_route(iface->name, rt, metric);
		free(rt);
		rt = rtn;
	}
	iface->routes = NULL;

	return retval;
}

static int
in_routes(const struct rt *routes, const struct rt *rt)
{
	while (routes) {
		if (routes->dest.s_addr == rt->dest.s_addr &&
				routes->net.s_addr == rt->net.s_addr &&
				routes->gate.s_addr == rt->gate.s_addr)
			return 0;
		routes = routes->next;
	}
	return -1;
}

static int
configure_routes(struct interface *iface, const struct dhcp_message *dhcp,
		 const struct options *options)
{
	struct rt *rt, *ort;
	struct rt *rtn = NULL, *nr = NULL;
	int remember;
	int retval = 0;
	char *addr;

	ort = get_option_routes(dhcp);

#ifdef IPV4LL_ALWAYSROUTE
	if (options->options & DHCPCD_IPV4LL &&
	    IN_PRIVATE(ntohl(dhcp->yiaddr)))
	{
		for (rt = ort; rt; rt = rt->next) {
			/* Check if we have already got a link locale route
			 * dished out by the DHCP server */
			if (rt->dest.s_addr == htonl(LINKLOCAL_ADDR) &&
			    rt->net.s_addr == htonl(LINKLOCAL_MASK))
				break;
			rtn = rt;
		}

		if (!rt) {
			rt = xmalloc(sizeof(*rt));
			rt->dest.s_addr = htonl(LINKLOCAL_ADDR);
			rt->net.s_addr = htonl(LINKLOCAL_MASK);
			rt->gate.s_addr = 0;
			rt->next = NULL;
			if (rtn)
				rtn->next = rt;
			else
				ort = rt;
		}
	}
#endif

	/* Now remove old routes we no longer use.
 	 * We should do this in reverse order. */
	iface->routes = reverse_routes(iface->routes);
	for (rt = iface->routes; rt; rt = rt->next)
		if (in_routes(ort, rt) != 0)
			delete_route(iface->name, rt, options->metric);

	for (rt = ort; rt; rt = rt->next) {
		/* Don't set default routes if not asked to */
		if (rt->dest.s_addr == 0 &&
		    rt->net.s_addr == 0 &&
		    !(options->options & DHCPCD_GATEWAY))
			continue;

		addr = xstrdup(inet_ntoa(rt->dest));
		logger(LOG_DEBUG, "adding route to %s/%d via %s",
			addr, inet_ntocidr(rt->net), inet_ntoa(rt->gate));
		free(addr);
		remember = add_route(iface->name, &rt->dest,
				     &rt->net, &rt->gate,
				     options->metric);
		retval += remember;

		/* If we failed to add the route, we may have already added it
		   ourselves. If so, remember it again. */
		if (remember < 0) {
			if (errno != EEXIST)
				logger(LOG_ERR, "add_route: %s",
				       strerror(errno));
			if (in_routes(iface->routes, rt) == 0)
				remember = 1;
		}

		/* This login is split from above due to the #ifdef below */
		if (remember >= 0) {
			if (nr) {
				rtn->next = xmalloc(sizeof(*rtn));
				rtn = rtn->next;
			} else {
				nr = rtn = xmalloc(sizeof(*rtn));
			}
			rtn->dest.s_addr = rt->dest.s_addr;
			rtn->net.s_addr = rt->net.s_addr;
			rtn->gate.s_addr = rt->gate.s_addr;
			rtn->next = NULL;
		}
	}
	free_routes(ort);
	free_routes(iface->routes);
	iface->routes = nr;
	return retval;
}

static int
delete_address(struct interface *iface)
{
	int retval;
	logger(LOG_DEBUG, "deleting IP address %s/%d",
	       inet_ntoa(iface->addr),
	       inet_ntocidr(iface->net));
	retval = del_address(iface->name, &iface->addr, &iface->net);
	if (retval == -1 && errno != EADDRNOTAVAIL) 
		logger(LOG_ERR, "del_address: %s", strerror(errno));
	iface->addr.s_addr = 0;
	iface->net.s_addr = 0;
	return retval;
}

int
configure(struct interface *iface, const char *reason,
	  const struct dhcp_message *dhcp, const struct dhcp_message *old,
	  const struct dhcp_lease *lease, const struct options *options,
	  int up)
{
	struct in_addr addr;
	struct in_addr net;
	struct in_addr brd;
#ifdef __linux__
	struct in_addr dest;
	struct in_addr gate;
#endif

	/* Grab our IP config */
	if (dhcp == NULL)
		up = 0;
	else {
		addr.s_addr = dhcp->yiaddr;
		if (addr.s_addr == 0)
			addr.s_addr = lease->addr.s_addr;
		/* Ensure we have all the needed values */
		if (get_option_addr(&net.s_addr, dhcp, DHO_SUBNETMASK) == -1)
			net.s_addr = get_netmask(addr.s_addr);
		if (get_option_addr(&brd.s_addr, dhcp, DHO_BROADCAST) == -1)
			brd.s_addr = addr.s_addr | ~net.s_addr;
	}

	/* If we aren't up, then reset the interface as much as we can */
	if (!up) {
		/* Only reset things if we had set them before */
		if (iface->addr.s_addr != 0) {
			delete_routes(iface, options->metric);
			delete_address(iface);
		}

		run_script(options, iface->name, reason, NULL, old);
		return 0;
	}

	/* This also changes netmask */
	if (!(options->options & DHCPCD_INFORM) ||
	    !has_address(iface->name, &addr, &net)) {
		logger(LOG_DEBUG, "adding IP address %s/%d",
		       inet_ntoa(addr), inet_ntocidr(net));
		if (add_address(iface->name, &addr, &net, &brd) == -1 &&
		    errno != EEXIST)
		{
			logger(LOG_ERR, "add_address: %s", strerror(errno));
			return -1;
		}
	}

	/* Now delete the old address if different */
	if (iface->addr.s_addr != addr.s_addr &&
	    iface->addr.s_addr != 0)
		delete_address(iface);

#ifdef __linux__
	/* On linux, we need to change the subnet route to have our metric. */
	if (iface->addr.s_addr != lease->addr.s_addr &&
	    options->metric > 0 && net.s_addr != INADDR_BROADCAST)
	{
		dest.s_addr = addr.s_addr & net.s_addr;
		gate.s_addr = 0;
		add_route(iface->name, &dest, &net, &gate, options->metric);
		del_route(iface->name, &dest, &net, &gate, 0);
	}
#endif

	configure_routes(iface, dhcp, options);
	up = (iface->addr.s_addr != addr.s_addr ||
	      iface->net.s_addr != net.s_addr);
	iface->addr.s_addr = addr.s_addr;
	iface->net.s_addr = net.s_addr;

	if (!lease->frominfo)
		if (write_lease(iface, dhcp) == -1)
			logger(LOG_ERR, "write_lease: %s", strerror(errno));

	run_script(options, iface->name, reason, dhcp, old);
	return 0;
}
