/*
 * ipconfig/main.c
 */
#include <errno.h>
#include <poll.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <arpa/inet.h>

#include "ipconfig.h"
#include "netdev.h"
#include "bootp_packet.h"
#include "bootp_proto.h"
#include "dhcp_proto.h"
#include "packet.h"

static const char *progname;
static char do_not_config;
static unsigned int default_caps = CAP_DHCP | CAP_BOOTP | CAP_RARP;
static int loop_timeout = -1;
static int configured;

struct state {
	int		state;
	int		restart_state;
	time_t		expire;
	int		retry_period;

	struct netdev	*dev;
	struct state	*next;
};

static inline const char *my_inet_ntoa(__u32 addr)
{
	struct in_addr a;

	a.s_addr = addr;

	return inet_ntoa(a);
}

static void print_device_config(struct netdev *dev)
{
	printf("IP-Config: %s complete (from %s):\n", dev->name,
		my_inet_ntoa(dev->serverid ? dev->serverid : dev->ip_server));
	printf(" address: %-16s ", my_inet_ntoa(dev->ip_addr));
	printf("broadcast: %-16s ", my_inet_ntoa(dev->ip_broadcast));
	printf("netmask: %-16s\n", my_inet_ntoa(dev->ip_netmask));
	printf(" gateway: %-16s ", my_inet_ntoa(dev->ip_gateway));
	printf("dns0     : %-16s ", my_inet_ntoa(dev->ip_nameserver[0]));
	printf("dns1   : %-16s\n", my_inet_ntoa(dev->ip_nameserver[1]));
	if (dev->hostname[0])
		printf(" host   : %-64s\n", dev->hostname);
	if (dev->dnsdomainname[0])
		printf(" domain : %-64s\n", dev->dnsdomainname);
	if (dev->nisdomainname[0])
		printf(" nisdomain: %-64s\n", dev->nisdomainname);
	printf(" rootserver: %s ", my_inet_ntoa(dev->ip_server));
	printf("rootpath: %s\n", dev->bootpath);
}

static void configure_device(struct netdev *dev)
{
	if (do_not_config)
		return;

	if (netdev_setmtu(dev))
		printf("IP-Config: failed to set MTU on %s to %u\n",
		       dev->name, dev->mtu);

	if (netdev_setaddress(dev))
		printf("IP-Config: failed to set addresses on %s\n", dev->name);
	if (netdev_setdefaultroute(dev))
		printf("IP-Config: failed to set default route on %s\n", dev->name);
}

static void dump_device_config(struct netdev *dev)
{
	char fn[40];
	FILE *f;

	snprintf(fn, sizeof(fn), "/tmp/net-%s.conf", dev->name);
	f = fopen(fn, "w");
	if (f) {
		fprintf(f, "DEVICE=%s\n", dev->name);
		fprintf(f, "IPV4ADDR=%s\n", my_inet_ntoa(dev->ip_addr));
		fprintf(f, "IPV4BROADCAST=%s\n", my_inet_ntoa(dev->ip_broadcast));
		fprintf(f, "IPV4NETMASK=%s\n", my_inet_ntoa(dev->ip_netmask));
		fprintf(f, "IPV4GATEWAY=%s\n", my_inet_ntoa(dev->ip_gateway));
		fprintf(f, "IPV4DNS0=%s\n", my_inet_ntoa(dev->ip_nameserver[0]));
		fprintf(f, "IPV4DNS1=%s\n", my_inet_ntoa(dev->ip_nameserver[1]));
		fprintf(f, "HOSTNAME=%s\n", dev->hostname);
		fprintf(f, "DNSDOMAIN=%s\n", dev->dnsdomainname);
		fprintf(f, "NISDOMAIN=%s\n", dev->nisdomainname);
		fprintf(f, "ROOTSERVER=%s\n", my_inet_ntoa(dev->ip_server));
		fprintf(f, "ROOTPATH=%s\n", dev->bootpath);
		fclose(f);
	}
}

static __u32 inet_class_netmask(__u32 ip)
{
	ip = ntohl(ip);
	if (IN_CLASSA(ip))
		return htonl(IN_CLASSA_NET);
	if (IN_CLASSB(ip))
		return htonl(IN_CLASSB_NET);
	if (IN_CLASSC(ip))
		return htonl(IN_CLASSC_NET);
	return INADDR_ANY;
}

static void postprocess_device(struct netdev *dev)
{
	if (dev->ip_netmask == INADDR_ANY) {
		dev->ip_netmask = inet_class_netmask(dev->ip_addr);
		printf("IP-Config: %s guessed netmask %s\n",
			dev->name, my_inet_ntoa(dev->ip_netmask));
	}
	if (dev->ip_broadcast == INADDR_ANY) {
		dev->ip_broadcast = (dev->ip_addr & dev->ip_netmask) | ~dev->ip_netmask;
		printf("IP-Config: %s guessed broadcast address %s\n",
			dev->name, my_inet_ntoa(dev->ip_broadcast));
	}
	if (dev->ip_nameserver[0] == INADDR_ANY) {
		dev->ip_nameserver[0] = dev->ip_server;
		printf("IP-Config: %s guessed nameserver address %s\n",
			dev->name, my_inet_ntoa(dev->ip_nameserver[0]));
	}
}

static void complete_device(struct netdev *dev)
{
	postprocess_device(dev);
	configure_device(dev);
	dump_device_config(dev);
	print_device_config(dev);

	++configured;

	dev->next = ifaces;
	ifaces = dev;
}

static int process_receive_event(struct state *s, time_t now)
{
	int handled = 1;

	switch (s->state) {
	case DEVST_BOOTP:
		s->restart_state = DEVST_BOOTP;
		switch (bootp_recv_reply(s->dev)) {
		case -1:
			s->state = DEVST_ERROR;
			break;
		case 1:
			s->state = DEVST_COMPLETE;
			DEBUG(("\n   bootp reply\n"));
			break;
		}
		break;

	case DEVST_DHCPDISC:
		s->restart_state = DEVST_DHCPDISC;
		switch (dhcp_recv_offer(s->dev)) {
		case -1:
			s->state = DEVST_ERROR;
			break;
		case 1: /* Offer received */
			s->state = DEVST_DHCPREQ;
			dhcp_send_request(s->dev);
			break;
		}
		break;

	case DEVST_DHCPREQ:
		s->restart_state = DEVST_DHCPDISC;
		switch (dhcp_recv_ack(s->dev)) {
		case -1: /* error */
			s->state = DEVST_ERROR;
			break;
		case 1:	/* ACK received */
			s->state = DEVST_COMPLETE;
			break;
		case 2:	/* NAK received */
			s->state = DEVST_DHCPDISC;
			break;
		}
		break;
	}

	switch (s->state) {
	case DEVST_COMPLETE:
		complete_device(s->dev);
		break;

	case DEVST_ERROR:
		/* error occurred, try again in 10 seconds */
		s->expire = now + 10;
	default:
		DEBUG(("\n"));
		handled = 0;
		break;
	}

	return handled;
}

static void process_timeout_event(struct state *s, time_t now)
{
	int ret = 0;

	/*
	 * Is the link up?  If not, try again in 1 second.
	 */
	if (!netdev_running(s->dev)) {
		s->expire = now + 1;
		s->state = s->restart_state;
		return;
	}

	/*
	 * If we had an error, restore a sane state to
	 * restart from.
	 */
	if (s->state == DEVST_ERROR)
		s->state = s->restart_state;

	/*
	 * Now send a packet depending on our state.
	 */
	switch (s->state) {
	case DEVST_BOOTP:
		ret = bootp_send_request(s->dev);
		s->restart_state = DEVST_BOOTP;
		break;

	case DEVST_DHCPDISC:
		ret = dhcp_send_discover(s->dev);
		s->restart_state = DEVST_DHCPDISC;
		break;

	case DEVST_DHCPREQ:
		ret = dhcp_send_request(s->dev);
		s->restart_state = DEVST_DHCPDISC;
		break;
	}

	if (ret == -1) {
		s->state = DEVST_ERROR;
		s->expire = now + 10;
	} else {
		s->expire = now + s->retry_period;

		s->retry_period *= 2;
		if (s->retry_period > 60)
			s->retry_period = 60;
	}
}

static struct state *slist;
struct netdev *ifaces;

static int do_pkt_recv(int pkt_fd, time_t now)
{
	int ifindex, ret;
	struct state *s;

	ret = packet_peek(&ifindex);
	if (ret < 0)
		goto bail;

	for (s = slist; s; s = s->next) {
		if (s->dev->ifindex == ifindex) {
			ret |= process_receive_event(s, now);
			break;
		}
	}

 bail:
	return ret;
}

static int loop(void)
{
#define NR_FDS	1
	struct pollfd fds[NR_FDS];
	struct state *s;
	int pkt_fd;
	int nr = 0;
	struct timeval now, prev;
	time_t start;

	pkt_fd = packet_open();
	if (pkt_fd == -1) {
		perror("packet_open");
		return -1;
	}

	fds[0].fd = pkt_fd;
	fds[0].events = POLLRDNORM;

	gettimeofday(&now, NULL);
	start = now.tv_sec;
	while (1) {
		int timeout = 60;
		int pending = 0;
		int timeout_ms;
		int x;

		for (s = slist; s; s = s->next) {
			if (s->state == DEVST_COMPLETE)
				continue;

			pending++;

			if (s->expire - now.tv_sec <= 0)
				process_timeout_event(s, now.tv_sec);

			if (timeout > s->expire - now.tv_sec)
				timeout = s->expire - now.tv_sec;
		}

		if (pending == 0)
			break;

		timeout_ms = timeout * 1000;

		for (x = 0; x < 2; x++) {
			int delta_ms;

			if (timeout_ms <= 0)
				timeout_ms = 100;

			nr = poll(fds, NR_FDS, timeout_ms);
			prev = now;
			gettimeofday(&now, NULL);

			if ((fds[0].revents & POLLRDNORM)) {
				nr = do_pkt_recv(pkt_fd, now.tv_sec);
				if (nr == 1)
					break;
				else if (nr == 0)
					packet_discard();
			}

			if (loop_timeout >= 0 &&
			    now.tv_sec - start >= loop_timeout) {
				printf("IP-Config: no response after %d "
				       "secs - giving up\n", loop_timeout);
				goto bail;
			}

			delta_ms = (now.tv_sec - prev.tv_sec) * 1000;
			delta_ms += (now.tv_usec - prev.tv_usec) / 1000;

			DEBUG(("Delta: %d ms\n", delta_ms));

			timeout_ms -= delta_ms;
		}
	}
 bail:
	packet_close();

	return 0;
}

static int add_one_dev(struct netdev *dev)
{
	struct state *state;

	state = malloc(sizeof(struct state));
	if (!state)
		return -1;

	state->dev = dev;
	state->expire = time(NULL);
	state->retry_period = 1;

	/*
	 * Select the state that we start from.
	 */
	if (dev->caps & CAP_DHCP && dev->ip_addr == INADDR_ANY) {
		state->restart_state = state->state = DEVST_DHCPDISC;
	} else if (dev->caps & CAP_DHCP) {
		state->restart_state = state->state = DEVST_DHCPREQ;
	} else if (dev->caps & CAP_BOOTP) {
		state->restart_state = state->state = DEVST_BOOTP;
	}

	state->next = slist;
	slist = state;

	return 0;
}

static void parse_addr(__u32 *addr, const char *ip)
{
	struct in_addr in;
	if (inet_aton(ip, &in) == 0) {
		fprintf(stderr, "%s: can't parse IP address '%s'\n",
			progname, ip);
		exit(1);
	}
	*addr = in.s_addr;
}

static unsigned int parse_proto(const char *ip)
{
	unsigned int caps = 0;

	if (*ip == '\0' || strcmp(ip, "on") == 0 || strcmp(ip, "any") == 0 || strcmp(ip, "both") == 0)
		caps = CAP_BOOTP | CAP_DHCP | CAP_RARP;
	else if (strcmp(ip, "dhcp") == 0)
		caps = CAP_BOOTP | CAP_DHCP;
	else if (strcmp(ip, "bootp") == 0)
		caps = CAP_BOOTP;
	else if (strcmp(ip, "rarp") == 0)
		caps = CAP_RARP;
	else if (strcmp(ip, "none") == 0 || strcmp(ip, "static") == 0 || strcmp(ip, "off") == 0)
		goto bail;
	else {
		fprintf(stderr, "%s: invalid protocol '%s'\n",
			progname, ip);
		exit(1);
	}
 bail:
	return caps;
}

static void bringup_device(struct netdev *dev)
{
	if (netdev_up(dev) == 0) {
		if (dev->caps) {
			add_one_dev(dev);
		} else {
			complete_device(dev);
		}
	}
}

static struct netdev *add_device(const char *info);

static void add_all_devices(struct netdev *template)
{
#define MAX_IFS 128
	struct ifreq ifr[MAX_IFS];
	struct ifconf ifc;
	int fd, nif, i;

	fd = packet_open();

	ifc.ifc_len = sizeof(ifr);
	ifc.ifc_req = ifr;

	if (ioctl(fd, SIOCGIFCONF, &ifc) == -1) {
		perror("SIOCGIFCONF");
		exit(1);
	}
	nif = ifc.ifc_len / sizeof(ifr[0]);

	for (i = 0; i < nif; i++) {
		struct netdev *dev;

		if (strcmp(ifr[i].ifr_name, "lo") == 0)
			continue;
		if ((dev = add_device(ifr[i].ifr_name)) == NULL)
			continue;

		if (template->ip_addr != INADDR_NONE)
			dev->ip_addr = template->ip_addr;
		if (template->ip_server != INADDR_NONE)
			dev->ip_server = template->ip_server;
		if (template->ip_gateway != INADDR_NONE)
			dev->ip_gateway = template->ip_gateway;
		if (template->ip_nameserver[0] != INADDR_NONE)
			dev->ip_nameserver[0] = template->ip_nameserver[0];
		if (template->ip_nameserver[1] != INADDR_NONE)
			dev->ip_nameserver[1] = template->ip_nameserver[1];
		if (template->hostname[0] != '\0')
			strcpy(dev->hostname, template->hostname);
		dev->caps &= template->caps;

		bringup_device(dev);
	}
}

static int parse_device(struct netdev *dev, const char *ip)
{
	char *cp;
	int i, opt;

	if (strncmp(ip, "ip=", 3) == 0) {
		ip += 3;
	}
	else if (strncmp(ip, "nfsaddrs=", 9) == 0) {
		ip += 9;
	}

	if (strchr(ip, ':') == NULL) {
		dev->name = ip;
		goto done;
	}

	for (i = opt = 0; ip && *ip; ip = cp, opt++) {
		if ((cp = strchr(ip, ':'))) {
			*cp++ = '\0';
		}
		if (opt > 6) {
			fprintf(stderr, "%s: too many options for %s\n",
				progname, dev->name);
			exit(1);
		}

		if (*ip == '\0')
			continue;
		DEBUG(("IP-Config: opt #%d: '%s'\n", opt, ip));
		switch (opt) {
		case 0:
			parse_addr(&dev->ip_addr, ip);
			break;
		case 1:
			parse_addr(&dev->ip_server, ip);
			break;
		case 2:
			parse_addr(&dev->ip_gateway, ip);
			break;
		case 3:
			parse_addr(&dev->ip_netmask, ip);
			break;
		case 4:
			strncpy(dev->hostname, ip, SYS_NMLN - 1);
			dev->hostname[SYS_NMLN - 1] = '\0';
			break;
		case 5:
			dev->name = ip;
			break;
		case 6:
			dev->caps = parse_proto(ip);
			break;
		}
	}
 done:
	if (dev->name == NULL ||
	    dev->name[0] == '\0' ||
	    strcmp(dev->name, "all") == 0) {
		add_all_devices(dev);
		return 0;
	}
	return 1;
}

static struct netdev *add_device(const char *info)
{
	struct netdev *dev;
	int i;

	dev = malloc(sizeof(struct netdev));
	if (dev == NULL) {
		fprintf(stderr, "%s: out of memory\n", progname);
		exit(1);
	}

	memset(dev, 0, sizeof(struct netdev));
	dev->caps = default_caps;

	if (parse_device(dev, info) == 0)
		goto bail;

	if (netdev_init_if(dev) == -1)
		goto bail;

	if (bootp_init_if(dev) == -1)
		goto bail;

	printf("IP-Config: %s hardware address", dev->name);
	for (i = 0; i < dev->hwlen; i++)
		printf("%c%02x", i == 0 ? ' ' : ':', dev->hwaddr[i]);
	printf(" mtu %d%s%s\n", dev->mtu,
		dev->caps & CAP_DHCP  ? " DHCP"  :
		dev->caps & CAP_BOOTP ? " BOOTP" : "",
	       dev->caps & CAP_RARP  ? " RARP"  : "");
	return dev;
 bail:
	free(dev);
	return NULL;
}

static int check_autoconfig(void)
{
	int ndev = 0, nauto = 0;
	struct state *s;

	for (s = slist; s; s = s->next) {
		ndev++;
		if (s->dev->caps)
			nauto++;
	}

	if (ndev == 0) {
		if (configured == 0) {
			fprintf(stderr, "%s: no devices to configure\n",
				progname);
			exit(1);
		}
	}

	return nauto;
}

int main(int argc, char *argv[])
	__attribute__ ((weak, alias ("ipconfig_main")));

int ipconfig_main(int argc, char *argv[])
{
	struct netdev *dev;
	struct timeval now;
	int c, port;

	progname = argv[0];

	gettimeofday(&now, NULL);
	srand48(now.tv_usec ^ (now.tv_sec << 24));

	do {
		c = getopt(argc, argv, "c:d:np:t:");
		if (c == EOF)
			break;

		switch (c) {
		case 'c':
			default_caps = parse_proto(optarg);
			break;
		case 'p':
			port = atoi(optarg);
			if (port <= 0 || port > USHRT_MAX) {
				fprintf(stderr,
					"%s: invalid port number %d\n",
					progname, port);
				exit(1);
			}
			cfg_local_port = port;
			cfg_remote_port = cfg_local_port - 1;
			break;
		case 't':
			loop_timeout = atoi(optarg);
			if (loop_timeout < 0) {
				fprintf(stderr,
					"%s: invalid timeout %d\n",
					progname, loop_timeout);
				exit(1);
			}
			break;
		case 'n':
			do_not_config = 1;
			break;
		case 'd':
			dev = add_device(optarg);
			if (dev)
				bringup_device(dev);
			break;
		case '?':
			fprintf(stderr, "%s: invalid option -%c\n",
				progname, optopt);
			exit(1);
		}
	} while (1);

	for (c = optind; c < argc; c++) {
		dev = add_device(argv[c]);
		if (dev)
			bringup_device(dev);
	}

	if (check_autoconfig()) {
		if (cfg_local_port != LOCAL_PORT) {
			printf("IP-Config: binding source port to %d, "
			       "dest to %d\n",
			       cfg_local_port,
			       cfg_remote_port);
		}
		loop();
	}

	return 0;
}
