/*
 * (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>
 */

#define _GNU_SOURCE
#include "config.h"
#include <errno.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <netinet/ether.h>
#include <netinet/in.h>
#include <netinet/ip6.h>
#include <net/if_arp.h>
#include <getopt.h>

#include <sys/socket.h>
#include <arpa/inet.h>

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

#include <libmnl/libmnl.h>
#include <libnftnl/table.h>
#include <libnftnl/trace.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"
#include "nft-arp.h"

struct cb_arg {
	uint32_t nfproto;
	bool is_event;
	struct nft_handle *h;
};

static int table_cb(const struct nlmsghdr *nlh, void *data)
{
	uint32_t type = nlh->nlmsg_type & 0xFF;
	const struct cb_arg *arg = data;
	struct nftnl_table *t;
	char buf[4096];

	t = nftnl_table_alloc();
	if (t == NULL)
		goto err;

	if (nftnl_table_nlmsg_parse(nlh, t) < 0)
		goto err_free;

	if (arg->nfproto && arg->nfproto != nftnl_table_get_u32(t, NFTNL_TABLE_FAMILY))
		goto err_free;
	nftnl_table_snprintf(buf, sizeof(buf), t, NFTNL_OUTPUT_DEFAULT, 0);
	printf(" EVENT: ");
	printf("nft: %s table: %s\n", type == NFT_MSG_NEWTABLE ? "NEW" : "DEL", buf);

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

static bool counters;
static bool trace;
static bool events;

static int rule_cb(const struct nlmsghdr *nlh, void *data)
{
	uint32_t type = nlh->nlmsg_type & 0xFF;
	const struct cb_arg *arg = data;
	struct nftnl_rule *r;
	uint8_t family;

	r = nftnl_rule_alloc();
	if (r == NULL)
		goto err;

	if (nftnl_rule_nlmsg_parse(nlh, r) < 0)
		goto err_free;

	family = nftnl_rule_get_u32(r, NFTNL_RULE_FAMILY);
	if (arg->nfproto && arg->nfproto != family)
		goto err_free;

	arg->h->ops = nft_family_ops_lookup(family);

	if (arg->is_event)
		printf(" EVENT: ");
	switch (family) {
	case AF_INET:
	case AF_INET6:
		printf("-%c ", family == AF_INET ? '4' : '6');
		break;
	case NFPROTO_ARP:
		printf("-0 ");
		break;
	default:
		puts("");
		goto err_free;
	}

	printf("-t %s ", nftnl_rule_get_str(r, NFTNL_RULE_TABLE));
	nft_rule_print_save(arg->h, r, type == NFT_MSG_NEWRULE ? NFT_RULE_APPEND :
							   NFT_RULE_DEL,
			    counters ? 0 : FMT_NOCOUNTS);
err_free:
	nftnl_rule_free(r);
err:
	return MNL_CB_OK;
}

static int chain_cb(const struct nlmsghdr *nlh, void *data)
{
	uint32_t type = nlh->nlmsg_type & 0xFF;
	const struct cb_arg *arg = data;
	struct nftnl_chain *c;
	char buf[4096];
	int family;

	c = nftnl_chain_alloc();
	if (c == NULL)
		goto err;

	if (nftnl_chain_nlmsg_parse(nlh, c) < 0)
		goto err_free;

	family = nftnl_chain_get_u32(c, NFTNL_CHAIN_FAMILY);
	if (arg->nfproto && arg->nfproto != family)
		goto err_free;

	if (nftnl_chain_is_set(c, NFTNL_CHAIN_PRIO))
		family = -1;

	printf(" EVENT: ");
	switch (family) {
	case NFPROTO_IPV4:
		family = 4;
		break;
	case NFPROTO_IPV6:
		family = 6;
		break;
	default:
		nftnl_chain_snprintf(buf, sizeof(buf), c, NFTNL_OUTPUT_DEFAULT, 0);
		printf("# nft: %s\n", buf);
		goto err_free;
	}

	printf("-%d -t %s -%c %s\n",
			family,
			nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE),
			type == NFT_MSG_NEWCHAIN ? 'N' : 'X',
			nftnl_chain_get_str(c, NFTNL_CHAIN_NAME));
err_free:
	nftnl_chain_free(c);
err:
	return MNL_CB_OK;
}

static int newgen_cb(const struct nlmsghdr *nlh, void *data)
{
	uint32_t genid = 0, pid = 0;
	const struct nlattr *attr;
	const char *name = NULL;

	mnl_attr_for_each(attr, nlh, sizeof(struct nfgenmsg)) {
		switch (mnl_attr_get_type(attr)) {
		case NFTA_GEN_ID:
			if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
				break;
		        genid = ntohl(mnl_attr_get_u32(attr));
			break;
		case NFTA_GEN_PROC_NAME:
			if (mnl_attr_validate(attr, MNL_TYPE_NUL_STRING) < 0)
				break;
			name = mnl_attr_get_str(attr);
			break;
		case NFTA_GEN_PROC_PID:
			if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
				break;
			pid = ntohl(mnl_attr_get_u32(attr));
			break;
		}
	}

	if (name)
		printf("NEWGEN: GENID=%u PID=%u NAME=%s\n", genid, pid, name);

	return MNL_CB_OK;
}

static void trace_print_return(const struct nftnl_trace *nlt)
{
	const char *chain = NULL;

	if (nftnl_trace_is_set(nlt, NFTNL_TRACE_JUMP_TARGET)) {
		chain = nftnl_trace_get_str(nlt, NFTNL_TRACE_JUMP_TARGET);
		printf("%s", chain);
	}
}

static void trace_print_rule(const struct nftnl_trace *nlt, struct cb_arg *args)
{
	uint64_t handle = nftnl_trace_get_u64(nlt, NFTNL_TRACE_RULE_HANDLE);
	uint32_t family = nftnl_trace_get_u32(nlt, NFTNL_TRACE_FAMILY);
	const char *table = nftnl_trace_get_str(nlt, NFTNL_TRACE_TABLE);
	const char *chain = nftnl_trace_get_str(nlt, NFTNL_TRACE_CHAIN);
        struct nftnl_rule *r;
	struct mnl_socket *nl;
	struct nlmsghdr *nlh;
	uint32_t portid;
	char buf[16536];
	int ret;

        r = nftnl_rule_alloc();
	if (r == NULL) {
		perror("OOM");
		exit(EXIT_FAILURE);
	}

	nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_GETRULE, family, 0, 0);

        nftnl_rule_set_u32(r, NFTNL_RULE_FAMILY, family);
	nftnl_rule_set_str(r, NFTNL_RULE_CHAIN, chain);
	nftnl_rule_set_str(r, NFTNL_RULE_TABLE, table);
	nftnl_rule_set_u64(r, NFTNL_RULE_HANDLE, handle);
	nftnl_rule_nlmsg_build_payload(nlh, r);
	nftnl_rule_free(r);

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

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

	portid = mnl_socket_get_portid(nl);
	if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
		perror("mnl_socket_send");
		exit(EXIT_FAILURE);
	}

	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	if (ret > 0) {
		args->is_event = false;
		ret = mnl_cb_run(buf, ret, 0, portid, rule_cb, args);
	}
	if (ret == -1) {
		perror("error");
		exit(EXIT_FAILURE);
	}
	mnl_socket_close(nl);
}

static void trace_print_packet(const struct nftnl_trace *nlt, struct cb_arg *args)
{
	struct list_head stmts = LIST_HEAD_INIT(stmts);
	uint32_t nfproto, family;
	uint16_t l4proto = 0;
	uint32_t mark;
	char name[IFNAMSIZ];

	family = nftnl_trace_get_u32(nlt, NFTNL_TRACE_FAMILY);
	printf("PACKET: %d %08x ", family, nftnl_trace_get_u32(nlt, NFTNL_TRACE_ID));

	if (nftnl_trace_is_set(nlt, NFTNL_TRACE_IIF))
		printf("IN=%s ", if_indextoname(nftnl_trace_get_u32(nlt, NFTNL_TRACE_IIF), name));
	if (nftnl_trace_is_set(nlt, NFTNL_TRACE_OIF))
		printf("OUT=%s ", if_indextoname(nftnl_trace_get_u32(nlt, NFTNL_TRACE_OIF), name));

	nfproto = family;
	if (nftnl_trace_is_set(nlt, NFTNL_TRACE_NFPROTO)) {
		nfproto = nftnl_trace_get_u32(nlt, NFTNL_TRACE_NFPROTO);

		if (family != nfproto)
			printf("NFPROTO=%d ", nfproto);
	}

	if (nftnl_trace_is_set(nlt, NFTNL_TRACE_LL_HEADER)) {
		const struct ethhdr *eh;
		const char *linklayer;
		uint32_t i, len;
		uint16_t type = nftnl_trace_get_u16(nlt, NFTNL_TRACE_IIFTYPE);

		linklayer = nftnl_trace_get_data(nlt, NFTNL_TRACE_LL_HEADER, &len);
		switch (type) {
		case ARPHRD_ETHER:
			if (len < sizeof(*eh))
			       break;
			eh = (const void *)linklayer;
			printf("MACSRC=%s ", ether_ntoa((const void *)eh->h_source));
			printf("MACDST=%s ", ether_ntoa((const void *)eh->h_dest));
			printf("MACPROTO=%04x ", ntohs(eh->h_proto));
			break;
		case ARPHRD_LOOPBACK:
			printf("LOOPBACK ");
			break;
		default:
			printf("LL=0x%x ", type);
			for (i = 0 ; i < len; i++)
				printf("%02x", linklayer[i]);
			printf(" ");
			break;
		}
	}

	if (nftnl_trace_is_set(nlt, NFTNL_TRACE_NETWORK_HEADER)) {
		const struct ip6_hdr *ip6h;
		const struct iphdr *iph;
		uint32_t i, len;
		const char *nh;

		ip6h = nftnl_trace_get_data(nlt, NFTNL_TRACE_NETWORK_HEADER, &len);

		switch (nfproto) {
		case NFPROTO_IPV4: {
			char addrbuf[INET_ADDRSTRLEN];

			if (len < sizeof(*iph))
				break;
			iph = (const void *)ip6h;


			inet_ntop(AF_INET, &iph->saddr, addrbuf, sizeof(addrbuf));
			printf("SRC=%s ", addrbuf);
			inet_ntop(AF_INET, &iph->daddr, addrbuf, sizeof(addrbuf));
			printf("DST=%s ", addrbuf);

			printf("LEN=%d TOS=0x%x TTL=%d ID=%d", ntohs(iph->tot_len), iph->tos, iph->ttl, ntohs(iph->id));
			if (iph->frag_off & htons(0x8000))
				printf("CE ");
			if (iph->frag_off & htons(IP_DF))
				printf("DF ");
			if (iph->frag_off & htons(IP_MF))
				printf("MF ");

			if (ntohs(iph->frag_off) & 0x1fff)
				printf("FRAG:%u ", ntohs(iph->frag_off) & 0x1fff);

			l4proto = iph->protocol;
			if (iph->ihl * 4 > sizeof(*iph)) {
				unsigned int optsize;
				const char *op;

				optsize = iph->ihl * 4 - sizeof(*iph);
				op = (const char *)iph;
				op += sizeof(*iph);

				printf("OPT (");
				for (i = 0; i < optsize; i++)
					printf("%02X", op[i]);
				printf(")");
			}
			break;
		}
		case NFPROTO_IPV6: {
			uint32_t flowlabel = ntohl(*(uint32_t *)ip6h);
			char addrbuf[INET6_ADDRSTRLEN];

			if (len < sizeof(*ip6h))
				break;

			inet_ntop(AF_INET6, &ip6h->ip6_src, addrbuf, sizeof(addrbuf));
			printf("SRC=%s ", addrbuf);
			inet_ntop(AF_INET6, &ip6h->ip6_dst, addrbuf, sizeof(addrbuf));
			printf("DST=%s ", addrbuf);

			printf("LEN=%zu TC=%u HOPLIMIT=%u FLOWLBL=%u ",
				ntohs(ip6h->ip6_plen) + sizeof(*iph),
				(flowlabel & 0x0ff00000) >> 20,
				ip6h->ip6_hops,
				flowlabel & 0x000fffff);

			l4proto = ip6h->ip6_nxt;
			break;
		}
		default:
			nh = (const char *)ip6h;
			printf("NH=");
			for (i = 0 ; i < len; i++)
				printf("%02x", nh[i]);
			printf(" ");
		}
	}

	if (nftnl_trace_is_set(nlt, NFTNL_TRACE_TRANSPORT_HEADER)) {
		const struct tcphdr *tcph;
		uint32_t len;

		tcph = nftnl_trace_get_data(nlt, NFTNL_TRACE_TRANSPORT_HEADER, &len);

		switch (l4proto) {
		case IPPROTO_DCCP:
		case IPPROTO_SCTP:
		case IPPROTO_UDPLITE:
		case IPPROTO_UDP:
			if (len < 4)
				break;
			printf("SPORT=%d DPORT=%d ", ntohs(tcph->source), ntohs(tcph->dest));
			break;
		case IPPROTO_TCP:
			if (len < sizeof(*tcph))
				break;
			printf("SPORT=%d DPORT=%d ", ntohs(tcph->source), ntohs(tcph->dest));
			if (tcph->syn)
				printf("SYN ");
			if (tcph->ack)
				printf("ACK ");
			if (tcph->fin)
				printf("FIN ");
			if (tcph->rst)
				printf("RST ");
			if (tcph->psh)
				printf("PSH ");
			if (tcph->urg)
				printf("URG ");
			break;
		default:
			break;
		}
	}

	mark = nftnl_trace_get_u32(nlt, NFTNL_TRACE_MARK);
	if (mark)
		printf("MARK=0x%x ", mark);
	puts("");
}

static void trace_print_hdr(const struct nftnl_trace *nlt)
{
	printf(" TRACE: %d %08x %s:%s", nftnl_trace_get_u32(nlt, NFTNL_TABLE_FAMILY),
					nftnl_trace_get_u32(nlt, NFTNL_TRACE_ID),
					nftnl_trace_get_str(nlt, NFTNL_TRACE_TABLE),
					nftnl_trace_get_str(nlt, NFTNL_TRACE_CHAIN));
}

static void print_verdict(const struct nftnl_trace *nlt, uint32_t verdict)
{
	const char *chain;

	switch (verdict) {
	case NF_ACCEPT:
		printf("ACCEPT");
		break;
	case NF_DROP:
		printf("DROP");
		break;
	case NF_QUEUE:
		printf("QUEUE");
		break;
	case NF_STOLEN:
		printf("STOLEN");
		break;
	case NFT_BREAK:
		printf("BREAK");
		break;
	case NFT_CONTINUE:
		printf("CONTINUE");
		break;
	case NFT_GOTO:
		printf("GOTO");
		if (nftnl_trace_is_set(nlt, NFTNL_TRACE_JUMP_TARGET)) {
			chain = nftnl_trace_get_str(nlt, NFTNL_TRACE_JUMP_TARGET);
			printf(":%s", chain);
		}
		break;
	case NFT_JUMP:
		printf("JUMP");
		if (nftnl_trace_is_set(nlt, NFTNL_TRACE_JUMP_TARGET)) {
			chain = nftnl_trace_get_str(nlt, NFTNL_TRACE_JUMP_TARGET);
			printf(":%s", chain);
		}
		break;
	default:
		printf("0x%x", verdict);
		break;
	}

	printf(" ");
}

static int trace_cb(const struct nlmsghdr *nlh, struct cb_arg *arg)
{
	struct nftnl_trace *nlt;
	uint32_t verdict;

	nlt = nftnl_trace_alloc();
	if (nlt == NULL)
		goto err;

	if (nftnl_trace_nlmsg_parse(nlh, nlt) < 0)
		goto err_free;

	if (arg->nfproto &&
	    arg->nfproto != nftnl_trace_get_u32(nlt, NFTNL_TABLE_FAMILY))
		goto err_free;

	switch (nftnl_trace_get_u32(nlt, NFTNL_TRACE_TYPE)) {
	case NFT_TRACETYPE_RULE:
		verdict = nftnl_trace_get_u32(nlt, NFTNL_TRACE_VERDICT);

		if (nftnl_trace_is_set(nlt, NFTNL_TRACE_LL_HEADER) ||
		    nftnl_trace_is_set(nlt, NFTNL_TRACE_NETWORK_HEADER))
			trace_print_packet(nlt, arg);

		if (nftnl_trace_is_set(nlt, NFTNL_TRACE_RULE_HANDLE)) {
			trace_print_hdr(nlt);
			printf(":rule:0x%" PRIx64":", nftnl_trace_get_u64(nlt, NFTNL_TRACE_RULE_HANDLE));
			print_verdict(nlt, verdict);
			printf(" ");
			trace_print_rule(nlt, arg);
		}
		break;
	case NFT_TRACETYPE_POLICY:
		trace_print_hdr(nlt);
		printf(":policy:");
		verdict = nftnl_trace_get_u32(nlt, NFTNL_TRACE_POLICY);

		print_verdict(nlt, verdict);
		puts("");
		break;
	case NFT_TRACETYPE_RETURN:
		trace_print_hdr(nlt);
		printf(":return:");
		trace_print_return(nlt);
		puts("");
		break;
	}
err_free:
	nftnl_trace_free(nlt);
err:
	fflush(stdout);
	return MNL_CB_OK;
}

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

	switch(type) {
	case NFT_MSG_NEWTABLE:
	case NFT_MSG_DELTABLE:
		ret = table_cb(nlh, data);
		break;
	case NFT_MSG_NEWCHAIN:
	case NFT_MSG_DELCHAIN:
		ret = chain_cb(nlh, data);
		break;
	case NFT_MSG_NEWRULE:
	case NFT_MSG_DELRULE:
		arg->is_event = true;
		ret = rule_cb(nlh, data);
		break;
	case NFT_MSG_NEWGEN:
		ret = newgen_cb(nlh, data);
		break;
	case NFT_MSG_TRACE:
		ret = trace_cb(nlh, data);
		break;
	}

	return ret;
}

static const struct option options[] = {
	{.name = "counters", .has_arg = false, .val = 'c'},
	{.name = "trace", .has_arg = false, .val = 't'},
	{.name = "event", .has_arg = false, .val = 'e'},
	{.name = "ipv4", .has_arg = false, .val = '4'},
	{.name = "ipv6", .has_arg = false, .val = '6'},
	{.name = "version", .has_arg = false, .val = 'V'},
	{.name = "help", .has_arg = false, .val = 'h'},
	{NULL},
};

static void print_usage(void)
{
	printf("%s %s\n", xtables_globals.program_name,
			  xtables_globals.program_version);
	printf("Usage: %s [ -t | -e ]\n"
	       "        --trace    -t    trace ruleset traversal of packets tagged via -j TRACE rule\n"
	       "        --event    -e    show events that modify the ruleset\n"
	       "Optional arguments:\n"
	       "        --ipv4     -4    only monitor IPv4\n"
	       "        --ipv6     -6    only monitor IPv6\n"
	       "	--counters -c    show counters in rules\n"

	       , xtables_globals.program_name);
	exit(EXIT_FAILURE);
}

int xtables_monitor_main(int argc, char *argv[])
{
	struct mnl_socket *nl;
	char buf[MNL_SOCKET_BUFFER_SIZE];
	uint32_t nfgroup = 0;
	struct nft_handle h = {};
	struct cb_arg cb_arg = {
		.h = &h,
	};
	int ret, c;

	xtables_globals.program_name = "xtables-monitor";
	/* 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

	if (nft_init(&h, AF_INET, xtables_ipv4)) {
		fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
			xtables_globals.program_name,
			xtables_globals.program_version,
			strerror(errno));
		exit(EXIT_FAILURE);
	}

	opterr = 0;
	while ((c = getopt_long(argc, argv, "ceht46V", options, NULL)) != -1) {
		switch (c) {
	        case 'c':
			counters = true;
			break;
	        case 't':
			trace = true;
			break;
	        case 'e':
			events = true;
			break;
	        case 'h':
			print_usage();
			exit(0);
		case '4':
			cb_arg.nfproto = NFPROTO_IPV4;
			break;
		case '6':
			cb_arg.nfproto = NFPROTO_IPV6;
			break;
		case 'V':
			printf("xtables-monitor %s\n", PACKAGE_VERSION);
			exit(0);
		default:
			fprintf(stderr, "xtables-monitor %s: Bad argument.\n", PACKAGE_VERSION);
			fprintf(stderr, "Try `xtables-monitor -h' for more information.\n");
			exit(PARAMETER_PROBLEM);
		}
	}

	if (trace)
		nfgroup |= 1 << (NFNLGRP_NFTRACE - 1);
	if (events)
		nfgroup |= 1 << (NFNLGRP_NFTABLES - 1);

	if (nfgroup == 0) {
		print_usage();
		exit(EXIT_FAILURE);
	}

	nl = mnl_socket_open(NETLINK_NETFILTER);
	if (nl == NULL) {
		perror("cannot open nfnetlink socket");
		exit(EXIT_FAILURE);
	}

	if (mnl_socket_bind(nl, nfgroup, MNL_SOCKET_AUTOPID) < 0) {
		perror("cannot bind to nfnetlink socket");
		exit(EXIT_FAILURE);
	}

	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	while (ret > 0) {
		ret = mnl_cb_run(buf, ret, 0, 0, monitor_cb, &cb_arg);
		if (ret <= 0)
			break;
		ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
	}
	if (ret == -1) {
		perror("cannot receive from nfnetlink socket");
		exit(EXIT_FAILURE);
	}
	mnl_socket_close(nl);

	xtables_fini();

	return EXIT_SUCCESS;
}

