/*
 * (C) 2012 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 code has been sponsored by Vyatta Inc. <http://www.vyatta.com>
 */
#include "internal.h"

#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>	/* for htonl */

#include <libmnl/libmnl.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_cthelper.h>

#include <libnetfilter_cthelper/libnetfilter_cthelper.h>

/**
 * \mainpage
 *
 * libnetfilter_cthelper is the userspace library that provides a programming
 * interface (API) to user-space connection tracking helpers. Basically, you
 * can find here a set of helper functions that you can use together with
 * libmnl.
 *
 * libnetfilter_cthelper homepage is:
 *      http://netfilter.org/projects/libnetfilter_cthelper/
 *
 * \section Dependencies
 * libnetfilter_cthelper requires libmnl >= 1.0.0 and the Linux kernel that
 * includes the nfnetlink_cthelper subsystem (i.e. 3.3.x or any later).
 *
 * \section Main Features
 *  - register new user-space connection tracking helpers.
 *  - unregister user-space connection tracking helpers.
 *  - list existing registered user-space connection tracking helpers.
 *
 * \section Git Tree
 * The current development version of libnetfilter_cthelper can be accessed at
 * https://git.netfilter.org/cgi-bin/gitweb.cgi?p=libnetfilter_cthelper.git
 *
 * \section using Using libnetfilter_cthelper
 * To write your own program using libnetfilter_cthelper, you should start by
 * reading the documentation for libmnl to understand basic operation with
 * Netlink sockets. Moreover, you may want to check the examples available
 * under examples/ in the libnetfilter_cthelper source code. You can compile
 * these examples by invoking `make check'.
 *
 * \section Authors
 * libnetfilter_cthelper has been written by Pablo Neira Ayuso.
 */

/* XXX */
#ifndef NF_CT_HELPER_NAME_MAX
#define NF_CT_HELPER_NAME_MAX 16
#endif

#ifndef NF_CT_HELPER_CLASS_MAX
#define NF_CT_HELPER_CLASS_MAX 4
#endif

struct nfct_helper_policy {
	char		name[NF_CT_HELPER_NAME_MAX];
	uint32_t	expect_timeout;
	uint32_t	expect_max;
	uint32_t	bitset;
};

struct nfct_helper {
	char		name[NF_CT_HELPER_NAME_MAX];
	uint32_t	priv_data_len;
	uint32_t	queue_num;
	uint32_t	status;
	struct {
			uint16_t	l3num;
			uint8_t		l4num;
			uint16_t	port;
	} tuple;
	struct nfct_helper_policy *expect_policy[NF_CT_HELPER_CLASS_MAX];
	uint32_t	policy_num;

	uint32_t	bitset;
};

/**
 * \defgroup nfct_helper Accounting object handling
 * @{
 */

/**
 * nfct_helper_alloc - allocate a new helper object
 *
 * In case of success, this function returns a valid pointer, otherwise NULL
 * s returned and errno is appropriately set.
 */
struct nfct_helper __EXPORTED *nfct_helper_alloc(void)
{
	return calloc(1, sizeof(struct nfct_helper));
}

/**
 * nfct_helper_free - release one helper object
 * \param nfct_helper pointer to the helper object
 */
void __EXPORTED nfct_helper_free(struct nfct_helper *h)
{
	int i;

	free(h);
	for (i=0; i<NF_CT_HELPER_CLASS_MAX; i++) {
		if (h->expect_policy[i])
			free(h->expect_policy[i]);
	}
}

/**
 * nfct_helper_policy_alloc - allocate a new helper policy object
 *
 * In case of success, this function returns a valid pointer, otherwise NULL
 * s returned and errno is appropriately set.
 */
struct nfct_helper_policy __EXPORTED *nfct_helper_policy_alloc(void)
{
	return calloc(1, sizeof(struct nfct_helper_policy));
}

/**
 * nfct_helper_free - release one helper policy object
 * \param nfct_helper pointer to the helper object
 */
void __EXPORTED nfct_helper_policy_free(struct nfct_helper_policy *p)
{
	free(p);
}

/**
 * nfct_helper_policy_attr_set - set one attribute of the helper object
 * \param nfct_helper pointer to the helper object
 * \param type attribute type you want to set
 * \param data pointer to data that will be used to set this attribute
 */
void __EXPORTED
nfct_helper_policy_attr_set(struct nfct_helper_policy *p,
			    enum nfct_helper_policy_attr_type type,
			    const void *data)
{
	switch(type) {
	case NFCTH_ATTR_POLICY_NAME:
		strncpy(p->name, data, NF_CT_HELPER_NAME_MAX);
		p->name[NF_CT_HELPER_NAME_MAX-1] = '\0';
		p->bitset |= (1 << NFCTH_ATTR_POLICY_NAME);
		break;
	case NFCTH_ATTR_POLICY_TIMEOUT:
		p->expect_timeout = *((uint32_t *) data);
		p->bitset |= (1 << NFCTH_ATTR_POLICY_TIMEOUT);
		break;
	case NFCTH_ATTR_POLICY_MAX:
		p->expect_max = *((uint32_t *) data);
		p->bitset |= (1 << NFCTH_ATTR_POLICY_MAX);
		break;
	}
}

/**
 * nfct_helper_attr_set_str - set one attribute the helper object
 * \param nfct_helper pointer to the helper object
 * \param type attribute type you want to set
 * \param name string that will be used to set this attribute
 */
void __EXPORTED
nfct_helper_policy_attr_set_str(struct nfct_helper_policy *p,
				enum nfct_helper_policy_attr_type type,
				const char *name)
{
	nfct_helper_policy_attr_set(p, type, name);
}

void __EXPORTED
nfct_helper_policy_attr_set_u32(struct nfct_helper_policy *p,
				enum nfct_helper_policy_attr_type type,
				uint32_t value)
{
	nfct_helper_policy_attr_set(p, type, &value);
}

/**
 * nfct_helper_attr_set - set one attribute of the helper object
 * \param nfct_helper pointer to the helper object
 * \param type attribute type you want to set
 * \param data pointer to data that will be used to set this attribute
 */
void __EXPORTED
nfct_helper_attr_set(struct nfct_helper *h,
		     enum nfct_helper_attr_type type, const void *data)
{
	switch(type) {
	case NFCTH_ATTR_NAME:
		strncpy(h->name, data, NF_CT_HELPER_NAME_MAX);
		h->name[NF_CT_HELPER_NAME_MAX-1] = '\0';
		h->bitset |= (1 << NFCTH_ATTR_NAME);
		break;
	case NFCTH_ATTR_QUEUE_NUM:
		h->queue_num = *((uint32_t *) data);
		h->bitset |= (1 << NFCTH_ATTR_QUEUE_NUM);
		break;
	case NFCTH_ATTR_PROTO_L3NUM:
		h->tuple.l3num = *((uint16_t *) data);
		h->bitset |= (1 << NFCTH_ATTR_PROTO_L3NUM);
		break;
	case NFCTH_ATTR_PROTO_L4NUM:
		h->tuple.l4num = *((uint8_t *) data);
		h->bitset |= (1 << NFCTH_ATTR_PROTO_L4NUM);
		break;
	case NFCTH_ATTR_PRIV_DATA_LEN:
		h->priv_data_len = *((uint32_t *) data);
		h->bitset |= (1 << NFCTH_ATTR_PRIV_DATA_LEN);
		break;
	case NFCTH_ATTR_POLICY1:
		h->expect_policy[0] = (struct nfct_helper_policy *)data;
		h->bitset |= (1 << NFCTH_ATTR_POLICY1);
		break;
	case NFCTH_ATTR_POLICY2:
		h->expect_policy[1] = (struct nfct_helper_policy *)data;
		h->bitset |= (1 << NFCTH_ATTR_POLICY2);
		break;
	case NFCTH_ATTR_POLICY3:
		h->expect_policy[2] = (struct nfct_helper_policy *)data;
		h->bitset |= (1 << NFCTH_ATTR_POLICY3);
		break;
	case NFCTH_ATTR_POLICY4:
		h->expect_policy[3] = (struct nfct_helper_policy *)data;
		h->bitset |= (1 << NFCTH_ATTR_POLICY4);
		break;
	case NFCTH_ATTR_STATUS:
		h->status = *((uint32_t *) data);
		h->bitset |= (1 << NFCTH_ATTR_STATUS);
		break;
	}
}

/**
 * nfct_helper_attr_set_str - set one attribute the helper object
 * \param nfct_helper pointer to the helper object
 * \param type attribute type you want to set
 * \param name string that will be used to set this attribute
 */
void __EXPORTED
nfct_helper_attr_set_str(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type,
		    const char *name)
{
	nfct_helper_attr_set(nfct_helper, type, name);
}

void __EXPORTED
nfct_helper_attr_set_u8(struct nfct_helper *nfct_helper,
			 enum nfct_helper_attr_type type, uint8_t value)
{
	nfct_helper_attr_set(nfct_helper, type, &value);
}

void __EXPORTED
nfct_helper_attr_set_u16(struct nfct_helper *nfct_helper,
			 enum nfct_helper_attr_type type, uint16_t value)
{
	nfct_helper_attr_set(nfct_helper, type, &value);
}

void __EXPORTED
nfct_helper_attr_set_u32(struct nfct_helper *nfct_helper,
			 enum nfct_helper_attr_type type, uint32_t value)
{
	nfct_helper_attr_set(nfct_helper, type, &value);
}

/**
 * nfct_helper_attr_unset - unset one attribute the helper object
 * \param nfct_helper pointer to the helper object
 * \param type attribute type you want to set
 */
void __EXPORTED
nfct_helper_attr_unset(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type)
{
	switch(type) {
	case NFCTH_ATTR_NAME:
		nfct_helper->bitset &= ~(1 << NFCTH_ATTR_NAME);
		break;
	default:
		/* XXX */
		break;
	}
}

/**
 * nfct_helper_attr_get - get one attribute the helper object
 * \param nfct_helper pointer to the helper object
 * \param type attribute type you want to set
 *
 * This function returns a valid pointer to the attribute data. If a
 * unsupported attribute is used, this returns NULL.
 */
const void __EXPORTED *
nfct_helper_attr_get(struct nfct_helper *helper,
		     enum nfct_helper_attr_type type)
{
	const void *ret = NULL;

	switch(type) {
	case NFCTH_ATTR_NAME:
		ret = helper->name;
		break;
	case NFCTH_ATTR_QUEUE_NUM:
		ret = &helper->queue_num;
		break;
	case NFCTH_ATTR_PROTO_L3NUM:
		ret = &helper->tuple.l3num;
		break;
	case NFCTH_ATTR_PROTO_L4NUM:
		ret = &helper->tuple.l4num;
		break;
	case NFCTH_ATTR_PRIV_DATA_LEN:
		ret = &helper->priv_data_len;
		break;
	case NFCTH_ATTR_POLICY1:
		ret = helper->expect_policy[0];
		break;
	case NFCTH_ATTR_POLICY2:
		ret = helper->expect_policy[1];
		break;
	case NFCTH_ATTR_POLICY3:
		ret = helper->expect_policy[2];
		break;
	case NFCTH_ATTR_POLICY4:
		ret = helper->expect_policy[3];
		break;
	case NFCTH_ATTR_STATUS:
		ret = &helper->status;
		break;
	default:
		ret = NULL;
	}
	return ret;
}

/**
 * nfct_helper_attr_get_str - get one attribute the helper object
 * \param nfct_helper pointer to the helper object
 * \param type attribute type you want to set
 *
 * This function returns a valid pointer to the beginning of the string.
 * If the attribute is unsupported, this returns NULL.
 */
const char __EXPORTED *
nfct_helper_attr_get_str(struct nfct_helper *nfct_helper,
			 enum nfct_helper_attr_type type)
{
	return (const char *)nfct_helper_attr_get(nfct_helper, type);
}

/**
 * nfct_helper_attr_get_u8 - get one attribute the helper object
 * \param nfct_helper pointer to the helper object
 * \param type attribute type you want to set
 *
 * This function returns a unsigned 8-bits integer. If the attribute is
 * unsupported, this returns NULL.
 */
uint8_t __EXPORTED
nfct_helper_attr_get_u8(struct nfct_helper *nfct_helper,
			enum nfct_helper_attr_type type)
{
	return *((uint8_t *)nfct_helper_attr_get(nfct_helper, type));
}

/**
 * nfct_helper_attr_get_u16 - get one attribute the helper object
 * \param nfct_helper pointer to the helper object
 * \param type attribute type you want to set
 *
 * This function returns a unsigned 16-bits integer. If the attribute is
 * unsupported, this returns NULL.
 */
uint16_t __EXPORTED
nfct_helper_attr_get_u16(struct nfct_helper *nfct_helper,
			 enum nfct_helper_attr_type type)
{
	return *((uint16_t *)nfct_helper_attr_get(nfct_helper, type));
}

/**
 * nfct_helper_attr_get_u32 - get one attribute the helper object
 * \param nfct_helper pointer to the helper object
 * \param type attribute type you want to set
 *
 * This function returns a unsigned 32-bits integer. If the attribute is
 * unsupported, this returns NULL.
 */
uint32_t __EXPORTED
nfct_helper_attr_get_u32(struct nfct_helper *nfct_helper,
			 enum nfct_helper_attr_type type)
{
	return *((uint32_t *)nfct_helper_attr_get(nfct_helper, type));
}

/**
 * nfct_helper_snprintf - print helper object into one buffer
 * \param buf: pointer to buffer that is used to print the object
 * \param size: size of the buffer (or remaining room in it).
 * \param nfct_helper: pointer to a valid helper object.
 * \param flags: output flags (NFCTH_SNPRINTF_F_FULL).
 *
 * This function returns -1 in case that some mandatory attributes are
 * missing. On sucess, it returns 0.
 */
int __EXPORTED
nfct_helper_snprintf(char *buf, size_t size,
		     struct nfct_helper *helper,
		     unsigned int type, unsigned int flags)
{
	int ret;

	ret = snprintf(buf, size, "{\n"
				  "\t.name = %s,\n"
				  "\t.queuenum = %u,\n"
				  "\t.l3protonum = %u,\n"
				  "\t.l4protonum = %u,\n"
				  "\t.priv_data_len = %u,\n"
				  "\t.status = %s,\n};",
		nfct_helper_attr_get_str(helper, NFCTH_ATTR_NAME),
		nfct_helper_attr_get_u32(helper, NFCTH_ATTR_QUEUE_NUM),
		nfct_helper_attr_get_u16(helper, NFCTH_ATTR_PROTO_L3NUM),
		nfct_helper_attr_get_u8(helper, NFCTH_ATTR_PROTO_L4NUM),
		nfct_helper_attr_get_u32(helper, NFCTH_ATTR_PRIV_DATA_LEN),
		nfct_helper_attr_get_u32(helper, NFCTH_ATTR_STATUS) ?
			"enabled" : "disabled");

	return ret;
}

/**
 * @}
 */

/**
 * \defgroup nlmsg Netlink message helper functions
 * @{
 */

/**
 * nfct_helper_nlmsg_build_hdr - build netlink message header for nfct_helper subsystem
 * \param buf: buffer where this function outputs the netlink message.
 * \param cmd: nfct_helper nfnetlink command.
 * \param flags: netlink flags.
 * \param seq: sequence number for this message.
 *
 * Possible commands:
 * - NFNL_MSG_ACCT_NEW: new helper object.
 * - NFNL_MSG_ACCT_GET: get helper object.
 * - NFNL_MSG_ACCT_GET_CTRZERO: get helper object and atomically reset.
 *
 * Examples:
 * - Command NFNL_MSG_ACCT_NEW + flags NLM_F_CREATE | NLM_F_ACK, to create
 *   one new helper object (if it does not already exists). You receive
 *   one acknoledgment in any case with the result of the operation.
 *
 * - Command NFNL_MSG_ACCT_GET + flags NLM_F_DUMP, to obtain all the
 *   existing helper objects.
 *
 * - Command NFNL_MSG_ACCT_DEL, to delete all existing unused objects.
 *
 * - Command NFNL_MSG_ACCT_DEL, to delete one specific nfct_helper object (if
 *   unused, otherwise you hit EBUSY).
 */
struct nlmsghdr __EXPORTED *
nfct_helper_nlmsg_build_hdr(char *buf, uint8_t cmd,
			    uint16_t flags, uint32_t seq)
{
	struct nlmsghdr *nlh;
	struct nfgenmsg *nfh;

	nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type = (NFNL_SUBSYS_CTHELPER << 8) | cmd;
	nlh->nlmsg_flags = NLM_F_REQUEST | flags;
	nlh->nlmsg_seq = seq;

	nfh = mnl_nlmsg_put_extra_header(nlh, sizeof(struct nfgenmsg));
	nfh->nfgen_family = AF_UNSPEC;
	nfh->version = NFNETLINK_V0;
	nfh->res_id = 0;

	return nlh;
}

static void
nfct_helper_nlmsg_build_policy(struct nlmsghdr *nlh,
				struct nfct_helper_policy *p)
{
	struct nlattr *nest;

	nest = mnl_attr_nest_start(nlh, NFCTH_POLICY_SET);
	mnl_attr_put_strz(nlh, NFCTH_POLICY_NAME, p->name);
	mnl_attr_put_u32(nlh, NFCTH_POLICY_EXPECT_MAX, htonl(p->expect_max));
	mnl_attr_put_u32(nlh, NFCTH_POLICY_EXPECT_TIMEOUT,
			htonl(p->expect_timeout));
	mnl_attr_nest_end(nlh, nest);
}

/**
 * nfct_helper_nlmsg_build_payload - build payload from helper object
 * \param nlh: netlink message that you want to use to add the payload.
 * \param nfct_helper: pointer to a helper object
 */
void __EXPORTED
nfct_helper_nlmsg_build_payload(struct nlmsghdr *nlh, struct nfct_helper *h)
{
	struct nlattr *nest;


	if (h->bitset & (1 << NFCTH_ATTR_NAME))
		mnl_attr_put_strz(nlh, NFCTH_NAME, h->name);

	if (h->bitset & (1 << NFCTH_ATTR_QUEUE_NUM))
		mnl_attr_put_u32(nlh, NFCTH_QUEUE_NUM, htonl(h->queue_num));

	if (h->bitset & (1 << NFCTH_ATTR_PRIV_DATA_LEN)) {
		mnl_attr_put_u32(nlh, NFCTH_PRIV_DATA_LEN,
					htonl(h->priv_data_len));
	}

	if (h->bitset & (1 << NFCTH_ATTR_PROTO_L3NUM) ||
	    h->bitset & (1 << NFCTH_ATTR_PROTO_L4NUM)) {
		nest = mnl_attr_nest_start(nlh, NFCTH_TUPLE);
		mnl_attr_put_u16(nlh, NFCTH_TUPLE_L3PROTONUM,
					htons(h->tuple.l3num));
		mnl_attr_put_u8(nlh, NFCTH_TUPLE_L4PROTONUM, h->tuple.l4num);
		mnl_attr_nest_end(nlh, nest);
	}

	if (h->bitset & (1 << NFCTH_ATTR_POLICY1) ||
	    h->bitset & (1 << NFCTH_ATTR_POLICY2) ||
	    h->bitset & (1 << NFCTH_ATTR_POLICY3) ||
	    h->bitset & (1 << NFCTH_ATTR_POLICY4)) {
		nest = mnl_attr_nest_start(nlh, NFCTH_POLICY);
		int policy_set_num = 0;

		if (h->bitset & (1 << NFCTH_ATTR_POLICY1)) {
			nfct_helper_nlmsg_build_policy(nlh,
							h->expect_policy[0]);
			policy_set_num++;
		}
		if (h->bitset & (1 << NFCTH_ATTR_POLICY2)) {
			nfct_helper_nlmsg_build_policy(nlh,
							h->expect_policy[1]);
			policy_set_num++;
		}
		if (h->bitset & (1 << NFCTH_ATTR_POLICY3)) {
			nfct_helper_nlmsg_build_policy(nlh,
							h->expect_policy[2]);
			policy_set_num++;
		}
		if (h->bitset & (1 << NFCTH_ATTR_POLICY4)) {
			nfct_helper_nlmsg_build_policy(nlh,
							h->expect_policy[3]);
			policy_set_num++;
		}

		mnl_attr_put_u32(nlh, NFCTH_POLICY_SET_NUM,
					htonl(policy_set_num));

		mnl_attr_nest_end(nlh, nest);
	}

	if (h->bitset & (1 << NFCTH_ATTR_STATUS))
		mnl_attr_put_u32(nlh, NFCTH_STATUS, ntohl(h->status));
}

static int
nfct_helper_nlmsg_parse_tuple_cb(const struct nlattr *attr, void *data)
{
	const struct nlattr **tb = data;
	int type = mnl_attr_get_type(attr);

	if (mnl_attr_type_valid(attr, NFCTH_TUPLE_MAX) < 0)
		return MNL_CB_OK;

	switch(type) {
	case NFCTH_TUPLE_L3PROTONUM:
		if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0) {
			perror("mnl_attr_validate");
			return MNL_CB_ERROR;
		}
		break;
	case NFCTH_TUPLE_L4PROTONUM:
		if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0) {
			perror("mnl_attr_validate");
			return MNL_CB_ERROR;
		}
		break;
	default:
		break;
	}
	tb[type] = attr;
	return MNL_CB_OK;
}

static void
nfct_helper_nlmsg_parse_tuple(const struct nlattr *attr,
			      struct nfct_helper *helper)
{
	struct nlattr *tb[NFCTH_TUPLE_MAX+1] = {};

	mnl_attr_parse_nested(attr, nfct_helper_nlmsg_parse_tuple_cb, tb);
	if (tb[NFCTH_TUPLE_L3PROTONUM]) {
		nfct_helper_attr_set_u16(helper, NFCTH_ATTR_PROTO_L3NUM,
			ntohs(mnl_attr_get_u16(tb[NFCTH_TUPLE_L3PROTONUM])));
	}
	if (tb[NFCTH_TUPLE_L4PROTONUM]) {
		nfct_helper_attr_set_u8(helper, NFCTH_ATTR_PROTO_L4NUM,
			mnl_attr_get_u8(tb[NFCTH_TUPLE_L4PROTONUM]));
	}
}

static int
nfct_helper_nlmsg_parse_policy_cb(const struct nlattr *attr, void *data)
{
	const struct nlattr **tb = data;
	int type = mnl_attr_get_type(attr);

	if (mnl_attr_type_valid(attr, NFCTH_POLICY_MAX) < 0)
		return MNL_CB_OK;

	switch(type) {
	case NFCTH_POLICY_NAME:
		if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
			perror("mnl_attr_validate");
			return MNL_CB_ERROR;
		}
		break;
	case NFCTH_POLICY_EXPECT_MAX:
		if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
			perror("mnl_attr_validate");
			return MNL_CB_ERROR;
		}
		break;
	case NFCTH_POLICY_EXPECT_TIMEOUT:
		if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
			perror("mnl_attr_validate");
			return MNL_CB_ERROR;
		}
		break;
	default:
		break;
	}
	tb[type] = attr;
	return MNL_CB_OK;
}

static int
nfct_helper_nlmsg_parse_policy_set_cb(const struct nlattr *attr, void *data)
{
	const struct nlattr **tb = data;
	int type = mnl_attr_get_type(attr);

	if (mnl_attr_type_valid(attr, NFCTH_POLICY_SET_MAX) < 0)
		return MNL_CB_OK;

	switch(type) {
	case NFCTH_POLICY_SET_NUM:
		if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
			perror("mnl_attr_validate");
			return MNL_CB_ERROR;
		}
		break;
	default:
		/* NFCTH_POLICY_SET1, 2, 3 and 4. */
		break;
	}
	tb[type] = attr;
	return MNL_CB_OK;
}

static void
nfct_helper_nlmsg_parse_policy(const struct nlattr *attr,
			       struct nfct_helper *helper)
{
	struct nlattr *tb[NFCTH_POLICY_MAX+1] = {};
	struct nfct_helper_policy *p;

	p = nfct_helper_policy_alloc();
	if (p == NULL)
		return;

	mnl_attr_parse_nested(attr, nfct_helper_nlmsg_parse_policy_cb, tb);
	if (tb[NFCTH_POLICY_NAME]) {
		nfct_helper_policy_attr_set_str(p, NFCTH_ATTR_POLICY_NAME,
			mnl_attr_get_str(tb[NFCTH_POLICY_NAME]));
	}
	if (tb[NFCTH_POLICY_EXPECT_MAX]) {
		nfct_helper_policy_attr_set_u32(p, NFCTH_ATTR_POLICY_MAX,
			ntohl(mnl_attr_get_u32(tb[NFCTH_POLICY_EXPECT_MAX])));
	}
	if (tb[NFCTH_POLICY_EXPECT_TIMEOUT]) {
		nfct_helper_policy_attr_set_u32(p, NFCTH_ATTR_POLICY_TIMEOUT,
			ntohl(mnl_attr_get_u32(tb[NFCTH_POLICY_EXPECT_TIMEOUT])));
	}

	helper->expect_policy[helper->policy_num++] = p;
}

static void
nfct_helper_nlmsg_parse_policy_set(const struct nlattr *attr,
				   struct nfct_helper *helper)
{
	struct nlattr *tb[NFCTH_POLICY_SET_MAX+1] = {};
	int i;

	mnl_attr_parse_nested(attr, nfct_helper_nlmsg_parse_policy_set_cb, tb);
	if (tb[NFCTH_POLICY_SET_NUM]) {
		helper->policy_num =
			ntohl(mnl_attr_get_u32(tb[NFCTH_POLICY_SET_NUM]));
	}
	for (i=0; i<helper->policy_num; i++) {
		if (tb[NFCTH_POLICY_SET+i]) {
			nfct_helper_nlmsg_parse_policy(tb[NFCTH_POLICY_SET+i],
						       helper);
		}
	}
}

static int
nfct_helper_nlmsg_parse_attr_cb(const struct nlattr *attr, void *data)
{
	const struct nlattr **tb = data;
	int type = mnl_attr_get_type(attr);

	if (mnl_attr_type_valid(attr, NFCTH_MAX) < 0)
		return MNL_CB_OK;

	switch(type) {
	case NFCTH_NAME:
		if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
			perror("mnl_attr_validate");
			return MNL_CB_ERROR;
		}
		break;
	case NFCTH_QUEUE_NUM:
		if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
			perror("mnl_attr_validate");
			return MNL_CB_ERROR;
		}
		break;
	case NFCTH_TUPLE:
		if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
			perror("mnl_attr_validate");
			return MNL_CB_ERROR;
		}
		break;
	case NFCTH_POLICY:
		if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
			perror("mnl_attr_validate");
			return MNL_CB_ERROR;
		}
		break;
	}
	tb[type] = attr;
	return MNL_CB_OK;
}

/**
 * nfct_helper_nlmsg_parse_payload - set helper object attributes from message
 * \param nlh: netlink message that you want to use to add the payload.
 * \param nfct_helper: pointer to a helper object
 *
 * This function returns -1 in case that some mandatory attributes are
 * missing. On sucess, it returns 0.
 */
int __EXPORTED
nfct_helper_nlmsg_parse_payload(const struct nlmsghdr *nlh,
				struct nfct_helper *h)
{
	struct nlattr *tb[NFCTH_MAX+1] = {};
	struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);

	mnl_attr_parse(nlh, sizeof(*nfg), nfct_helper_nlmsg_parse_attr_cb, tb);
	if (!tb[NFCTH_NAME] || !tb[NFCTH_QUEUE_NUM] ||
	    !tb[NFCTH_TUPLE] || !tb[NFCTH_POLICY] || !tb[NFCTH_STATUS])
		return -1;

	if (tb[NFCTH_NAME]) {
		nfct_helper_attr_set_str(h, NFCTH_ATTR_NAME,
				 mnl_attr_get_str(tb[NFCTH_NAME]));
	}
	if (tb[NFCTH_ATTR_QUEUE_NUM]) {
		nfct_helper_attr_set_u32(h, NFCTH_ATTR_QUEUE_NUM,
				 ntohl(mnl_attr_get_u32(tb[NFCTH_QUEUE_NUM])));
	}
	if (tb[NFCTH_TUPLE])
		nfct_helper_nlmsg_parse_tuple(tb[NFCTH_TUPLE], h);

	if (tb[NFCTH_POLICY])
		nfct_helper_nlmsg_parse_policy_set(tb[NFCTH_POLICY], h);

	if (tb[NFCTH_PRIV_DATA_LEN]) {
		nfct_helper_attr_set_u32(h, NFCTH_ATTR_PRIV_DATA_LEN,
			ntohl(mnl_attr_get_u32(tb[NFCTH_PRIV_DATA_LEN])));
	}

	if (tb[NFCTH_STATUS]) {
		nfct_helper_attr_set_u32(h, NFCTH_ATTR_STATUS,
				 ntohl(mnl_attr_get_u32(tb[NFCTH_STATUS])));
	}
	return 0;
}

/**
 * @}
 */
