/*
 * 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) {
#ifdef ENABLE_ARP
		pf.bf_insns = UNCONST(arp_bpf_filter);
		pf.bf_len = arp_bpf_filter_len;
		fdp = &iface->arp_fd;
#endif
	} else {
		pf.bf_insns = UNCONST(dhcp_bpf_filter);
		pf.bf_len = dhcp_bpf_filter_len;
		fdp = &iface->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;

	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;
	return writev(iface->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) {
#ifdef ENABLE_ARP
		fd = iface->arp_fd;
#endif
	} else
		fd = iface->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;
	}
}
