/*
 * Original implementation on libmnl:
 * (C) 2011 by Pablo Neira Ayuso <pablo@netfilter.org>
 * (C) 2011 by Intra2net AG <http://www.intra2net.com>
 *
 * Port to libnl:
 * (C) 2013 by Mathieu J. Poirier <mathieu.poirier@linaro.org>
 *
 * 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.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>
#include <endian.h>

#include <netlink-private/object-api.h>
#include <netlink-private/types.h>
#include <linux/netlink.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_acct.h>
#include <netlink/netfilter/nfnl.h>
#include <netlink/netlink.h>
#include <netlink/socket.h>
#include <netlink/msg.h>

#define VERSION "1.0.1"

enum {
	NFACCT_CMD_NONE = 0,
	NFACCT_CMD_LIST,
	NFACCT_CMD_ADD,
	NFACCT_CMD_DELETE,
	NFACCT_CMD_GET,
	NFACCT_CMD_FLUSH,
	NFACCT_CMD_VERSION,
	NFACCT_CMD_HELP,
	NFACCT_CMD_RESTORE,
};

static int nfacct_cmd_list(int argc, char *argv[]);
static int nfacct_cmd_add(int argc, char *argv[]);
static int nfacct_cmd_delete(int argc, char *argv[]);
static int nfacct_cmd_get(int argc, char *argv[]);
static int nfacct_cmd_flush(int argc, char *argv[]);
static int nfacct_cmd_version(int argc, char *argv[]);
static int nfacct_cmd_help(int argc, char *argv[]);
static int nfacct_cmd_restore(int argc, char *argv[]);

#ifndef HAVE_LIBNL20
#define nl_sock nl_handle
#define nl_socket_alloc nl_handle_alloc
#define nl_socket_free nl_handle_destroy
#endif

#define NL_DBG(LVL,FMT,ARG...) do { } while(0)

static void usage(char *argv[])
{
	fprintf(stderr, "Usage: %s command [parameters]...\n", argv[0]);
}

static void nfacct_perror(const char *msg)
{
	if (errno == 0) {
		fprintf(stderr, "nfacct v%s: %s\n", VERSION, msg);
	} else {
		fprintf(stderr, "nfacct v%s: %s: %s\n",
			VERSION, msg, strerror(errno));
	}
}

int main(int argc, char *argv[])
{
	int cmd = NFACCT_CMD_NONE, ret = 0;

	if (argc < 2) {
		usage(argv);
		exit(EXIT_FAILURE);
	}

	if (strncmp(argv[1], "list", strlen(argv[1])) == 0)
		cmd = NFACCT_CMD_LIST;
	else if (strncmp(argv[1], "add", strlen(argv[1])) == 0)
		cmd = NFACCT_CMD_ADD;
	else if (strncmp(argv[1], "delete", strlen(argv[1])) == 0)
		cmd = NFACCT_CMD_DELETE;
	else if (strncmp(argv[1], "get", strlen(argv[1])) == 0)
		cmd = NFACCT_CMD_GET;
	else if (strncmp(argv[1], "flush", strlen(argv[1])) == 0)
		cmd = NFACCT_CMD_FLUSH;
	else if (strncmp(argv[1], "version", strlen(argv[1])) == 0)
		cmd = NFACCT_CMD_VERSION;
	else if (strncmp(argv[1], "help", strlen(argv[1])) == 0)
		cmd = NFACCT_CMD_HELP;
	else if (strncmp(argv[1], "restore", strlen(argv[1])) == 0)
		cmd = NFACCT_CMD_RESTORE;
	else {
		fprintf(stderr, "nfacct v%s: Unknown command: %s\n",
			VERSION, argv[1]);
		usage(argv);
		exit(EXIT_FAILURE);
	}

	switch(cmd) {
	case NFACCT_CMD_LIST:
		ret = nfacct_cmd_list(argc, argv);
		break;
	case NFACCT_CMD_ADD:
		ret = nfacct_cmd_add(argc, argv);
		break;
	case NFACCT_CMD_DELETE:
		ret = nfacct_cmd_delete(argc, argv);
		break;
	case NFACCT_CMD_GET:
		ret = nfacct_cmd_get(argc, argv);
		break;
	case NFACCT_CMD_FLUSH:
		ret = nfacct_cmd_flush(argc, argv);
		break;
	case NFACCT_CMD_VERSION:
		ret = nfacct_cmd_version(argc, argv);
		break;
	case NFACCT_CMD_HELP:
		ret = nfacct_cmd_help(argc, argv);
		break;
	case NFACCT_CMD_RESTORE:
		ret = nfacct_cmd_restore(argc, argv);
		break;
	}
	return ret < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}


static int message_received(struct nl_msg *msg, void *arg)
{
	struct nlmsghdr *hdr = msg->nm_nlh;

	if (hdr->nlmsg_type == NLMSG_ERROR) {
		struct nlmsgerr *err = nlmsg_data(hdr);

		if (err->error == 0)
			return NL_STOP;
	}

	return NL_OK;
}

static int valid_input(struct nl_msg *msg, void *arg)
{
	struct nlattr *nla = nlmsg_attrdata(nlmsg_hdr(msg),
					 sizeof(struct nfgenmsg));
	struct nlattr *tb[NFACCT_NAME_MAX+1] = {};
	char buf[4096];
	int ret;

	ret = nlmsg_parse(nlmsg_hdr(msg),
			 sizeof(struct nfgenmsg), tb, NFACCT_MAX, NULL);

	if (ret < 0) {
		nfacct_perror("Can't parse message\n");
		return ret;
	}

	ret = snprintf(buf, sizeof(buf),
		"{ pkts = %.20llu, bytes = %.20llu } = %s;",
		(unsigned long long)be64toh(nla_get_u64(tb[NFACCT_PKTS])),
		(unsigned long long)be64toh(nla_get_u64(tb[NFACCT_BYTES])),
		nla_get_string(tb[NFACCT_NAME]));

	printf("%s\n", buf);

	return 0;
}

static int nfacct_cmd_list(int argc, char *argv[])
{
	struct nl_msg *msg;
	struct nl_sock *handle;
	int zeroctr = 0;
	int ret, i;

	for (i=2; i<argc; i++) {
		if (strncmp(argv[i], "reset", strlen(argv[i])) == 0) {
			zeroctr = 1;
		} else if (strncmp(argv[i], "xml", strlen(argv[i])) == 0) {
			nfacct_perror("xml feature not implemented");
			return -1;
		} else {
			nfacct_perror("unknown argument");
			return -1;
		}
	}

	msg = nlmsg_alloc();
	if (!msg)
		return -1;

	ret = nfnlmsg_put(msg,
			NL_AUTO_PID,
			NL_AUTO_SEQ,
			NFNL_SUBSYS_ACCT,
			zeroctr ?
			NFNL_MSG_ACCT_GET_CTRZERO : NFNL_MSG_ACCT_GET,
			NLM_F_DUMP | NLM_F_REQUEST,
			AF_UNSPEC,
			0);

	if (ret) {
		NL_DBG(2, "Can't append payload to message: %s line: %d\n",
							__FUNCTION__, __LINE__);
		goto fail;
	}

	handle = nl_socket_alloc();
	if ((ret = nfnl_connect(handle))) {
		NL_DBG(2, "Can't connect handle: %s line: %d\n",
							__FUNCTION__, __LINE__);
		goto fail;
	}

	if ((ret = nl_send_auto_complete(handle, msg)) < 0) {
		NL_DBG(2, "Can't send msg: %s line: %d\n",
							__FUNCTION__, __LINE__);
		goto fail_send;
        }

	nl_socket_modify_cb(handle, NL_CB_VALID, NL_CB_CUSTOM, valid_input, NULL);
	ret = nl_recvmsgs_default(handle);
	if (ret < 0) {
		NL_DBG(2, "Can't receice msg: %s line: %d\n",
							__FUNCTION__, __LINE__);
	}

fail_send:
	nl_close(handle);
	nl_socket_free(handle);
fail:
	nlmsg_free(msg);
	return ret;
}

static int _nfacct_cmd_add(char *name, int pkts, int bytes)
{
	struct nl_msg *msg;
	struct nl_sock *handle;
	char nfname[NFACCT_NAME_MAX];
	int ret;

	strncpy(nfname, name, NFACCT_NAME_MAX);
	nfname[NFACCT_NAME_MAX-1] = '\0';

	msg = nlmsg_alloc();
	if (!msg)
		return -1;

	ret = nfnlmsg_put(msg,
			NL_AUTO_PID,
			NL_AUTO_SEQ,
			NFNL_SUBSYS_ACCT,
			NFNL_MSG_ACCT_NEW,
			NLM_F_CREATE | NLM_F_ACK | NLM_F_REQUEST,
			AF_UNSPEC,
			0);

	if (ret) {
		NL_DBG(2, "Can't append payload to message: %s line: %d\n",
							__FUNCTION__, __LINE__);
		goto fail;
	}

	nla_put_string(msg, NFACCT_NAME, nfname);
	nla_put_u64(msg, NFACCT_PKTS, htobe64(pkts));
	nla_put_u64(msg, NFACCT_BYTES, htobe64(bytes));

	handle = nl_socket_alloc();
	if ((ret = nfnl_connect(handle))) {
		NL_DBG(2, "Can't connect handle: %s line: %d\n",
							__FUNCTION__, __LINE__);
		goto fail;
	}

	if ((ret = nl_send_auto_complete(handle, msg)) < 0) {
		NL_DBG(2, "Can't send msg: %s line: %d\n",
							__FUNCTION__, __LINE__);
		goto fail_send;
        }

	ret = nl_recvmsgs_default(handle);
	if (ret < 0) {
		NL_DBG(2, "Can't receice msg: %s line: %d\n",
							__FUNCTION__, __LINE__);
	}

fail_send:
	nl_close(handle);
	nl_socket_free(handle);
fail:
	nlmsg_free(msg);
	return ret;
}



static int nfacct_cmd_add(int argc, char *argv[])
{
	if (argc < 3) {
		nfacct_perror("missing object name");
		return -1;
	} else if (argc > 3) {
		nfacct_perror("too many arguments");
		return -1;
	}

	return _nfacct_cmd_add(argv[2], 0, 0);
}

static int nfacct_cmd_delete(int argc, char *argv[])
{
	struct nl_msg *msg;
	struct nl_sock *handle;
	char nfname[NFACCT_NAME_MAX];
	int ret;

	if (argc < 3) {
		nfacct_perror("missing object name");
		return -1;
	} else if (argc > 3) {
		nfacct_perror("too many arguments");
		return -1;
	}

	strncpy(nfname, argv[2], NFACCT_NAME_MAX);
	nfname[NFACCT_NAME_MAX-1] = '\0';

	msg = nlmsg_alloc();
	if (!msg)
		return -1;

	ret = nfnlmsg_put(msg,
			NL_AUTO_PID,
			NL_AUTO_SEQ,
			NFNL_SUBSYS_ACCT,
			NFNL_MSG_ACCT_DEL,
			NLM_F_ACK | NLM_F_REQUEST,
			AF_UNSPEC,
			0);

	if (ret) {
		NL_DBG(2, "Can't append payload to message: %s line: %d\n",
							__FUNCTION__, __LINE__);
		goto fail;
	}

	nla_put_string(msg, NFACCT_NAME, nfname);

	handle = nl_socket_alloc();
	if ((ret = nfnl_connect(handle))) {
		NL_DBG(2, "Can't connect handle: %s line: %d\n",
							__FUNCTION__, __LINE__);
		goto fail;
	}

	if ((ret = nl_send_auto_complete(handle, msg)) < 0) {
		NL_DBG(2, "Can't send msg: %s line: %d\n",
							__FUNCTION__, __LINE__);
		goto fail_send;
        }

	ret = nl_recvmsgs_default(handle);
	if (ret < 0) {
		NL_DBG(2, "Can't receice msg: %s line: %d\n",
							__FUNCTION__, __LINE__);
	}

fail_send:
	nl_close(handle);
	nl_socket_free(handle);
fail:
	nlmsg_free(msg);
	return ret;
	return 0;
}


static int nfacct_cmd_get(int argc, char *argv[])
{
	struct nl_msg *msg;
	struct nl_sock *handle;
	struct nl_cb *cb;
	char nfname[NFACCT_NAME_MAX];
	int zeroctr = 0;
	int ret, i;

	if (argc < 3) {
		nfacct_perror("missing object name");
		 return -1;
	}

	for (i=3; i<argc; i++) {
		if (strncmp(argv[i], "reset", strlen(argv[i])) == 0) {
			zeroctr = 1;
		} else if (strncmp(argv[i], "xml", strlen(argv[i])) == 0) {
			nfacct_perror("xml feature not implemented");
			return -1;
		} else {
			nfacct_perror("unknown argument");
			return -1;
		}
	}

	strncpy(nfname, argv[2], NFACCT_NAME_MAX);
	nfname[NFACCT_NAME_MAX-1] = '\0';

	msg = nlmsg_alloc();
	if (!msg)
		return -1;

	ret = nfnlmsg_put(msg,
			NL_AUTO_PID,
			NL_AUTO_SEQ,
			NFNL_SUBSYS_ACCT,
			zeroctr ?
			NFNL_MSG_ACCT_GET_CTRZERO : NFNL_MSG_ACCT_GET,
			NLM_F_ACK | NLM_F_REQUEST,
			AF_UNSPEC,
			0);

	if (ret) {
		NL_DBG(2, "Can't append payload to message: %s line: %d\n",
							__FUNCTION__, __LINE__);
		goto fail;
	}

	nla_put_string(msg, NFACCT_NAME, nfname);

	handle = nl_socket_alloc();

	if (handle) {
		cb = nl_cb_alloc(NL_CB_DEFAULT);
		if (!cb)
			goto fail;

		if (nl_cb_set(cb, NL_CB_MSG_IN,
				 NL_CB_CUSTOM,
				 message_received, NULL) < 0)
			goto fail;

		nl_socket_set_cb(handle,cb);
	} else {
		goto fail;
	}

	if ((ret = nfnl_connect(handle))) {
		NL_DBG(2, "Can't connect handle: %s line: %d\n",
							__FUNCTION__, __LINE__);
		goto fail;
	}

	if ((ret = nl_send_auto_complete(handle, msg)) < 0) {
		NL_DBG(2, "Can't send msg: %s line: %d\n",
							__FUNCTION__, __LINE__);
		goto fail_send;
        }

	nl_socket_modify_cb(handle, NL_CB_VALID, NL_CB_CUSTOM, valid_input, NULL);
	ret = nl_recvmsgs_default(handle);
	if (ret < 0) {
		NL_DBG(2, "Can't receice msg: %s line: %d\n",
							__FUNCTION__, __LINE__);
	}

fail_send:
	nl_close(handle);
	nl_socket_free(handle);
fail:
	nlmsg_free(msg);
	return ret;
}

static int nfacct_cmd_flush(int argc, char *argv[])
{
	struct nl_msg *msg;
	struct nl_sock *handle;
	int ret;

	if (argc > 2) {
		nfacct_perror("too many arguments");
		return -1;
	}

	msg = nlmsg_alloc();
	if (!msg)
		return -1;

	ret = nfnlmsg_put(msg,
			NL_AUTO_PID,
			NL_AUTO_SEQ,
			NFNL_SUBSYS_ACCT,
			NFNL_MSG_ACCT_DEL,
			NLM_F_ACK | NLM_F_REQUEST,
			AF_UNSPEC,
			0);

	if (ret) {
		NL_DBG(2, "Can't append payload to message: %s line: %d\n",
							__FUNCTION__, __LINE__);
		goto fail;
	}

	handle = nl_socket_alloc();
	if ((ret = nfnl_connect(handle))) {
		NL_DBG(2, "Can't connect handle: %s line: %d\n",
							__FUNCTION__, __LINE__);
		goto fail;
	}

	if ((ret = nl_send_auto_complete(handle, msg)) < 0) {
		NL_DBG(2, "Can't send msg: %s line: %d\n",
							__FUNCTION__, __LINE__);
		goto fail_send;
        }

	ret = nl_recvmsgs_default(handle);
	if (ret < 0) {
		NL_DBG(2, "Can't receice msg: %s line: %d\n",
							__FUNCTION__, __LINE__);
	}

fail_send:
	nl_close(handle);
	nl_socket_free(handle);
fail:
	nlmsg_free(msg);
	return ret;
}

static const char version_msg[] =
	"nfacct v%s: utility for the Netfilter extended accounting "
	"infrastructure\n"
	"Copyright (C) 2011 Pablo Neira Ayuso <pablo@netfilter.org>\n"
	"Copyright (C) 2011 Intra2net AG <http://www.intra2net.com>\n"
	"Copyright (C) 2013 Mathieu Poirier <mathieu.poirier@linaro.org>\n"
	"This program comes with ABSOLUTELY NO WARRANTY.\n"
	"This is free software, and you are welcome to redistribute it under "
	"certain \nconditions; see LICENSE file distributed in this package "
	"for details.\n";

static int nfacct_cmd_version(int argc, char *argv[])
{
	printf(version_msg, VERSION);
	return 0;
}

static const char help_msg[] =
	"nfacct v%s: utility for the Netfilter extended accounting "
	"infrastructure\n"
	"Usage: %s command [parameters]...\n\n"
	"Commands:\n"
	"  list [reset]\t\tList the accounting object table (and reset)\n"
	"  add object-name\tAdd new accounting object to table\n"
	"  delete object-name\tDelete existing accounting object\n"
	"  get object-name\tGet existing accounting object\n"
	"  flush\t\t\tFlush accounting object table\n"
	"  restore\t\tRestore accounting object table reading 'list' output from stdin\n"
	"  version\t\tDisplay version and disclaimer\n"
	"  help\t\t\tDisplay this help message\n";

static int nfacct_cmd_help(int argc, char *argv[])
{
	printf(help_msg, VERSION, argv[0]);
	return 0;
}

static int nfacct_cmd_restore(int argc, char *argv[])
{
	uint64_t pkts, bytes;
	char name[512];
	char buffer[512];
	int ret;
	while (fgets(buffer, sizeof(buffer), stdin)) {
		char *semicolon = strchr(buffer, ';');
		if (semicolon == NULL) {
			nfacct_perror("invalid line");
			return -1;
		}
		*semicolon = 0;
		ret = sscanf(buffer, "{ pkts = %llu, bytes = %llu } = %s",
		       &pkts, &bytes, name);
		if (ret != 3) {
			nfacct_perror("error reading input");
			return -1;
		}
		if ((ret = _nfacct_cmd_add(name, pkts, bytes)) != 0)
			return ret;

	}
	return 0;
}
