/* vi: set sw=4 ts=4: */
/*
 * RFC3927 ZeroConf IPv4 Link-Local addressing
 * (see <http://www.zeroconf.org/>)
 *
 * Copyright (C) 2003 by Arthur van Hoff (avh@strangeberry.com)
 * Copyright (C) 2004 by David Brownell
 *
 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
 */

/*
 * ZCIP just manages the 169.254.*.* addresses.  That network is not
 * routed at the IP level, though various proxies or bridges can
 * certainly be used.  Its naming is built over multicast DNS.
 */

//#define DEBUG

// TODO:
// - more real-world usage/testing, especially daemon mode
// - kernel packet filters to reduce scheduling noise
// - avoid silent script failures, especially under load...
// - link status monitoring (restart on link-up; stop on link-down)

#include "busybox.h"
#include <errno.h>
#include <string.h>
#include <syslog.h>
#include <poll.h>
#include <time.h>

#include <sys/wait.h>

#include <netinet/ether.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_arp.h>

#include <linux/if_packet.h>
#include <linux/sockios.h>


struct arp_packet {
	struct ether_header hdr;
	struct ether_arp arp;
} ATTRIBUTE_PACKED;

enum {
/* 169.254.0.0 */
	LINKLOCAL_ADDR = 0xa9fe0000,

/* protocol timeout parameters, specified in seconds */
	PROBE_WAIT = 1,
	PROBE_MIN = 1,
	PROBE_MAX = 2,
	PROBE_NUM = 3,
	MAX_CONFLICTS = 10,
	RATE_LIMIT_INTERVAL = 60,
	ANNOUNCE_WAIT = 2,
	ANNOUNCE_NUM = 2,
	ANNOUNCE_INTERVAL = 2,
	DEFEND_INTERVAL = 10
};

/* States during the configuration process. */
enum {
	PROBE = 0,
	RATE_LIMIT_PROBE,
	ANNOUNCE,
	MONITOR,
	DEFEND
};

#define VDBG(fmt,args...) \
	do { } while (0)

static unsigned long opts;
#define FOREGROUND (opts & 1)
#define QUIT (opts & 2)

/**
 * Pick a random link local IP address on 169.254/16, except that
 * the first and last 256 addresses are reserved.
 */
static void pick(struct in_addr *ip)
{
	unsigned tmp;

	/* use cheaper math than lrand48() mod N */
	do {
		tmp = (lrand48() >> 16) & IN_CLASSB_HOST;
	} while (tmp > (IN_CLASSB_HOST - 0x0200));
	ip->s_addr = htonl((LINKLOCAL_ADDR + 0x0100) + tmp);
}

/* TODO: we need a flag to direct bb_[p]error_msg output to stderr. */

/**
 * Broadcast an ARP packet.
 */
static void arp(int fd, struct sockaddr *saddr, int op,
	const struct ether_addr *source_addr, struct in_addr source_ip,
	const struct ether_addr *target_addr, struct in_addr target_ip)
{
	struct arp_packet p;
	memset(&p, 0, sizeof(p));

	// ether header
	p.hdr.ether_type = htons(ETHERTYPE_ARP);
	memcpy(p.hdr.ether_shost, source_addr, ETH_ALEN);
	memset(p.hdr.ether_dhost, 0xff, ETH_ALEN);

	// arp request
	p.arp.arp_hrd = htons(ARPHRD_ETHER);
	p.arp.arp_pro = htons(ETHERTYPE_IP);
	p.arp.arp_hln = ETH_ALEN;
	p.arp.arp_pln = 4;
	p.arp.arp_op = htons(op);
	memcpy(&p.arp.arp_sha, source_addr, ETH_ALEN);
	memcpy(&p.arp.arp_spa, &source_ip, sizeof (p.arp.arp_spa));
	memcpy(&p.arp.arp_tha, target_addr, ETH_ALEN);
	memcpy(&p.arp.arp_tpa, &target_ip, sizeof (p.arp.arp_tpa));

	// send it
	if (sendto(fd, &p, sizeof (p), 0, saddr, sizeof (*saddr)) < 0) {
		bb_perror_msg("sendto");
		//return -errno;
	}
	// Currently all callers ignore errors, that's why returns are
	// commented out...
	//return 0;
}

/**
 * Run a script.
 */
static int run(char *script, char *arg, char *intf, struct in_addr *ip)
{
	int pid, status;
	char *why;

	if(1) { //always true: if (script != NULL)
		VDBG("%s run %s %s\n", intf, script, arg);
		if (ip != NULL) {
			char *addr = inet_ntoa(*ip);
			setenv("ip", addr, 1);
			bb_info_msg("%s %s %s", arg, intf, addr);
		}

		pid = vfork();
		if (pid < 0) {			// error
			why = "vfork";
			goto bad;
		} else if (pid == 0) {		// child
			execl(script, script, arg, NULL);
			bb_perror_msg("execl");
			_exit(EXIT_FAILURE);
		}

		if (waitpid(pid, &status, 0) <= 0) {
			why = "waitpid";
			goto bad;
		}
		if (WEXITSTATUS(status) != 0) {
			bb_error_msg("script %s failed, exit=%d",
				script, WEXITSTATUS(status));
			return -errno;
		}
	}
	return 0;
bad:
	status = -errno;
	bb_perror_msg("%s %s, %s", arg, intf, why);
	return status;
}


/**
 * Return milliseconds of random delay, up to "secs" seconds.
 */
static unsigned ATTRIBUTE_ALWAYS_INLINE ms_rdelay(unsigned secs)
{
	return lrand48() % (secs * 1000);
}

/**
 * main program
 */

/* Used to be auto variables on main() stack, but
 * most of them were zero-inited. Moving them to bss
 * is more space-efficient.
 */
static	const struct in_addr null_ip; // = { 0 };
static	const struct ether_addr null_addr; // = { {0, 0, 0, 0, 0, 0} };

static	struct sockaddr saddr; // memset(0);
static	struct in_addr ip; // = { 0 };
static	struct ifreq ifr; //memset(0);

static	char *intf; // = NULL;
static	char *script; // = NULL;
static	suseconds_t timeout; // = 0;	// milliseconds
static	unsigned conflicts; // = 0;
static	unsigned nprobes; // = 0;
static	unsigned nclaims; // = 0;
static	int ready; // = 0;
static	int verbose; // = 0;
static	int state = PROBE;

int zcip_main(int argc, char *argv[])
{
	struct ether_addr eth_addr;
	char *why;
	int fd;

	// parse commandline: prog [options] ifname script
	char *r_opt;
	bb_opt_complementally = "vv:vf"; // -v accumulates and implies -f
	opts = bb_getopt_ulflags(argc, argv, "fqr:v", &r_opt, &verbose);
	if (!FOREGROUND) {
		/* Do it early, before all bb_xx_msg calls */
		logmode = LOGMODE_SYSLOG;
		openlog(bb_applet_name, 0, LOG_DAEMON);
	}
	if (opts & 4) { // -r n.n.n.n
		if (inet_aton(r_opt, &ip) == 0
		|| (ntohl(ip.s_addr) & IN_CLASSB_NET) != LINKLOCAL_ADDR) {
			bb_error_msg_and_die("invalid link address");
		}
	}
	argc -= optind;
	argv += optind;
	if (argc != 2)
		bb_show_usage();
	intf = argv[0];
	script = argv[1];
	setenv("interface", intf, 1);

	// initialize the interface (modprobe, ifup, etc)
	if (run(script, "init", intf, NULL) < 0)
		return EXIT_FAILURE;

	// initialize saddr
	//memset(&saddr, 0, sizeof (saddr));
	safe_strncpy(saddr.sa_data, intf, sizeof (saddr.sa_data));

	// open an ARP socket
	fd = xsocket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP));
	// bind to the interface's ARP socket
	xbind(fd, &saddr, sizeof (saddr));

	// get the interface's ethernet address
	//memset(&ifr, 0, sizeof (ifr));
	strncpy(ifr.ifr_name, intf, sizeof (ifr.ifr_name));
	if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {
		bb_perror_msg_and_die("get ethernet address");
	}
	memcpy(&eth_addr, &ifr.ifr_hwaddr.sa_data, ETH_ALEN);

	// start with some stable ip address, either a function of
	// the hardware address or else the last address we used.
	// NOTE: the sequence of addresses we try changes only
	// depending on when we detect conflicts.
	// (SVID 3 bogon: who says that "short" is always 16 bits?)
	seed48( (unsigned short*)&ifr.ifr_hwaddr.sa_data );
	if (ip.s_addr == 0)
		pick(&ip);

	// FIXME cases to handle:
	//  - zcip already running!
	//  - link already has local address... just defend/update

	// daemonize now; don't delay system startup
	if (!FOREGROUND) {
		setsid();
		xdaemon(0, 0);
		bb_info_msg("start, interface %s", intf);
	}

	// run the dynamic address negotiation protocol,
	// restarting after address conflicts:
	//  - start with some address we want to try
	//  - short random delay
	//  - arp probes to see if another host else uses it
	//  - arp announcements that we're claiming it
	//  - use it
	//  - defend it, within limits
	while (1) {
		struct pollfd fds[1];
		struct timeval tv1;
		struct arp_packet p;

		int source_ip_conflict = 0;
		int target_ip_conflict = 0;

		fds[0].fd = fd;
		fds[0].events = POLLIN;
		fds[0].revents = 0;

		// poll, being ready to adjust current timeout
		if (!timeout) {
			timeout = ms_rdelay(PROBE_WAIT);
			// FIXME setsockopt(fd, SO_ATTACH_FILTER, ...) to
			// make the kernel filter out all packets except
			// ones we'd care about.
		}
		// set tv1 to the point in time when we timeout
		gettimeofday(&tv1, NULL);
		tv1.tv_usec += (timeout % 1000) * 1000;
		while (tv1.tv_usec > 1000000) {
			tv1.tv_usec -= 1000000;
			tv1.tv_sec++;
		}
		tv1.tv_sec += timeout / 1000;
	
		VDBG("...wait %ld %s nprobes=%d, nclaims=%d\n",
				timeout, intf, nprobes, nclaims);
		switch (poll(fds, 1, timeout)) {

		// timeout
		case 0:
			VDBG("state = %d\n", state);
			switch (state) {
			case PROBE:
				// timeouts in the PROBE state mean no conflicting ARP packets
				// have been received, so we can progress through the states
				if (nprobes < PROBE_NUM) {
					nprobes++;
					VDBG("probe/%d %s@%s\n",
							nprobes, intf, inet_ntoa(ip));
					arp(fd, &saddr, ARPOP_REQUEST,
							&eth_addr, null_ip,
							&null_addr, ip);
					timeout = PROBE_MIN * 1000;
					timeout += ms_rdelay(PROBE_MAX
							- PROBE_MIN);
				}
				else {
					// Switch to announce state.
					state = ANNOUNCE;
					nclaims = 0;
					VDBG("announce/%d %s@%s\n",
							nclaims, intf, inet_ntoa(ip));
					arp(fd, &saddr, ARPOP_REQUEST,
							&eth_addr, ip,
							&eth_addr, ip);
					timeout = ANNOUNCE_INTERVAL * 1000;
				}
				break;
			case RATE_LIMIT_PROBE:
				// timeouts in the RATE_LIMIT_PROBE state mean no conflicting ARP packets
				// have been received, so we can move immediately to the announce state
				state = ANNOUNCE;
				nclaims = 0;
				VDBG("announce/%d %s@%s\n",
						nclaims, intf, inet_ntoa(ip));
				arp(fd, &saddr, ARPOP_REQUEST,
						&eth_addr, ip,
						&eth_addr, ip);
				timeout = ANNOUNCE_INTERVAL * 1000;
				break;
			case ANNOUNCE:
				// timeouts in the ANNOUNCE state mean no conflicting ARP packets
				// have been received, so we can progress through the states
				if (nclaims < ANNOUNCE_NUM) {
					nclaims++;
					VDBG("announce/%d %s@%s\n",
							nclaims, intf, inet_ntoa(ip));
					arp(fd, &saddr, ARPOP_REQUEST,
							&eth_addr, ip,
							&eth_addr, ip);
					timeout = ANNOUNCE_INTERVAL * 1000;
				}
				else {
					// Switch to monitor state.
					state = MONITOR;
					// link is ok to use earlier
					// FIXME update filters
					run(script, "config", intf, &ip);
					ready = 1;
					conflicts = 0;
					timeout = -1; // Never timeout in the monitor state.

					// NOTE: all other exit paths
					// should deconfig ...
					if (QUIT)
						return EXIT_SUCCESS;
				}
				break;
			case DEFEND:
				// We won!  No ARP replies, so just go back to monitor.
				state = MONITOR;
				timeout = -1;
				conflicts = 0;
				break;
			default:
				// Invalid, should never happen.  Restart the whole protocol.
				state = PROBE;
				pick(&ip);
				timeout = 0;
				nprobes = 0;
				nclaims = 0;
				break;
			} // switch (state)
			break; // case 0 (timeout)
		// packets arriving
		case 1:
			// We need to adjust the timeout in case we didn't receive
			// a conflicting packet.
			if (timeout > 0) {
				struct timeval tv2;

				gettimeofday(&tv2, NULL);
				if (timercmp(&tv1, &tv2, <)) {
					// Current time is greater than the expected timeout time.
					// Should never happen.
					VDBG("missed an expected timeout\n");
					timeout = 0;
				} else {
					VDBG("adjusting timeout\n");
					timersub(&tv1, &tv2, &tv1);
					timeout = 1000 * tv1.tv_sec
							+ tv1.tv_usec / 1000;
				}
			}

			if ((fds[0].revents & POLLIN) == 0) {
				if (fds[0].revents & POLLERR) {
					// FIXME: links routinely go down;
					// this shouldn't necessarily exit.
					bb_error_msg("%s: poll error", intf);
					if (ready) {
						run(script, "deconfig",
								intf, &ip);
					}
					return EXIT_FAILURE;
				}
				continue;
			}

			// read ARP packet
			if (recv(fd, &p, sizeof (p), 0) < 0) {
				why = "recv";
				goto bad;
			}
			if (p.hdr.ether_type != htons(ETHERTYPE_ARP))
				continue;

#ifdef DEBUG
			{
				struct ether_addr * sha = (struct ether_addr *) p.arp.arp_sha;
				struct ether_addr * tha = (struct ether_addr *) p.arp.arp_tha;
				struct in_addr * spa = (struct in_addr *) p.arp.arp_spa;
				struct in_addr * tpa = (struct in_addr *) p.arp.arp_tpa;
				VDBG("%s recv arp type=%d, op=%d,\n",
					intf, ntohs(p.hdr.ether_type),
					ntohs(p.arp.arp_op));
				VDBG("\tsource=%s %s\n",
					ether_ntoa(sha),
					inet_ntoa(*spa));
				VDBG("\ttarget=%s %s\n",
					ether_ntoa(tha),
					inet_ntoa(*tpa));
			}
#endif
			if (p.arp.arp_op != htons(ARPOP_REQUEST)
					&& p.arp.arp_op != htons(ARPOP_REPLY))
				continue;

			if (memcmp(p.arp.arp_spa, &ip.s_addr, sizeof(struct in_addr)) == 0 &&
				memcmp(&eth_addr, &p.arp.arp_sha, ETH_ALEN) != 0) {
				source_ip_conflict = 1;
			}
			if (memcmp(p.arp.arp_tpa, &ip.s_addr, sizeof(struct in_addr)) == 0 &&
				p.arp.arp_op == htons(ARPOP_REQUEST) &&
				memcmp(&eth_addr, &p.arp.arp_tha, ETH_ALEN) != 0) {
				target_ip_conflict = 1;
			}

			VDBG("state = %d, source ip conflict = %d, target ip conflict = %d\n", 
				state, source_ip_conflict, target_ip_conflict);
			switch (state) {
			case PROBE:
			case ANNOUNCE:
				// When probing or announcing, check for source IP conflicts
				// and other hosts doing ARP probes (target IP conflicts).
				if (source_ip_conflict || target_ip_conflict) {
					conflicts++;
					if (conflicts >= MAX_CONFLICTS) {
						VDBG("%s ratelimit\n", intf);
						timeout = RATE_LIMIT_INTERVAL * 1000;
						state = RATE_LIMIT_PROBE;
					}

					// restart the whole protocol
					pick(&ip);
					timeout = 0;
					nprobes = 0;
					nclaims = 0;
				}
				break;
			case MONITOR:
				// If a conflict, we try to defend with a single ARP probe.
				if (source_ip_conflict) {
					VDBG("monitor conflict -- defending\n");
					state = DEFEND;
					timeout = DEFEND_INTERVAL * 1000;
					arp(fd, &saddr,
							ARPOP_REQUEST,
							&eth_addr, ip,
							&eth_addr, ip);
				}
				break;
			case DEFEND:
				// Well, we tried.  Start over (on conflict).
				if (source_ip_conflict) {
					state = PROBE;
					VDBG("defend conflict -- starting over\n");
					ready = 0;
					run(script, "deconfig", intf, &ip);

					// restart the whole protocol
					pick(&ip);
					timeout = 0;
					nprobes = 0;
					nclaims = 0;
				}
				break;
			default:
				// Invalid, should never happen.  Restart the whole protocol.
				VDBG("invalid state -- starting over\n");
				state = PROBE;
				pick(&ip);
				timeout = 0;
				nprobes = 0;
				nclaims = 0;
				break;
			} // switch state

			break; // case 1 (packets arriving)
		default:
			why = "poll";
			goto bad;
		} // switch poll
	}
bad:
	bb_perror_msg("%s, %s", intf, why);
	return EXIT_FAILURE;
}
