/*
 * (C) 2012-2013 by Pablo Neira Ayuso <pablo@netfilter.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.
 *
 * This software has been sponsored by Sophos Astaro <http://www.sophos.com>
 */

#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <netinet/in.h>
#include <getopt.h>

#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nf_tables.h>

#include <libmnl/libmnl.h>
#include <libnftnl/table.h>
#include <libnftnl/chain.h>
#include <libnftnl/rule.h>

#include <include/xtables.h>
#include "iptables.h" /* for xtables_globals */
#include "xtables-multi.h"
#include "nft.h"

static int table_cb(const struct nlmsghdr *nlh, int type)
{
	struct nft_table *t;
	char buf[4096];

	t = nft_table_alloc();
	if (t == NULL) {
		perror("OOM");
		goto err;
	}

	if (nft_table_nlmsg_parse(nlh, t) < 0) {
		perror("nft_table_nlmsg_parse");
		goto err_free;
	}

	nft_table_snprintf(buf, sizeof(buf), t, NFT_OUTPUT_DEFAULT, 0);
	/* FIXME: define syntax to represent table events */
	printf("# [table: %s]\t%s\n", type == NFT_MSG_NEWTABLE ? "NEW" : "DEL", buf);

err_free:
	nft_table_free(t);
err:
	return MNL_CB_OK;
}

static bool counters;

static int rule_cb(const struct nlmsghdr *nlh, int type)
{
	struct iptables_command_state cs = {};
	struct nft_rule *r;

	r = nft_rule_alloc();
	if (r == NULL) {
		perror("OOM");
		goto err;
	}

	if (nft_rule_nlmsg_parse(nlh, r) < 0) {
		perror("nft_rule_nlmsg_parse");
		goto err_free;
	}

	nft_rule_to_iptables_command_state(r, &cs);

	switch(nft_rule_attr_get_u8(r, NFT_RULE_ATTR_FAMILY)) {
	case AF_INET:
		printf("-4 ");
		break;
	case AF_INET6:
		printf("-6 ");
		break;
	default:
		break;
	}


	nft_rule_print_save(&cs, r,
			    type == NFT_MSG_NEWRULE ? NFT_RULE_APPEND :
						      NFT_RULE_DEL,
			    counters ? 0 : FMT_NOCOUNTS);
err_free:
	nft_rule_free(r);
err:
	return MNL_CB_OK;
}

static int chain_cb(const struct nlmsghdr *nlh, int type)
{
	struct nft_chain *t;
	char buf[4096];

	t = nft_chain_alloc();
	if (t == NULL) {
		perror("OOM");
		goto err;
	}

	if (nft_chain_nlmsg_parse(nlh, t) < 0) {
		perror("nft_chain_nlmsg_parse");
		goto err_free;
	}

	nft_chain_snprintf(buf, sizeof(buf), t, NFT_OUTPUT_DEFAULT, 0);
	/* FIXME: define syntax to represent chain events */
	printf("# [chain: %s]\t%s\n", type == NFT_MSG_NEWCHAIN ? "NEW" : "DEL", buf);

err_free:
	nft_chain_free(t);
err:
	return MNL_CB_OK;
}

static int events_cb(const struct nlmsghdr *nlh, void *data)
{
	int ret = MNL_CB_OK;
	int type = nlh->nlmsg_type & 0xFF;

	switch(type) {
	case NFT_MSG_NEWTABLE:
	case NFT_MSG_DELTABLE:
		ret = table_cb(nlh, type);
		break;
	case NFT_MSG_NEWCHAIN:
	case NFT_MSG_DELCHAIN:
		ret = chain_cb(nlh, type);
		break;
	case NFT_MSG_NEWRULE:
	case NFT_MSG_DELRULE:
		ret = rule_cb(nlh, type);
		break;
	}

	return ret;
}

static const struct option options[] = {
	{.name = "counters", .has_arg = false, .val = 'c'},
	{NULL},
};

static void print_usage(const char *name, const char *version)
{
	fprintf(stderr, "Usage: %s [-c]\n"
			"	   [ --counters ]\n", name);
	exit(EXIT_FAILURE);
}

int xtables_events_main(int argc, char *argv[])
{
	struct mnl_socket *nl;
	char buf[MNL_SOCKET_BUFFER_SIZE];
	int ret, c;

	xtables_globals.program_name = "xtables-events";
	/* XXX xtables_init_all does several things we don't want */
	c = xtables_init_all(&xtables_globals, NFPROTO_IPV4);
	if (c < 0) {
		fprintf(stderr, "%s/%s Failed to initialize xtables\n",
				xtables_globals.program_name,
				xtables_globals.program_version);
		exit(1);
	}
#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
	init_extensions();
	init_extensions4();
#endif

	opterr = 0;
	while ((c = getopt_long(argc, argv, "c", options, NULL)) != -1) {
		switch (c) {
	        case 'c':
			counters = true;
			break;
		default:
			print_usage(argv[0], XTABLES_VERSION);
			exit(EXIT_FAILURE);
		}
	}

	nl = mnl_socket_open(NETLINK_NETFILTER);
	if (nl == NULL) {
		perror("mnl_socket_open");
		exit(EXIT_FAILURE);
	}

	if (mnl_socket_bind(nl, (1 << (NFNLGRP_NFTABLES-1)), MNL_SOCKET_AUTOPID) < 0) {
		perror("mnl_socket_bind");
		exit(EXIT_FAILURE);
	}

	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	while (ret > 0) {
		ret = mnl_cb_run(buf, ret, 0, 0, events_cb, NULL);
		if (ret <= 0)
			break;
		ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	}
	if (ret == -1) {
		perror("error");
		exit(EXIT_FAILURE);
	}
	mnl_socket_close(nl);

	return EXIT_SUCCESS;
}
