/*
 * lib/netfilter/ct.c	Conntrack
 *
 *	This library is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU Lesser General Public
 *	License as published by the Free Software Foundation version 2.1
 *	of the License.
 *
 * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
 * Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
 * Copyright (c) 2007 Secure Computing Corporation
 * Copyright (c= 2008 Patrick McHardy <kaber@trash.net>
 */

/**
 * @ingroup nfnl
 * @defgroup ct Conntrack
 * @brief
 * @{
 */

#include <byteswap.h>
#include <sys/types.h>
#include <linux/netfilter/nfnetlink_conntrack.h>

#include <netlink-local.h>
#include <netlink/attr.h>
#include <netlink/netfilter/nfnl.h>
#include <netlink/netfilter/ct.h>

static struct nl_cache_ops nfnl_ct_ops;

#if __BYTE_ORDER == __BIG_ENDIAN
static uint64_t ntohll(uint64_t x)
{
	return x;
}
#elif __BYTE_ORDER == __LITTLE_ENDIAN
static uint64_t ntohll(uint64_t x)
{
	return __bswap_64(x);
}
#endif

static struct nla_policy ct_policy[CTA_MAX+1] = {
	[CTA_TUPLE_ORIG]	= { .type = NLA_NESTED },
	[CTA_TUPLE_REPLY]	= { .type = NLA_NESTED },
	[CTA_STATUS]		= { .type = NLA_U32 },
	[CTA_PROTOINFO]		= { .type = NLA_NESTED },
	//[CTA_HELP]
	//[CTA_NAT_SRC]
	[CTA_TIMEOUT]		= { .type = NLA_U32 },
	[CTA_MARK]		= { .type = NLA_U32 },
	[CTA_COUNTERS_ORIG]	= { .type = NLA_NESTED },
	[CTA_COUNTERS_REPLY]	= { .type = NLA_NESTED },
	[CTA_USE]		= { .type = NLA_U32 },
	[CTA_ID]		= { .type = NLA_U32 },
	//[CTA_NAT_DST]
};

static struct nla_policy ct_tuple_policy[CTA_TUPLE_MAX+1] = {
	[CTA_TUPLE_IP]		= { .type = NLA_NESTED },
	[CTA_TUPLE_PROTO]	= { .type = NLA_NESTED },
};

static struct nla_policy ct_ip_policy[CTA_IP_MAX+1] = {
	[CTA_IP_V4_SRC]		= { .type = NLA_U32 },
	[CTA_IP_V4_DST]		= { .type = NLA_U32 },
	[CTA_IP_V6_SRC]		= { .minlen = 16 },
	[CTA_IP_V6_DST]		= { .minlen = 16 },
};

static struct nla_policy ct_proto_policy[CTA_PROTO_MAX+1] = {
	[CTA_PROTO_NUM]		= { .type = NLA_U8 },
	[CTA_PROTO_SRC_PORT]	= { .type = NLA_U16 },
	[CTA_PROTO_DST_PORT]	= { .type = NLA_U16 },
	[CTA_PROTO_ICMP_ID]	= { .type = NLA_U16 },
	[CTA_PROTO_ICMP_TYPE]	= { .type = NLA_U8 },
	[CTA_PROTO_ICMP_CODE]	= { .type = NLA_U8 },
	[CTA_PROTO_ICMPV6_ID]	= { .type = NLA_U16 },
	[CTA_PROTO_ICMPV6_TYPE]	= { .type = NLA_U8 },
	[CTA_PROTO_ICMPV6_CODE]	= { .type = NLA_U8 },
};

static struct nla_policy ct_protoinfo_policy[CTA_PROTOINFO_MAX+1] = {
	[CTA_PROTOINFO_TCP]	= { .type = NLA_NESTED },
};

static struct nla_policy ct_protoinfo_tcp_policy[CTA_PROTOINFO_TCP_MAX+1] = {
	[CTA_PROTOINFO_TCP_STATE]		= { .type = NLA_U8 },
	[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL]	= { .type = NLA_U8 },
	[CTA_PROTOINFO_TCP_WSCALE_REPLY]	= { .type = NLA_U8 },
	[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]	= { .minlen = 2 },
	[CTA_PROTOINFO_TCP_FLAGS_REPLY]		= { .minlen = 2 },

};

static struct nla_policy ct_counters_policy[CTA_COUNTERS_MAX+1] = {
	[CTA_COUNTERS_PACKETS]	= { .type = NLA_U64 },
	[CTA_COUNTERS_BYTES]	= { .type = NLA_U64 },
	[CTA_COUNTERS32_PACKETS]= { .type = NLA_U32 },
	[CTA_COUNTERS32_BYTES]	= { .type = NLA_U32 },
};

static int ct_parse_ip(struct nfnl_ct *ct, int repl, struct nlattr *attr)
{
	struct nlattr *tb[CTA_IP_MAX+1];
	struct nl_addr *addr;
	int err;

        err = nla_parse_nested(tb, CTA_IP_MAX, attr, ct_ip_policy);
	if (err < 0)
		goto errout;

	if (tb[CTA_IP_V4_SRC]) {
		addr = nl_addr_alloc_attr(tb[CTA_IP_V4_SRC], AF_INET);
		if (addr == NULL)
			goto errout_enomem;
		err = nfnl_ct_set_src(ct, repl, addr);
		nl_addr_put(addr);
		if (err < 0)
			goto errout;
	}
	if (tb[CTA_IP_V4_DST]) {
		addr = nl_addr_alloc_attr(tb[CTA_IP_V4_DST], AF_INET);
		if (addr == NULL)
			goto errout_enomem;
		err = nfnl_ct_set_dst(ct, repl, addr);
		nl_addr_put(addr);
		if (err < 0)
			goto errout;
	}
	if (tb[CTA_IP_V6_SRC]) {
		addr = nl_addr_alloc_attr(tb[CTA_IP_V6_SRC], AF_INET6);
		if (addr == NULL)
			goto errout_enomem;
		err = nfnl_ct_set_src(ct, repl, addr);
		nl_addr_put(addr);
		if (err < 0)
			goto errout;
	}
	if (tb[CTA_IP_V6_DST]) {
		addr = nl_addr_alloc_attr(tb[CTA_IP_V6_DST], AF_INET6);
		if (addr == NULL)
			goto errout_enomem;
		err = nfnl_ct_set_dst(ct, repl, addr);
		nl_addr_put(addr);
		if (err < 0)
			goto errout;
	}

	return 0;

errout_enomem:
	err = -NLE_NOMEM;
errout:
	return err;
}

static int ct_parse_proto(struct nfnl_ct *ct, int repl, struct nlattr *attr)
{
	struct nlattr *tb[CTA_PROTO_MAX+1];
	int err;

	err = nla_parse_nested(tb, CTA_PROTO_MAX, attr, ct_proto_policy);
	if (err < 0)
		return err;

	if (!repl && tb[CTA_PROTO_NUM])
		nfnl_ct_set_proto(ct, nla_get_u8(tb[CTA_PROTO_NUM]));
	if (tb[CTA_PROTO_SRC_PORT])
		nfnl_ct_set_src_port(ct, repl,
			ntohs(nla_get_u16(tb[CTA_PROTO_SRC_PORT])));
	if (tb[CTA_PROTO_DST_PORT])
		nfnl_ct_set_dst_port(ct, repl,
			ntohs(nla_get_u16(tb[CTA_PROTO_DST_PORT])));
	if (tb[CTA_PROTO_ICMP_ID])
		nfnl_ct_set_icmp_id(ct, repl,
			ntohs(nla_get_u16(tb[CTA_PROTO_ICMP_ID])));
	if (tb[CTA_PROTO_ICMP_TYPE])
		nfnl_ct_set_icmp_type(ct, repl,
				nla_get_u8(tb[CTA_PROTO_ICMP_TYPE]));
	if (tb[CTA_PROTO_ICMP_CODE])
		nfnl_ct_set_icmp_code(ct, repl,
				nla_get_u8(tb[CTA_PROTO_ICMP_CODE]));

	return 0;
}

static int ct_parse_tuple(struct nfnl_ct *ct, int repl, struct nlattr *attr)
{
	struct nlattr *tb[CTA_TUPLE_MAX+1];
	int err;

	err = nla_parse_nested(tb, CTA_TUPLE_MAX, attr, ct_tuple_policy);
	if (err < 0)
		return err;

	if (tb[CTA_TUPLE_IP]) {
		err = ct_parse_ip(ct, repl, tb[CTA_TUPLE_IP]);
		if (err < 0)
			return err;
	}

	if (tb[CTA_TUPLE_PROTO]) {
		err = ct_parse_proto(ct, repl, tb[CTA_TUPLE_PROTO]);
		if (err < 0)
			return err;
	}

	return 0;
}

static int ct_parse_protoinfo_tcp(struct nfnl_ct *ct, struct nlattr *attr)
{
	struct nlattr *tb[CTA_PROTOINFO_TCP_MAX+1];
	int err;

	err = nla_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr,
			       ct_protoinfo_tcp_policy);
	if (err < 0)
		return err;

	if (tb[CTA_PROTOINFO_TCP_STATE])
		nfnl_ct_set_tcp_state(ct,
				nla_get_u8(tb[CTA_PROTOINFO_TCP_STATE]));

	return 0;
}

static int ct_parse_protoinfo(struct nfnl_ct *ct, struct nlattr *attr)
{
	struct nlattr *tb[CTA_PROTOINFO_MAX+1];
	int err;

	err = nla_parse_nested(tb, CTA_PROTOINFO_MAX, attr,
			       ct_protoinfo_policy);
	if (err < 0)
		return err;

	if (tb[CTA_PROTOINFO_TCP]) {
		err = ct_parse_protoinfo_tcp(ct, tb[CTA_PROTOINFO_TCP]);
		if (err < 0)
			return err;
	}

	return 0;
}

static int ct_parse_counters(struct nfnl_ct *ct, int repl, struct nlattr *attr)
{
	struct nlattr *tb[CTA_COUNTERS_MAX+1];
	int err;

	err = nla_parse_nested(tb, CTA_COUNTERS_MAX, attr, ct_counters_policy);
	if (err < 0)
		return err;

	if (tb[CTA_COUNTERS_PACKETS])
		nfnl_ct_set_packets(ct, repl,
			ntohll(nla_get_u64(tb[CTA_COUNTERS_PACKETS])));
	if (tb[CTA_COUNTERS32_PACKETS])
		nfnl_ct_set_packets(ct, repl,
			ntohl(nla_get_u32(tb[CTA_COUNTERS32_PACKETS])));
	if (tb[CTA_COUNTERS_BYTES])
		nfnl_ct_set_bytes(ct, repl,
			ntohll(nla_get_u64(tb[CTA_COUNTERS_BYTES])));
	if (tb[CTA_COUNTERS32_BYTES])
		nfnl_ct_set_bytes(ct, repl,
			ntohl(nla_get_u32(tb[CTA_COUNTERS32_BYTES])));

	return 0;
}

int nfnlmsg_ct_group(struct nlmsghdr *nlh)
{
	switch (nfnlmsg_subtype(nlh)) {
	case IPCTNL_MSG_CT_NEW:
		if (nlh->nlmsg_flags & (NLM_F_CREATE|NLM_F_EXCL))
			return NFNLGRP_CONNTRACK_NEW;
		else
			return NFNLGRP_CONNTRACK_UPDATE;
	case IPCTNL_MSG_CT_DELETE:
		return NFNLGRP_CONNTRACK_DESTROY;
	default:
		return NFNLGRP_NONE;
	}
}

int nfnlmsg_ct_parse(struct nlmsghdr *nlh, struct nfnl_ct **result)
{
	struct nfnl_ct *ct;
	struct nlattr *tb[CTA_MAX+1];
	int err;

	ct = nfnl_ct_alloc();
	if (!ct)
		return -NLE_NOMEM;

	ct->ce_msgtype = nlh->nlmsg_type;

	err = nlmsg_parse(nlh, sizeof(struct nfgenmsg), tb, CTA_MAX,
			  ct_policy);
	if (err < 0)
		goto errout;

	nfnl_ct_set_family(ct, nfnlmsg_family(nlh));

	if (tb[CTA_TUPLE_ORIG]) {
		err = ct_parse_tuple(ct, 0, tb[CTA_TUPLE_ORIG]);
		if (err < 0)
			goto errout;
	}
	if (tb[CTA_TUPLE_REPLY]) {
		err = ct_parse_tuple(ct, 1, tb[CTA_TUPLE_REPLY]);
		if (err < 0)
			goto errout;
	}

	if (tb[CTA_PROTOINFO]) {
		err = ct_parse_protoinfo(ct, tb[CTA_PROTOINFO]);
		if (err < 0)
			goto errout;
	}

	if (tb[CTA_STATUS])
		nfnl_ct_set_status(ct, ntohl(nla_get_u32(tb[CTA_STATUS])));
	if (tb[CTA_TIMEOUT])
		nfnl_ct_set_timeout(ct, ntohl(nla_get_u32(tb[CTA_TIMEOUT])));
	if (tb[CTA_MARK])
		nfnl_ct_set_mark(ct, ntohl(nla_get_u32(tb[CTA_MARK])));
	if (tb[CTA_USE])
		nfnl_ct_set_use(ct, ntohl(nla_get_u32(tb[CTA_USE])));
	if (tb[CTA_ID])
		nfnl_ct_set_id(ct, ntohl(nla_get_u32(tb[CTA_ID])));

	if (tb[CTA_COUNTERS_ORIG]) {
		err = ct_parse_counters(ct, 0, tb[CTA_COUNTERS_ORIG]);
		if (err < 0)
			goto errout;
	}

	if (tb[CTA_COUNTERS_REPLY]) {
		err = ct_parse_counters(ct, 1, tb[CTA_COUNTERS_REPLY]);
		if (err < 0)
			goto errout;
	}

	*result = ct;
	return 0;

errout:
	nfnl_ct_put(ct);
	return err;
}

static int ct_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
			 struct nlmsghdr *nlh, struct nl_parser_param *pp)
{
	struct nfnl_ct *ct;
	int err;

	if ((err = nfnlmsg_ct_parse(nlh, &ct)) < 0)
		goto errout;

	err = pp->pp_cb((struct nl_object *) ct, pp);
errout:
	nfnl_ct_put(ct);
	return err;
}

int nfnl_ct_dump_request(struct nl_sock *sk)
{
	return nfnl_send_simple(sk, NFNL_SUBSYS_CTNETLINK, IPCTNL_MSG_CT_GET,
				NLM_F_DUMP, AF_UNSPEC, 0);
}

static int ct_request_update(struct nl_cache *cache, struct nl_sock *sk)
{
	return nfnl_ct_dump_request(sk);
}

static int nfnl_ct_build_tuple(struct nl_msg *msg, const struct nfnl_ct *ct,
			       int repl)
{
	struct nlattr *tuple, *ip, *proto;
	struct nl_addr *addr;
	int family;

	family = nfnl_ct_get_family(ct);

	tuple = nla_nest_start(msg, repl ? CTA_TUPLE_REPLY : CTA_TUPLE_ORIG);
	if (!tuple)
		goto nla_put_failure;

	ip = nla_nest_start(msg, CTA_TUPLE_IP);
	if (!ip)
		goto nla_put_failure;

	addr = nfnl_ct_get_src(ct, repl);
	if (addr)
		NLA_PUT_ADDR(msg,
			     family == AF_INET ? CTA_IP_V4_SRC : CTA_IP_V6_SRC,
			     addr);

	addr = nfnl_ct_get_dst(ct, repl);
	if (addr)
		NLA_PUT_ADDR(msg,
			     family == AF_INET ? CTA_IP_V4_DST : CTA_IP_V6_DST,
			     addr);

	nla_nest_end(msg, ip);

	proto = nla_nest_start(msg, CTA_TUPLE_PROTO);
	if (!proto)
		goto nla_put_failure;

	if (nfnl_ct_test_proto(ct))
		NLA_PUT_U8(msg, CTA_PROTO_NUM, nfnl_ct_get_proto(ct));

	if (nfnl_ct_test_src_port(ct, repl))
		NLA_PUT_U16(msg, CTA_PROTO_SRC_PORT,
			htons(nfnl_ct_get_src_port(ct, repl)));

	if (nfnl_ct_test_dst_port(ct, repl))
		NLA_PUT_U16(msg, CTA_PROTO_DST_PORT,
			htons(nfnl_ct_get_dst_port(ct, repl)));

	if (nfnl_ct_test_icmp_id(ct, repl))
		NLA_PUT_U16(msg, CTA_PROTO_ICMP_ID,
			htons(nfnl_ct_get_icmp_id(ct, repl)));

	if (nfnl_ct_test_icmp_type(ct, repl))
		NLA_PUT_U8(msg, CTA_PROTO_ICMP_TYPE,
			    nfnl_ct_get_icmp_type(ct, repl));

	if (nfnl_ct_test_icmp_code(ct, repl))
		NLA_PUT_U8(msg, CTA_PROTO_ICMP_CODE,
			    nfnl_ct_get_icmp_code(ct, repl));

	nla_nest_end(msg, proto);

	nla_nest_end(msg, tuple);
	return 0;

nla_put_failure:
	return -NLE_MSGSIZE;
}

static int nfnl_ct_build_message(const struct nfnl_ct *ct, int cmd, int flags,
				 struct nl_msg **result)
{
	struct nl_msg *msg;
	int err;

	msg = nfnlmsg_alloc_simple(NFNL_SUBSYS_CTNETLINK, cmd, flags,
				   nfnl_ct_get_family(ct), 0);
	if (msg == NULL)
		return -NLE_NOMEM;

	if ((err = nfnl_ct_build_tuple(msg, ct, 0)) < 0)
		goto err_out;

	*result = msg;
	return 0;

err_out:
	nlmsg_free(msg);
	return err;
}

int nfnl_ct_build_add_request(const struct nfnl_ct *ct, int flags,
			      struct nl_msg **result)
{
	return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_NEW, flags, result);
}

int nfnl_ct_add(struct nl_sock *sk, const struct nfnl_ct *ct, int flags)
{
	struct nl_msg *msg;
	int err;

	if ((err = nfnl_ct_build_add_request(ct, flags, &msg)) < 0)
		return err;

	err = nl_send_auto_complete(sk, msg);
	nlmsg_free(msg);
	if (err < 0)
		return err;

	return wait_for_ack(sk);
}

int nfnl_ct_build_delete_request(const struct nfnl_ct *ct, int flags,
				 struct nl_msg **result)
{
	return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_DELETE, flags, result);
}

int nfnl_ct_del(struct nl_sock *sk, const struct nfnl_ct *ct, int flags)
{
	struct nl_msg *msg;
	int err;

	if ((err = nfnl_ct_build_delete_request(ct, flags, &msg)) < 0)
		return err;

	err = nl_send_auto_complete(sk, msg);
	nlmsg_free(msg);
	if (err < 0)
		return err;

	return wait_for_ack(sk);
}

int nfnl_ct_build_query_request(const struct nfnl_ct *ct, int flags,
				struct nl_msg **result)
{
	return nfnl_ct_build_message(ct, IPCTNL_MSG_CT_GET, flags, result);
}

int nfnl_ct_query(struct nl_sock *sk, const struct nfnl_ct *ct, int flags)
{
	struct nl_msg *msg;
	int err;

	if ((err = nfnl_ct_build_query_request(ct, flags, &msg)) < 0)
		return err;

	err = nl_send_auto_complete(sk, msg);
	nlmsg_free(msg);
	if (err < 0)
		return err;

	return wait_for_ack(sk);
}

/**
 * @name Cache Management
 * @{
 */

/**
 * Build a conntrack cache holding all conntrack currently in the kernel
 * @arg sk		Netlink socket.
 * @arg result		Pointer to store resulting cache.
 *
 * Allocates a new cache, initializes it properly and updates it to
 * contain all conntracks currently in the kernel.
 *
 * @return 0 on success or a negative error code.
 */
int nfnl_ct_alloc_cache(struct nl_sock *sk, struct nl_cache **result)
{
	return nl_cache_alloc_and_fill(&nfnl_ct_ops, sk, result);
}

/** @} */

/**
 * @name Conntrack Addition
 * @{
 */

/** @} */

static struct nl_af_group ct_groups[] = {
	{ AF_UNSPEC, NFNLGRP_CONNTRACK_NEW },
	{ AF_UNSPEC, NFNLGRP_CONNTRACK_UPDATE },
	{ AF_UNSPEC, NFNLGRP_CONNTRACK_DESTROY },
	{ END_OF_GROUP_LIST },
};

#define NFNLMSG_CT_TYPE(type) NFNLMSG_TYPE(NFNL_SUBSYS_CTNETLINK, (type))
static struct nl_cache_ops nfnl_ct_ops = {
	.co_name		= "netfilter/ct",
	.co_hdrsize		= NFNL_HDRLEN,
	.co_msgtypes		= {
		{ NFNLMSG_CT_TYPE(IPCTNL_MSG_CT_NEW), NL_ACT_NEW, "new" },
		{ NFNLMSG_CT_TYPE(IPCTNL_MSG_CT_GET), NL_ACT_GET, "get" },
		{ NFNLMSG_CT_TYPE(IPCTNL_MSG_CT_DELETE), NL_ACT_DEL, "del" },
		END_OF_MSGTYPES_LIST,
	},
	.co_protocol		= NETLINK_NETFILTER,
	.co_groups		= ct_groups,
	.co_request_update	= ct_request_update,
	.co_msg_parser		= ct_msg_parser,
	.co_obj_ops		= &ct_obj_ops,
};

static void __init ct_init(void)
{
	nl_cache_mngt_register(&nfnl_ct_ops);
}

static void __exit ct_exit(void)
{
	nl_cache_mngt_unregister(&nfnl_ct_ops);
}

/** @} */
