/*
 * dhcpcd - DHCP client daemon
 * Copyright (c) 2006-2015 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/socket.h>
#include <sys/types.h>

#include <net/if.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>

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

#define ELOOP_QUEUE 5
#include "config.h"
#include "arp.h"
#include "if.h"
#include "ipv4.h"
#include "common.h"
#include "dhcp.h"
#include "dhcpcd.h"
#include "eloop.h"
#include "if.h"
#include "if-options.h"
#include "ipv4ll.h"

#define ARP_LEN								      \
	(sizeof(struct arphdr) + (2 * sizeof(uint32_t)) + (2 * HWADDR_LEN))

static ssize_t
arp_request(const struct interface *ifp, in_addr_t sip, in_addr_t tip,
	    const uint8_t *dest_hw_addr)
{
	uint8_t arp_buffer[ARP_LEN];
	struct arphdr ar;
	size_t len;
	uint8_t *p;

	ar.ar_hrd = htons(ifp->family);
	ar.ar_pro = htons(ETHERTYPE_IP);
	ar.ar_hln = ifp->hwlen;
	ar.ar_pln = sizeof(sip);
	ar.ar_op = htons(ARPOP_REQUEST);

	p = arp_buffer;
	len = 0;

#define CHECK(fun, b, l)						\
	do {								\
		if (len + (l) > sizeof(arp_buffer))			\
			goto eexit;					\
		fun(p, (b), (l));					\
		p += (l);						\
		len += (l);						\
	} while (/* CONSTCOND */ 0)
#define APPEND(b, l)	CHECK(memcpy, b, l)
#define ZERO(l)		CHECK(memset, 0, l)

	APPEND(&ar, sizeof(ar));
	APPEND(ifp->hwaddr, ifp->hwlen);
	APPEND(&sip, sizeof(sip));
	if (dest_hw_addr)
		APPEND(dest_hw_addr, ifp->hwlen);
	else
		ZERO(ifp->hwlen);
	APPEND(&tip, sizeof(tip));
	return if_sendrawpacket(ifp, ETHERTYPE_ARP, arp_buffer, len,
				dest_hw_addr);

eexit:
	errno = ENOBUFS;
	return -1;
}

void
arp_report_conflicted(const struct arp_state *astate, const struct arp_msg *amsg)
{

	if (amsg) {
		char buf[HWADDR_LEN * 3];

		logger(astate->iface->ctx, LOG_ERR,
		    "%s: hardware address %s claims %s",
		    astate->iface->name,
		    hwaddr_ntoa(amsg->sha, astate->iface->hwlen,
		    buf, sizeof(buf)),
		    inet_ntoa(astate->failed));
	} else
		logger(astate->iface->ctx, LOG_ERR,
		    "%s: DAD detected %s",
		    astate->iface->name, inet_ntoa(astate->failed));
}

static void
arp_packet(void *arg)
{
	struct interface *ifp = arg;
	const struct interface *ifn;
	uint8_t arp_buffer[ARP_LEN];
	struct arphdr ar;
	struct arp_msg arm;
	ssize_t bytes;
	struct dhcp_state *state;
	struct arp_state *astate, *astaten;
	unsigned char *hw_s, *hw_t;
	int flags;

	state = D_STATE(ifp);
	state->failed.s_addr = 0;
	flags = 0;
	while (!(flags & RAW_EOF)) {
		bytes = if_readrawpacket(ifp, ETHERTYPE_ARP,
		    arp_buffer, sizeof(arp_buffer), &flags);
		if (bytes == -1) {
			logger(ifp->ctx, LOG_ERR,
			    "%s: arp if_readrawpacket: %m", ifp->name);
			dhcp_close(ifp);
			return;
		}
		/* We must have a full ARP header */
		if ((size_t)bytes < sizeof(ar))
			continue;
		memcpy(&ar, arp_buffer, sizeof(ar));
		/* Families must match */
		if (ar.ar_hrd != htons(ifp->family))
			continue;
		/* Protocol must be IP. */
		if (ar.ar_pro != htons(ETHERTYPE_IP))
			continue;
		if (ar.ar_pln != sizeof(arm.sip.s_addr))
			continue;
		/* Only these types are recognised */
		if (ar.ar_op != htons(ARPOP_REPLY) &&
		    ar.ar_op != htons(ARPOP_REQUEST))
			continue;

		/* Get pointers to the hardware addreses */
		hw_s = arp_buffer + sizeof(ar);
		hw_t = hw_s + ar.ar_hln + ar.ar_pln;
		/* Ensure we got all the data */
		if ((hw_t + ar.ar_hln + ar.ar_pln) - arp_buffer > bytes)
			continue;
		/* Ignore messages from ourself */
		TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) {
			if (ar.ar_hln == ifn->hwlen &&
			    memcmp(hw_s, ifn->hwaddr, ifn->hwlen) == 0)
				break;
		}
		if (ifn)
			continue;
		/* Copy out the HW and IP addresses */
		memcpy(&arm.sha, hw_s, ar.ar_hln);
		memcpy(&arm.sip.s_addr, hw_s + ar.ar_hln, ar.ar_pln);
		memcpy(&arm.tha, hw_t, ar.ar_hln);
		memcpy(&arm.tip.s_addr, hw_t + ar.ar_hln, ar.ar_pln);

		/* Run the conflicts */
		TAILQ_FOREACH_SAFE(astate, &state->arp_states, next, astaten) {
			if (astate->conflicted_cb)
				astate->conflicted_cb(astate, &arm);
		}
	}
}

static void
arp_open(struct interface *ifp)
{
	struct dhcp_state *state;

	state = D_STATE(ifp);
	if (state->arp_fd == -1) {
		state->arp_fd = if_openrawsocket(ifp, ETHERTYPE_ARP);
		if (state->arp_fd == -1) {
			logger(ifp->ctx, LOG_ERR, "%s: %s: %m",
			    __func__, ifp->name);
			return;
		}
		eloop_event_add(ifp->ctx->eloop, state->arp_fd,
		    arp_packet, ifp, NULL, NULL);
	}
}

static void
arp_announced(void *arg)
{
	struct arp_state *astate = arg;

	if (astate->announced_cb) {
		astate->announced_cb(astate);
		return;
	}

	/* Nothing more to do, so free us */
	arp_free(astate);
}

static void
arp_announce1(void *arg)
{
	struct arp_state *astate = arg;
	struct interface *ifp = astate->iface;

	if (++astate->claims < ANNOUNCE_NUM)
		logger(ifp->ctx, LOG_DEBUG,
		    "%s: ARP announcing %s (%d of %d), "
		    "next in %d.0 seconds",
		    ifp->name, inet_ntoa(astate->addr),
		    astate->claims, ANNOUNCE_NUM, ANNOUNCE_WAIT);
	else
		logger(ifp->ctx, LOG_DEBUG,
		    "%s: ARP announcing %s (%d of %d)",
		    ifp->name, inet_ntoa(astate->addr),
		    astate->claims, ANNOUNCE_NUM);
	if (arp_request(ifp, astate->addr.s_addr, astate->addr.s_addr,
			NULL) == -1)
		logger(ifp->ctx, LOG_ERR, "send_arp: %m");
	eloop_timeout_add_sec(ifp->ctx->eloop, ANNOUNCE_WAIT,
	    astate->claims < ANNOUNCE_NUM ? arp_announce1 : arp_announced,
	    astate);
}

void
arp_announce(struct arp_state *astate)
{

	arp_open(astate->iface);
	astate->claims = 0;
	arp_announce1(astate);
}

static void
arp_probed(void *arg)
{
	struct arp_state *astate = arg;

	astate->probed_cb(astate);
}

static void
arp_probe1(void *arg)
{
	struct arp_state *astate = arg;
	struct interface *ifp = astate->iface;
	struct timespec tv;
	uint8_t *dest_hwaddr = NULL;

	if (++astate->probes < PROBE_NUM) {
		tv.tv_sec = PROBE_MIN;
		tv.tv_nsec = (suseconds_t)arc4random_uniform(
		    (PROBE_MAX - PROBE_MIN) * NSEC_PER_SEC);
		timespecnorm(&tv);
		eloop_timeout_add_tv(ifp->ctx->eloop, &tv, arp_probe1, astate);
	} else {
		tv.tv_sec = ANNOUNCE_WAIT;
		tv.tv_nsec = 0;
		eloop_timeout_add_tv(ifp->ctx->eloop, &tv, arp_probed, astate);
	}
	logger(ifp->ctx, LOG_INFO,
	    "%s: ARP probing %s (%d of %d), next in %0.1f seconds",
	    ifp->name, inet_ntoa(astate->addr),
	    astate->probes ? astate->probes : PROBE_NUM, PROBE_NUM,
	    timespec_to_double(&tv));
	if (astate->dest_hwlen == ifp->hwlen)
		dest_hwaddr = astate->dest_hwaddr;
	if (arp_request(ifp, astate->src_addr.s_addr,
			astate->addr.s_addr, dest_hwaddr) == -1)
		logger(ifp->ctx, LOG_ERR, "send_arp: %m");
}

void
arp_probe(struct arp_state *astate)
{

	arp_open(astate->iface);
	astate->probes = 0;
	logger(astate->iface->ctx, LOG_DEBUG, "%s: probing for %s",
	    astate->iface->name, inet_ntoa(astate->addr));
	arp_probe1(astate);
}

static struct arp_state *
arp_find(struct interface *ifp, const struct in_addr *addr)
{
	struct arp_state *astate;
	struct dhcp_state *state;

	state = D_STATE(ifp);
	TAILQ_FOREACH(astate, &state->arp_states, next) {
		if (astate->addr.s_addr == addr->s_addr && astate->iface == ifp)
			return astate;
	}
	errno = ESRCH;
	return NULL;
}

struct arp_state *
arp_new(struct interface *ifp, const struct in_addr *addr)
{
	struct arp_state *astate;
	struct dhcp_state *state;

	if (addr && (astate = arp_find(ifp, addr)))
		return astate;

	if ((astate = calloc(1, sizeof(*astate))) == NULL) {
		logger(ifp->ctx, LOG_ERR, "%s: %s: %m", ifp->name, __func__);
		return NULL;
	}
	state = D_STATE(ifp);
	astate->iface = ifp;
	if (addr)
		astate->addr = *addr;
	TAILQ_INSERT_TAIL(&state->arp_states, astate, next);
	return astate;
}

void
arp_cancel(struct arp_state *astate)
{

	eloop_timeout_delete(astate->iface->ctx->eloop, NULL, astate);
}

void
arp_free(struct arp_state *astate)
{
	struct dhcp_state *state;

	if (astate) {
		eloop_timeout_delete(astate->iface->ctx->eloop, NULL, astate);
		state = D_STATE(astate->iface);
		TAILQ_REMOVE(&state->arp_states, astate, next);
		if (state->arp_ipv4ll == astate) {
			ipv4ll_stop(astate->iface);
			state->arp_ipv4ll = NULL;
		}
		free(astate);
	}
}

void
arp_free_but(struct arp_state *astate)
{
	struct arp_state *p, *n;
	struct dhcp_state *state;

	state = D_STATE(astate->iface);
	TAILQ_FOREACH_SAFE(p, &state->arp_states, next, n) {
		if (p != astate)
			arp_free(p);
	}
}

void
arp_close(struct interface *ifp)
{
	struct dhcp_state *state = D_STATE(ifp);
	struct arp_state *astate;

	if (state == NULL)
		return;

	if (state->arp_fd != -1) {
		eloop_event_delete(ifp->ctx->eloop, state->arp_fd, 0);
		close(state->arp_fd);
		state->arp_fd = -1;
	}

	while ((astate = TAILQ_FIRST(&state->arp_states))) {
#ifndef __clang_analyzer__
		/* clang guard needed for a more compex variant on this bug:
		 * http://llvm.org/bugs/show_bug.cgi?id=18222 */
		arp_free(astate);
#endif
	}
}

void
arp_handleifa(int cmd, struct interface *ifp, const struct in_addr *addr,
    int flags)
{
#ifdef IN_IFF_DUPLICATED
	struct dhcp_state *state = D_STATE(ifp);
	struct arp_state *astate, *asn;

	if (cmd != RTM_NEWADDR || (state = D_STATE(ifp)) == NULL)
		return;

	TAILQ_FOREACH_SAFE(astate, &state->arp_states, next, asn) {
		if (astate->addr.s_addr == addr->s_addr) {
			if (flags & IN_IFF_DUPLICATED) {
				if (astate->conflicted_cb)
					astate->conflicted_cb(astate, NULL);
			} else if (!(flags & IN_IFF_NOTUSEABLE)) {
				if (astate->probed_cb)
					astate->probed_cb(astate);
			}
		}
	}
#else
	UNUSED(cmd);
	UNUSED(ifp);
	UNUSED(addr);
	UNUSED(flags);
#endif
}
