/**
 * nfexp_callback_register - register a callback
 * \param h library handler
 * \param cb callback used to process expect received
 * \param data data used by the callback, if any.
 *
 * This function register a callback to handle the expect received, 
 * in case of error -1 is returned and errno is set appropiately, otherwise
 * 0 is returned.
 * 
 * Note that the data parameter is optional, if you do not want to pass any
 * data to your callback, then use NULL.
 */
int nfexp_callback_register(struct nfct_handle *h,
			    enum nf_conntrack_msg_type type,
			    int (*cb)(enum nf_conntrack_msg_type type,
			   	      struct nf_expect *exp, 
				      void *data),
			   void *data)
{
	struct __data_container *container;

	assert(h != NULL);

	container = malloc(sizeof(struct __data_container));
	if (!container)
		return -1;
	memset(container, 0, sizeof(struct __data_container));

	h->expect_cb = cb;
	container->h = h;
	container->type = type;
	container->data = data;

	h->nfnl_cb_exp.call = __callback;
	h->nfnl_cb_exp.data = container;
	h->nfnl_cb_exp.attr_count = CTA_EXPECT_MAX;

	nfnl_callback_register(h->nfnlssh_exp, 
			       IPCTNL_MSG_EXP_NEW,
			       &h->nfnl_cb_exp);

	nfnl_callback_register(h->nfnlssh_exp,
			       IPCTNL_MSG_EXP_DELETE,
			       &h->nfnl_cb_exp);

	return 0;
}
struct nflog_handle *nflog_open_nfnl(struct nfnl_handle *nfnlh)
{
	struct nflog_handle *h;
	int err;

	h = malloc(sizeof(*h));
	if (!h)
		return NULL;

	memset(h, 0, sizeof(*h));
	h->nfnlh = nfnlh;

	h->nfnlssh = nfnl_subsys_open(h->nfnlh, NFNL_SUBSYS_ULOG, 
				      NFULNL_MSG_MAX, 0);
	if (!h->nfnlssh) {
		/* FIXME: nflog_errno */
		goto out_free;
	}

	pkt_cb.data = h;
	err = nfnl_callback_register(h->nfnlssh, NFULNL_MSG_PACKET, &pkt_cb);
	if (err < 0) {
		nflog_errno = err;
		goto out_close;
	}

	return h;
out_close:
	nfnl_close(h->nfnlh);
out_free:
	free(h);
	return NULL;
}