/*
 * libipq.c
 *
 * IPQ userspace library.
 *
 * Please note that this library is still developmental, and there may
 * be some API changes.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
        
#include <libipq/libipq.h>

/****************************************************************************
 *
 * Private interface
 *
 ****************************************************************************/

enum {
	IPQ_ERR_NONE = 0,
	IPQ_ERR_IMPL,
	IPQ_ERR_HANDLE,
	IPQ_ERR_SOCKET,
	IPQ_ERR_BIND,
	IPQ_ERR_BUFFER,
	IPQ_ERR_RECV,
	IPQ_ERR_NLEOF,
	IPQ_ERR_ADDRLEN,
	IPQ_ERR_STRUNC,
	IPQ_ERR_RTRUNC,
	IPQ_ERR_NLRECV,
	IPQ_ERR_SEND,
	IPQ_ERR_SUPP,
	IPQ_ERR_RECVBUF
};
#define IPQ_MAXERR IPQ_ERR_RECVBUF

struct ipq_errmap_t {
	int errcode;
	char *message;
} ipq_errmap[] = {
	{ IPQ_ERR_NONE, "Unknown error" },
	{ IPQ_ERR_IMPL, "Implementation error" },
	{ IPQ_ERR_HANDLE, "Unable to create netlink handle" },
	{ IPQ_ERR_SOCKET, "Unable to create netlink socket" },
	{ IPQ_ERR_BIND, "Unable to bind netlink socket" },
	{ IPQ_ERR_BUFFER, "Unable to allocate buffer" },
	{ IPQ_ERR_RECV, "Failed to receive netlink message" },
	{ IPQ_ERR_NLEOF, "Received EOF on netlink socket" },
	{ IPQ_ERR_ADDRLEN, "Invalid peer address length" },
	{ IPQ_ERR_STRUNC, "Sent message truncated" },
	{ IPQ_ERR_RTRUNC, "Received message truncated" },
	{ IPQ_ERR_NLRECV, "Received error from netlink" },
	{ IPQ_ERR_SEND, "Failed to send netlink message" },
	{ IPQ_ERR_SUPP, "Operation not supported" },
	{ IPQ_ERR_RECVBUF, "Receive buffer size invalid" }
};

static int ipq_errno = IPQ_ERR_NONE;

static ssize_t ipq_netlink_sendto(const struct ipq_handle *h,
                                  const void *msg, size_t len);
                    
static ssize_t ipq_netlink_recvfrom(const struct ipq_handle *h,
                                    unsigned char *buf, size_t len);
                      
static ssize_t ipq_netlink_sendmsg(const struct ipq_handle *h,
                                   const struct msghdr *msg,
                                   unsigned int flags);
                     
static char *ipq_strerror(int errcode);

static ssize_t ipq_netlink_sendto(const struct ipq_handle *h,
                                  const void *msg, size_t len)
{
	int status = sendto(h->fd, msg, len, 0,
	                    (struct sockaddr *)&h->peer, sizeof(h->peer));
	if (status < 0)
		ipq_errno = IPQ_ERR_SEND;
	return status;	
}

static ssize_t ipq_netlink_sendmsg(const struct ipq_handle *h,
                                   const struct msghdr *msg,
                                   unsigned int flags)
{
	int status = sendmsg(h->fd, msg, flags);
	if (status < 0)
		ipq_errno = IPQ_ERR_SEND;
	return status;	
}

static ssize_t ipq_netlink_recvfrom(const struct ipq_handle *h,
                                    unsigned char *buf, size_t len)
{
	int addrlen, status;
	struct nlmsghdr *nlh;
	
	if (len < sizeof(struct nlmsgerr)) {
		ipq_errno = IPQ_ERR_RECVBUF;
		return -1;
	}
	addrlen = sizeof(h->peer);
	status = recvfrom(h->fd, buf, len, 0,
	                      (struct sockaddr *)&h->peer, &addrlen);
	if (status < 0) {
		ipq_errno = IPQ_ERR_RECV;
		return status;
	}
	if (addrlen != sizeof(h->peer)) {
		ipq_errno = IPQ_ERR_RECV;
		return -1;
	}
	if (status == 0) {
		ipq_errno = IPQ_ERR_NLEOF;
		return -1;
	}
	nlh = (struct nlmsghdr *)buf;
	if (nlh->nlmsg_flags & MSG_TRUNC || nlh->nlmsg_len > status) {
		ipq_errno = IPQ_ERR_RTRUNC;
		return -1;
	}
	return status;
}

static char *ipq_strerror(int errcode)
{
	if (errcode < 0 || errcode > IPQ_MAXERR)
		errcode = IPQ_ERR_IMPL;
	return ipq_errmap[errcode].message;
}

/****************************************************************************
 *
 * Public interface
 *
 ****************************************************************************/

/* 
 * Create and initialise an ipq handle.
 * FIXME: implement flags.
 */
struct ipq_handle *ipq_create_handle(u_int32_t flags)
{
	int status;
	struct ipq_handle *h;
	
	h = (struct ipq_handle *)malloc(sizeof(struct ipq_handle));
	if (h == NULL) {
		ipq_errno = IPQ_ERR_HANDLE;
		return NULL;
	}
	memset(h, 0, sizeof(struct ipq_handle));
	h->fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_FIREWALL);
	if (h->fd == -1) {
		ipq_errno = IPQ_ERR_SOCKET;
		close(h->fd);
		free(h);
		return NULL;
	}
	memset(&h->local, 0, sizeof(struct sockaddr_nl));
	h->local.nl_family = AF_NETLINK;
	h->local.nl_pid = getpid();
	h->local.nl_groups = 0;
	status = bind(h->fd, (struct sockaddr *)&h->local, sizeof(h->local));
	if (status == -1) {
		ipq_errno = IPQ_ERR_BIND;
		close(h->fd);
		free(h);
		return NULL;
	}
	memset(&h->peer, 0, sizeof(struct sockaddr_nl));
	h->peer.nl_family = AF_NETLINK;
	h->peer.nl_pid = 0;
	h->peer.nl_groups = 0;
	return h;
}

/*
 * No error condition is checked here at this stage, but it may happen 
 * if/when reliable messaging is implemented.
 */
int ipq_destroy_handle(struct ipq_handle *h)
{
	if (h) {
		close(h->fd);
		free(h);
	}
	return 0;
}

int ipq_set_mode(const struct ipq_handle *h,
                 u_int8_t mode, size_t range)
{
	struct {
		struct nlmsghdr nlh;
		ipq_peer_msg_t pm;
	} req;
	
	memset(&req, 0, sizeof(req));
	req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(req));
	req.nlh.nlmsg_flags = NLM_F_REQUEST;
	req.nlh.nlmsg_type = IPQM_MODE;
	req.nlh.nlmsg_pid = h->local.nl_pid;
	req.pm.msg.mode.value = mode;
	req.pm.msg.mode.range = range;
	return ipq_netlink_sendto(h, (void *)&req, req.nlh.nlmsg_len);
}

/* Note: timeout is not yet implemented */
ssize_t ipq_read(const struct ipq_handle *h,
                 unsigned char *buf, size_t len, int timeout)
{
	return ipq_netlink_recvfrom(h, buf, len);
}

int ipq_message_type(const unsigned char *buf)
{
	return ((struct nlmsghdr*)buf)->nlmsg_type;
}

int ipq_get_msgerr(const unsigned char *buf)
{
	struct nlmsghdr *h = (struct nlmsghdr *)buf;
	struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h);
	return -err->error;
}

ipq_packet_msg_t *ipq_get_packet(const unsigned char *buf)
{
	return NLMSG_DATA((struct nlmsghdr *)(buf));
}

int ipq_set_verdict(const struct ipq_handle *h,
                    unsigned long id,
                    unsigned int verdict,
                    size_t data_len,
                    unsigned char *buf)
{
	unsigned char nvecs;
	size_t tlen;
	struct nlmsghdr nlh;
	ipq_peer_msg_t pm;
	struct iovec iov[3];
	struct msghdr msg;

	memset(&nlh, 0, sizeof(nlh));
	nlh.nlmsg_flags = NLM_F_REQUEST;
	nlh.nlmsg_type = IPQM_VERDICT;
	nlh.nlmsg_pid = h->local.nl_pid;
	memset(&pm, 0, sizeof(pm));
	pm.msg.verdict.value = verdict;
	pm.msg.verdict.id = id;
	pm.msg.verdict.data_len = data_len;
	iov[0].iov_base = &nlh;
	iov[0].iov_len = sizeof(nlh);
	iov[1].iov_base = &pm;
	iov[1].iov_len = sizeof(pm);
	tlen = sizeof(nlh) + sizeof(pm);
	nvecs = 2;
	if (data_len && buf) {
		iov[2].iov_base = buf;
		iov[2].iov_len = data_len;
		tlen += data_len;
		nvecs++;
	}
	msg.msg_name = (void *)&h->peer;
	msg.msg_namelen = sizeof(h->peer);
	msg.msg_iov = iov;
	msg.msg_iovlen = nvecs;
	msg.msg_control = NULL;
	msg.msg_controllen = 0;
	msg.msg_flags = 0;
	nlh.nlmsg_len = tlen;
	return ipq_netlink_sendmsg(h, &msg, 0);
}

/* Not implemented yet */
int ipq_ctl(const struct ipq_handle *h, int request, ...)
{
	return 1;
}

void ipq_perror(const char *s)
{
	if (s)
		fputs(s, stderr);
	else
		fputs("ERROR", stderr);
	if (ipq_errno)
		fprintf(stderr, ": %s", ipq_strerror(ipq_errno));
	if (errno)
		fprintf(stderr, ": %s", strerror(errno));
	fputc('\n', stderr);
}
