/*
 * dhcpcd - DHCP client daemon
 * Copyright 2006-2008 Roy Marples <roy@marples.name>
 *
 * 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/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/uio.h>

#include <net/bpf.h>
#include <net/if.h>
#include <arpa/inet.h>

#include <errno.h>
#include <fcntl.h>
#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "config.h"
#include "common.h"
#include "dhcp.h"
#include "logger.h"
#include "net.h"
#include "bpf-filter.h"

int
open_socket(struct interface *iface, int protocol)
{
	int fd = -1;
	int *fdp = NULL;
	struct ifreq ifr;
	int buf_len = 0;
	struct bpf_version pv;
	struct bpf_program pf;
#ifdef BIOCIMMEDIATE
	int flags;
#endif
#ifdef _PATH_BPF
	fd = open(_PATH_BPF, O_RDWR | O_NONBLOCK);
#else
	char *device;
	int n = 0;

	device = xmalloc(sizeof(char) * PATH_MAX);
	do {
		snprintf(device, PATH_MAX, "/dev/bpf%d", n++);
		fd = open(device, O_RDWR | O_NONBLOCK);
	} while (fd == -1 && errno == EBUSY);
	free(device);
#endif

	if (fd == -1)
		return -1;

	if (ioctl(fd, BIOCVERSION, &pv) == -1)
		goto eexit;
	if (pv.bv_major != BPF_MAJOR_VERSION ||
	    pv.bv_minor < BPF_MINOR_VERSION) {
		logger(LOG_ERR, "BPF version mismatch - recompile " PACKAGE);
		goto eexit;
	}

	memset(&ifr, 0, sizeof(ifr));
	strlcpy(ifr.ifr_name, iface->name, sizeof(ifr.ifr_name));
	if (ioctl(fd, BIOCSETIF, &ifr) == -1)
		goto eexit;

	/* Get the required BPF buffer length from the kernel. */
	if (ioctl(fd, BIOCGBLEN, &buf_len) == -1)
		goto eexit;
	if (iface->buffer_size != (size_t)buf_len) {
		free(iface->buffer);
		iface->buffer_size = buf_len;
		iface->buffer = xmalloc(buf_len);
		iface->buffer_len = iface->buffer_pos = 0;
	}

#ifdef BIOCIMMEDIATE
	flags = 1;
	if (ioctl(fd, BIOCIMMEDIATE, &flags) == -1)
		goto eexit;
#endif

	/* Install the DHCP filter */
	if (protocol == ETHERTYPE_ARP) {
		pf.bf_insns = UNCONST(arp_bpf_filter);
		pf.bf_len = arp_bpf_filter_len;
		fdp = &iface->arp_fd;
	} else {
		pf.bf_insns = UNCONST(dhcp_bpf_filter);
		pf.bf_len = dhcp_bpf_filter_len;
		fdp = &iface->raw_fd;
	}
	if (ioctl(fd, BIOCSETF, &pf) == -1)
		goto eexit;
	if (set_cloexec(fd) == -1)
		goto eexit;
	if (fdp) {
		if (*fdp != -1)
			close(*fdp);
		*fdp = fd;
	}
	return fd;

eexit:
	free(iface->buffer);
	iface->buffer = NULL;
	close(fd);
	return -1;
}

ssize_t
send_raw_packet(const struct interface *iface, int protocol,
		const void *data, ssize_t len)
{
	struct iovec iov[2];
	struct ether_header hw;
	int fd;

	memset(&hw, 0, ETHER_HDR_LEN);
	memset(&hw.ether_dhost, 0xff, ETHER_ADDR_LEN);
	hw.ether_type = htons(protocol);
	iov[0].iov_base = &hw;
	iov[0].iov_len = ETHER_HDR_LEN;
	iov[1].iov_base = UNCONST(data);
	iov[1].iov_len = len;
	if (protocol == ETHERTYPE_ARP)
		fd = iface->arp_fd;
	else
		fd = iface->raw_fd;
	return writev(fd, iov, 2);
}

/* BPF requires that we read the entire buffer.
 * So we pass the buffer in the API so we can loop on >1 packet. */
ssize_t
get_raw_packet(struct interface *iface, int protocol,
	       void *data, ssize_t len)
{
	int fd = -1;
	struct bpf_hdr packet;
	ssize_t bytes;
	const unsigned char *payload;

	if (protocol == ETHERTYPE_ARP)
		fd = iface->arp_fd;
	else
		fd = iface->raw_fd;

	for (;;) {
		if (iface->buffer_len == 0) {
			bytes = read(fd, iface->buffer, iface->buffer_size);
			if (bytes == -1)
				return errno == EAGAIN ? 0 : -1;
			else if ((size_t)bytes < sizeof(packet))
				return -1;
			iface->buffer_len = bytes;
			iface->buffer_pos = 0;
		}
		bytes = -1;
		memcpy(&packet, iface->buffer + iface->buffer_pos,
		       sizeof(packet));
		if (packet.bh_caplen != packet.bh_datalen)
			goto next; /* Incomplete packet, drop. */
		if (iface->buffer_pos + packet.bh_caplen + packet.bh_hdrlen >
		    iface->buffer_len)
			goto next; /* Packet beyond buffer, drop. */
		payload = iface->buffer + packet.bh_hdrlen + ETHER_HDR_LEN;
		bytes = packet.bh_caplen - ETHER_HDR_LEN;
		if (bytes > len)
			bytes = len;
		memcpy(data, payload, bytes);
next:
		iface->buffer_pos += BPF_WORDALIGN(packet.bh_hdrlen +
						   packet.bh_caplen);
		if (iface->buffer_pos >= iface->buffer_len)
			iface->buffer_len = iface->buffer_pos = 0;
		if (bytes != -1)
			return bytes;
	}
}
