18a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/*
28a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * (C) 2005-2011 by Pablo Neira Ayuso <pablo@netfilter.org>
38a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
48a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This program is free software; you can redistribute it and/or modify it
58a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * under the terms of the GNU General Public License as published by
68a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * the Free Software Foundation; either version 2 of the License, or
78a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * (at your option) any later version.
88a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
98a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar#include <stdlib.h>
118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar#include <string.h> /* for memset */
128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar#include <errno.h>
138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar#include <assert.h>
148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar#include "internal/internal.h"
168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \defgroup exp Expect object handling
198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @{
208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_new - allocate a new expectation
248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * In case of success, this function returns a valid pointer to a memory blob,
268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * otherwise NULL is returned and errno is set appropiately.
278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
288a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstruct nf_expect *nfexp_new(void)
298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	struct nf_expect *exp;
318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	exp = malloc(sizeof(struct nf_expect));
338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (!exp)
348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return NULL;
358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	memset(exp, 0, sizeof(struct nf_expect));
378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return exp;
398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_destroy - release an expectation object
438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param exp pointer to the expectation object
448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
458a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfexp_destroy(struct nf_expect *exp)
468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(exp != NULL);
488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	free(exp);
498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	exp = NULL; /* bugtrap */
508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_sizeof - return the size in bytes of a certain expect object
548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param exp pointer to the expect object
558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
568a44513648da0c5f5551f96b329cf56b66f5b303pkanwarsize_t nfexp_sizeof(const struct nf_expect *exp)
578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(exp != NULL);
598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return sizeof(*exp);
608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_maxsize - return the maximum size in bytes of a expect object
648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Use this function if you want to allocate a expect object in the stack
668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * instead of the heap. For example:
678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
688a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * char buf[nfexp_maxsize()];
698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * struct nf_expect *exp = (struct nf_expect *) buf;
708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * memset(exp, 0, nfexp_maxsize());
718a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
728a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Note: As for now this function returns the same size that nfexp_sizeof(exp)
738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * does although _this could change in the future_. Therefore, do not assume
748a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * that nfexp_sizeof(exp) == nfexp_maxsize().
758a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
768a44513648da0c5f5551f96b329cf56b66f5b303pkanwarsize_t nfexp_maxsize(void)
778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return sizeof(struct nf_expect);
798a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_clone - clone a expectation object
838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param exp pointer to a valid expectation object
848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On error, NULL is returned and errno is appropiately set. Otherwise,
868a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * a valid pointer to the clone expect is returned.
878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
888a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstruct nf_expect *nfexp_clone(const struct nf_expect *exp)
898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	struct nf_expect *clone;
918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
928a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(exp != NULL);
938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
948a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if ((clone = nfexp_new()) == NULL)
958a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return NULL;
968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	memcpy(clone, exp, sizeof(*exp));
978a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
988a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return clone;
998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
1008a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
1028a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_cmp - compare two expectation objects
1038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param exp1 pointer to a valid expectation object
1048a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param exp2 pointer to a valid expectation object
1058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param flags flags
1068a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
1078a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This function only compare attribute set in both objects, by default
1088a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * the comparison is not strict, ie. if a certain attribute is not set in one
1098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * of the objects, then such attribute is not used in the comparison.
1108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * If you want more strict comparisons, you can use the appropriate flags
1118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * to modify this behaviour (see NFCT_CMP_STRICT and NFCT_CMP_MASK).
1128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
1138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * The available flags are:
1148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *      - NFCT_CMP_STRICT: the compared objects must have the same attributes
1158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *      and the same values, otherwise it returns that the objects are
1168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *      different.
1178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *      - NFCT_CMP_MASK: the first object is used as mask, this means that
1188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *      if an attribute is present in exp1 but not in exp2, this function
1198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *      returns that the objects are different.
1208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
1218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Other existing flags that are used by nfct_cmp() are ignored.
1228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
1238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * If both conntrack object are equal, this function returns 1, otherwise
1248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 0 is returned.
1258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
1268a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfexp_cmp(const struct nf_expect *exp1, const struct nf_expect *exp2,
1278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	      unsigned int flags)
1288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
1298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar        assert(exp1 != NULL);
1308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar        assert(exp2 != NULL);
1318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar        return __cmp_expect(exp1, exp2, flags);
1338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
1348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
1368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @}
1378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
1388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
1408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \defgroup LibrarySetup Library setup
1418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @{
1428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
1438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
1458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_callback_register - register a callback
1468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param h library handler
1478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param cb callback used to process expect received
1488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param data data used by the callback, if any.
1498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
1508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This function register a callback to handle the expect received,
1518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * in case of error -1 is returned and errno is set appropiately, otherwise
1528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 0 is returned.
1538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
1548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Note that the data parameter is optional, if you do not want to pass any
1558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * data to your callback, then use NULL.
1568a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
1578a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfexp_callback_register(struct nfct_handle *h,
1588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			    enum nf_conntrack_msg_type type,
1598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			    int (*cb)(enum nf_conntrack_msg_type type,
1608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			   	      struct nf_expect *exp,
1618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar				      void *data),
1628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			   void *data)
1638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
1648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	struct __data_container *container;
1658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(h != NULL);
1678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1688a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	container = malloc(sizeof(struct __data_container));
1698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (!container)
1708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return -1;
1718a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	memset(container, 0, sizeof(struct __data_container));
1728a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->expect_cb = cb;
1748a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	container->h = h;
1758a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	container->type = type;
1768a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	container->data = data;
1778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->nfnl_cb_exp.call = __callback;
1798a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->nfnl_cb_exp.data = container;
1808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->nfnl_cb_exp.attr_count = CTA_EXPECT_MAX;
1818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfnl_callback_register(h->nfnlssh_exp,
1838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			       IPCTNL_MSG_EXP_NEW,
1848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			       &h->nfnl_cb_exp);
1858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1868a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfnl_callback_register(h->nfnlssh_exp,
1878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			       IPCTNL_MSG_EXP_DELETE,
1888a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			       &h->nfnl_cb_exp);
1898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return 0;
1918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
1928a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
1938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
1948a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_callback_unregister - unregister a callback
1958a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param h library handler
1968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
1978a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfexp_callback_unregister(struct nfct_handle *h)
1988a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
1998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(h != NULL);
2008a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfnl_callback_unregister(h->nfnlssh_exp, IPCTNL_MSG_EXP_NEW);
2028a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfnl_callback_unregister(h->nfnlssh_exp, IPCTNL_MSG_EXP_DELETE);
2038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2048a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->expect_cb = NULL;
2058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	free(h->nfnl_cb_exp.data);
2068a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2078a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->nfnl_cb_exp.call = NULL;
2088a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->nfnl_cb_exp.data = NULL;
2098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->nfnl_cb_exp.attr_count = 0;
2108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
2118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
2138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_callback_register2 - register a callback
2148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param h library handler
2158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param cb callback used to process expect received
2168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param data data used by the callback, if any.
2178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
2188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This function register a callback to handle the expect received,
2198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * in case of error -1 is returned and errno is set appropiately, otherwise
2208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 0 is returned.
2218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
2228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Note that the data parameter is optional, if you do not want to pass any
2238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * data to your callback, then use NULL.
2248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
2258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * NOTICE: The difference with nfexp_callback_register() is that this function
2268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * uses the new callback interface that includes the Netlink header.
2278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
2288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * WARNING: Don't mix nfexp_callback_register() and nfexp_callback_register2()
2298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * calls, use only once at a time.
2308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
2318a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfexp_callback_register2(struct nfct_handle *h,
2328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			     enum nf_conntrack_msg_type type,
2338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			     int (*cb)(const struct nlmsghdr *nlh,
2348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			     	       enum nf_conntrack_msg_type type,
2358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			   	       struct nf_expect *exp,
2368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar				       void *data),
2378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			     void *data)
2388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
2398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	struct __data_container *container;
2408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(h != NULL);
2428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	container = malloc(sizeof(struct __data_container));
2448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (!container)
2458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return -1;
2468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	memset(container, 0, sizeof(struct __data_container));
2478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->expect_cb2 = cb;
2498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	container->h = h;
2508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	container->type = type;
2518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	container->data = data;
2528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->nfnl_cb_exp.call = __callback;
2548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->nfnl_cb_exp.data = container;
2558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->nfnl_cb_exp.attr_count = CTA_EXPECT_MAX;
2568a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfnl_callback_register(h->nfnlssh_exp,
2588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			       IPCTNL_MSG_EXP_NEW,
2598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			       &h->nfnl_cb_exp);
2608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfnl_callback_register(h->nfnlssh_exp,
2628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			       IPCTNL_MSG_EXP_DELETE,
2638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			       &h->nfnl_cb_exp);
2648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return 0;
2668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
2678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2688a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
2698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_callback_unregister2 - unregister a callback
2708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param h library handler
2718a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
2728a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfexp_callback_unregister2(struct nfct_handle *h)
2738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
2748a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(h != NULL);
2758a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2768a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfnl_callback_unregister(h->nfnlssh_exp, IPCTNL_MSG_EXP_NEW);
2778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfnl_callback_unregister(h->nfnlssh_exp, IPCTNL_MSG_EXP_DELETE);
2788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2798a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->expect_cb2 = NULL;
2808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	free(h->nfnl_cb_exp.data);
2818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->nfnl_cb_exp.call = NULL;
2838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->nfnl_cb_exp.data = NULL;
2848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	h->nfnl_cb_exp.attr_count = 0;
2858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
2868a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
2888a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @}
2898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
2908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
2928a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \defgroup exp Expect object handling
2938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @{
2948a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
2958a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
2968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
2978a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_set_attr - set the value of a certain expect attribute
2988a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param exp pointer to a valid expect
2998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute type
3008a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param value pointer to the attribute value
3018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
3028a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Note that certain attributes are unsettable:
3038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- ATTR_EXP_USE
3048a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- ATTR_EXP_ID
3058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- ATTR_EXP_*_COUNTER_*
3068a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * The call of this function for such attributes do nothing.
3078a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
3088a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfexp_set_attr(struct nf_expect *exp,
3098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		    const enum nf_expect_attr type,
3108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		    const void *value)
3118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
3128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(exp != NULL);
3138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(value != NULL);
3148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (type >= ATTR_EXP_MAX)
3168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return;
3178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (set_exp_attr_array[type]) {
3198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		set_exp_attr_array[type](exp, value);
3208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		set_bit(type, exp->set);
3218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
3228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
3238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
3258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_set_attr_u8 - set the value of a certain expect attribute
3268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param exp pointer to a valid expect
3278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute type
3288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param value unsigned 8 bits attribute value
3298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
3308a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfexp_set_attr_u8(struct nf_expect *exp,
3318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		       const enum nf_expect_attr type,
3328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		       uint8_t value)
3338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
3348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfexp_set_attr(exp, type, &value);
3358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
3368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
3388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_set_attr_u16 - set the value of a certain expect attribute
3398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param exp pointer to a valid expect
3408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute type
3418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param value unsigned 16 bits attribute value
3428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
3438a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfexp_set_attr_u16(struct nf_expect *exp,
3448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			const enum nf_expect_attr type,
3458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			uint16_t value)
3468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
3478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfexp_set_attr(exp, type, &value);
3488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
3498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
3518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_set_attr_u32 - set the value of a certain expect attribute
3528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param exp pointer to a valid expect
3538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute type
3548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param value unsigned 32 bits attribute value
3558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
3568a44513648da0c5f5551f96b329cf56b66f5b303pkanwarvoid nfexp_set_attr_u32(struct nf_expect *exp,
3578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			const enum nf_expect_attr type,
3588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			uint32_t value)
3598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
3608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfexp_set_attr(exp, type, &value);
3618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
3628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
3648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_get_attr - get an expect attribute
3658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param exp pointer to a valid expect
3668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute type
3678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
3688a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * In case of success a valid pointer to the attribute requested is returned,
3698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * on error NULL is returned and errno is set appropiately.
3708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
3718a44513648da0c5f5551f96b329cf56b66f5b303pkanwarconst void *nfexp_get_attr(const struct nf_expect *exp,
3728a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			   const enum nf_expect_attr type)
3738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
3748a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(exp != NULL);
3758a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3768a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (type >= ATTR_EXP_MAX) {
3778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		errno = EINVAL;
3788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return NULL;
3798a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
3808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (!test_bit(type, exp->set)) {
3828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		errno = ENODATA;
3838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return NULL;
3848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
3858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3868a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return get_exp_attr_array[type](exp);
3878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
3888a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
3898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
3908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_get_attr_u8 - get attribute of unsigned 8-bits long
3918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param exp pointer to a valid expectation
3928a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute type
3938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
3948a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Returns the value of the requested attribute, if the attribute is not
3958a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * set, 0 is returned. In order to check if the attribute is set or not,
3968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * use nfexp_attr_is_set.
3978a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
3988a44513648da0c5f5551f96b329cf56b66f5b303pkanwaruint8_t nfexp_get_attr_u8(const struct nf_expect *exp,
3998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			   const enum nf_expect_attr type)
4008a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
4018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	const uint8_t *ret = nfexp_get_attr(exp, type);
4028a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return ret == NULL ? 0 : *ret;
4038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
4048a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
4058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
4068a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_get_attr_u16 - get attribute of unsigned 16-bits long
4078a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param exp pointer to a valid expectation
4088a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute type
4098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
4108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Returns the value of the requested attribute, if the attribute is not
4118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * set, 0 is returned. In order to check if the attribute is set or not,
4128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * use nfexp_attr_is_set.
4138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
4148a44513648da0c5f5551f96b329cf56b66f5b303pkanwaruint16_t nfexp_get_attr_u16(const struct nf_expect *exp,
4158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			     const enum nf_expect_attr type)
4168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
4178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	const uint16_t *ret = nfexp_get_attr(exp, type);
4188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return ret == NULL ? 0 : *ret;
4198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
4208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
4218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
4228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_get_attr_u32 - get attribute of unsigned 32-bits long
4238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param exp pointer to a valid expectation
4248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute type
4258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
4268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Returns the value of the requested attribute, if the attribute is not
4278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * set, 0 is returned. In order to check if the attribute is set or not,
4288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * use nfexp_attr_is_set.
4298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
4308a44513648da0c5f5551f96b329cf56b66f5b303pkanwaruint32_t nfexp_get_attr_u32(const struct nf_expect *exp,
4318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar			    const enum nf_expect_attr type)
4328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
4338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	const uint32_t *ret = nfexp_get_attr(exp, type);
4348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return ret == NULL ? 0 : *ret;
4358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
4368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
4378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
4388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_attr_is_set - check if a certain attribute is set
4398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param exp pointer to a valid expectation object
4408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute type
4418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
4428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On error, -1 is returned and errno is set appropiately, otherwise
4438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * the value of the attribute is returned.
4448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
4458a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfexp_attr_is_set(const struct nf_expect *exp,
4468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		      const enum nf_expect_attr type)
4478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
4488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(exp != NULL);
4498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
4508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (type >= ATTR_EXP_MAX) {
4518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		errno = EINVAL;
4528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return -1;
4538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
4548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return test_bit(type, exp->set);
4558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
4568a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
4578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
4588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_attr_unset - unset a certain attribute
4598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type attribute type
4608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param exp pointer to a valid expectation object
4618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
4628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On error, -1 is returned and errno is set appropiately, otherwise
4638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 0 is returned.
4648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
4658a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfexp_attr_unset(struct nf_expect *exp,
4668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		     const enum nf_expect_attr type)
4678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
4688a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(exp != NULL);
4698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
4708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (type >= ATTR_EXP_MAX) {
4718a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		errno = EINVAL;
4728a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return -1;
4738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
4748a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	unset_bit(type, exp->set);
4758a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
4768a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return 0;
4778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
4788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
4798a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
4808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @}
4818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
4828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
4838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
4848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \defgroup nl Low level object to Netlink message
4858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @{
4868a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
4878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
4888a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
4898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_build_expect - build a netlink message from a conntrack object
4908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ssh nfnetlink subsystem handler
4918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param req buffer used to build the netlink message
4928a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param size size of the buffer passed
4938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type netlink message type
4948a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param flags netlink flags
4958a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param exp pointer to a conntrack object
4968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
4978a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This is a low level function for those that require to be close to
4988a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * netlink details via libnfnetlink. If you do want to obviate the netlink
4998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * details then we suggest you to use nfexp_query.
5008a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
5018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On error, -1 is returned and errno is appropiately set.
5028a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On success, 0 is returned.
5038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
5048a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfexp_build_expect(struct nfnl_subsys_handle *ssh,
5058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		       void *req,
5068a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		       size_t size,
5078a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		       uint16_t type,
5088a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		       uint16_t flags,
5098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		       const struct nf_expect *exp)
5108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
5118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ssh != NULL);
5128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(req != NULL);
5138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(exp != NULL);
5148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
5158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return __build_expect(ssh, req, size, type, flags, exp);
5168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
5178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
5188a44513648da0c5f5551f96b329cf56b66f5b303pkanwarstatic int
5198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar__build_query_exp(struct nfnl_subsys_handle *ssh,
5208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		  const enum nf_conntrack_query qt,
5218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		  const void *data, void *buffer, unsigned int size)
5228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
5238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	struct nfnlhdr *req = buffer;
5248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	const uint8_t *family = data;
5258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
5268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(ssh != NULL);
5278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(data != NULL);
5288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(req != NULL);
5298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
5308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	memset(req, 0, size);
5318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
5328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	switch(qt) {
5338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	case NFCT_Q_CREATE:
5348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		__build_expect(ssh, req, size, IPCTNL_MSG_EXP_NEW, NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK|NLM_F_EXCL, data);
5358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		break;
5368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	case NFCT_Q_CREATE_UPDATE:
5378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		__build_expect(ssh, req, size, IPCTNL_MSG_EXP_NEW, NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK, data);
5388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		break;
5398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	case NFCT_Q_GET:
5408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		__build_expect(ssh, req, size, IPCTNL_MSG_EXP_GET, NLM_F_REQUEST|NLM_F_ACK, data);
5418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		break;
5428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	case NFCT_Q_DESTROY:
5438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		__build_expect(ssh, req, size, IPCTNL_MSG_EXP_DELETE, NLM_F_REQUEST|NLM_F_ACK, data);
5448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		break;
5458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	case NFCT_Q_FLUSH:
5468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		nfnl_fill_hdr(ssh, &req->nlh, 0, *family, 0, IPCTNL_MSG_EXP_DELETE, NLM_F_REQUEST|NLM_F_ACK);
5478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		break;
5488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	case NFCT_Q_DUMP:
5498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		nfnl_fill_hdr(ssh, &req->nlh, 0, *family, 0, IPCTNL_MSG_EXP_GET, NLM_F_REQUEST|NLM_F_DUMP);
5508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		break;
5518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	default:
5528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		errno = ENOTSUP;
5538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return -1;
5548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
5558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return 1;
5568a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
5578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
5588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
5598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_build_query - build a query in netlink message format for ctnetlink
5608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param ssh nfnetlink subsystem handler
5618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param qt query type
5628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param data data required to build the query
5638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param req buffer to build the netlink message
5648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param size size of the buffer passed
5658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
5668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This is a low level function, use it if you want to require to work
5678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * with netlink details via libnfnetlink, otherwise we suggest you to
5688a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * use nfexp_query.
5698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
5708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * The pointer to data can be a conntrack object or the protocol family
5718a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * depending on the request.
5728a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
5738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * For query types:
5748a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	NFEXP_Q_CREATE
5758a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	NFEXP_Q_DESTROY
5768a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
5778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Pass a valid pointer to an expectation object.
5788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
5798a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * For query types:
5808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	NFEXP_Q_FLUSH
5818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	NFEXP_Q_DUMP
5828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
5838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Pass a valid pointer to the protocol family (uint8_t)
5848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
5858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On success, 0 is returned. On error, -1 is returned and errno is set
5868a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * appropiately.
5878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
5888a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfexp_build_query(struct nfnl_subsys_handle *ssh,
5898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		      const enum nf_conntrack_query qt,
5908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		      const void *data,
5918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		      void *buffer,
5928a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		      unsigned int size)
5938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
5948a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return __build_query_exp(ssh, qt, data, buffer, size);
5958a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
5968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
5978a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
5988a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_parse_expect - translate a netlink message to a conntrack object
5998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param type do the translation iif the message type is of a certain type
6008a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param nlh pointer to the netlink message
6018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param exp pointer to the conntrack object
6028a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
6038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This is a low level function, use it in case that you require to work
6048a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * with netlink details via libnfnetlink. Otherwise, we suggest you to
6058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * use the high level API.
6068a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
6078a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * The message types are:
6088a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
6098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * NFEXP_T_NEW: parse messages with new conntracks
6108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * NFEXP_T_UPDATE: parse messages with conntrack updates
6118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * NFEXP_T_DESTROY: parse messages with conntrack destroy
6128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * NFEXP_T_ALL: all message types
6138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
6148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * The message type is a flag, therefore the can be combined, ie.
6158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * NFEXP_T_NEW | NFEXP_T_DESTROY to parse only new and destroy messages
6168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
6178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On error, NFEXP_T_ERROR is returned and errno is set appropiately. If
6188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * the message received is not of the requested type then 0 is returned,
6198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * otherwise this function returns the message type parsed.
6208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
6218a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfexp_parse_expect(enum nf_conntrack_msg_type type,
6228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		       const struct nlmsghdr *nlh,
6238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		       struct nf_expect *exp)
6248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
6258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	unsigned int flags;
6268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	int len = nlh->nlmsg_len;
6278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	struct nfgenmsg *nfhdr = NLMSG_DATA(nlh);
6288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	struct nfattr *cda[CTA_EXPECT_MAX];
6298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
6308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(nlh != NULL);
6318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(exp != NULL);
6328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
6338a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	len -= NLMSG_LENGTH(sizeof(struct nfgenmsg));
6348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (len < 0) {
6358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		errno = EINVAL;
6368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return NFCT_T_ERROR;
6378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	}
6388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
6398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	flags = __parse_expect_message_type(nlh);
6408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (!(flags & type))
6418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return 0;
6428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
6438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	nfnl_parse_attr(cda, CTA_EXPECT_MAX, NFA_DATA(nfhdr), len);
6448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
6458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	__parse_expect(nlh, cda, exp);
6468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
6478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return flags;
6488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
6498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
6508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
6518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @}
6528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
6538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
6548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
6558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \defgroup cmd Send commands to kernel-space and receive replies
6568a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @{
6578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
6588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
6598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
6608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_query - send a query to ctnetlink
6618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param h library handler
6628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param qt query type
6638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param data data required to send the query
6648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
6658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On error, -1 is returned and errno is explicitely set. On success, 0
6668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * is returned.
6678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
6688a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfexp_query(struct nfct_handle *h,
6698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	        const enum nf_conntrack_query qt,
6708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	        const void *data)
6718a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
6728a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	const size_t size = 4096;	/* enough for now */
6738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	union {
6748a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		char buffer[size];
6758a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		struct nfnlhdr req;
6768a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	} u;
6778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
6788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(h != NULL);
6798a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(data != NULL);
6808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
6818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (__build_query_exp(h->nfnlssh_exp, qt, data, &u.req, size) == -1)
6828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return -1;
6838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
6848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return nfnl_query(h->nfnlh, &u.req.nlh);
6858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
6868a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
6878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
6888a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_send - send a query to ctnetlink
6898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param h library handler
6908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param qt query type
6918a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param data data required to send the query
6928a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
6938a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Like nfexp_query but we do not wait for the reply from ctnetlink.
6948a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * You can use nfexp_send() and nfexp_catch() to emulate nfexp_query().
6958a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This is particularly useful when the socket is non-blocking.
6968a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
6978a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On error, -1 is returned and errno is explicitely set. On success, 0
6988a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * is returned.
6998a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
7008a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfexp_send(struct nfct_handle *h,
7018a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	       const enum nf_conntrack_query qt,
7028a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	       const void *data)
7038a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
7048a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	const size_t size = 4096;	/* enough for now */
7058a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	union {
7068a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		char buffer[size];
7078a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		struct nfnlhdr req;
7088a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	} u;
7098a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
7108a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(h != NULL);
7118a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(data != NULL);
7128a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
7138a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	if (__build_query_exp(h->nfnlssh_exp, qt, data, &u.req, size) == -1)
7148a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		return -1;
7158a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
7168a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return nfnl_send(h->nfnlh, &u.req.nlh);
7178a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
7188a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
7198a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
7208a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_catch - catch events
7218a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param h library handler
7228a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
7238a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * This function receives the event from the kernel and it invokes the
7248a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * callback that was registered to this handle.
7258a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
7268a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On error, -1 is returned and errno is set appropiately. On success,
7278a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * a value greater or equal to 0 is returned indicating the callback
7288a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * verdict: NFCT_CB_STOP, NFCT_CB_CONTINUE or NFCT_CB_STOLEN.
7298a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
7308a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Beware that this function is equivalent to nfct_catch(), so it handles both
7318a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * conntrack and expectation events.
7328a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
7338a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfexp_catch(struct nfct_handle *h)
7348a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
7358a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(h != NULL);
7368a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
7378a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return nfnl_catch(h->nfnlh);
7388a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
7398a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
7408a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
7418a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @}
7428a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
7438a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
7448a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
7458a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \defgroup exp Expect object handling
7468a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @{
7478a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
7488a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
7498a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
7508a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * nfexp_snprintf - print a conntrack object to a buffer
7518a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param buf buffer used to build the printable conntrack
7528a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param size size of the buffer
7538a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param exp pointer to a valid expectation object
7548a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param message_type print message type (NFEXP_T_UNKNOWN, NFEXP_T_NEW,...)
7558a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param output_type print type (NFEXP_O_DEFAULT, NFEXP_O_XML, ...)
7568a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * \param flags extra flags for the output type (NFEXP_OF_LAYER3)
7578a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
7588a44513648da0c5f5551f96b329cf56b66f5b303pkanwar  * If you are listening to events, probably you want to display the message
7598a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * type as well. In that case, set the message type parameter to any of the
7608a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * known existing types, ie. NFEXP_T_NEW, NFEXP_T_UPDATE, NFEXP_T_DESTROY.
7618a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * If you pass NFEXP_T_UNKNOWN, the message type will not be output.
7628a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
7638a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * Currently, the output available are:
7648a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFEXP_O_DEFAULT: default /proc-like output
7658a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFEXP_O_XML: XML output
7668a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
7678a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * The output flags are:
7688a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 	- NFEXP_O_LAYER: include layer 3 information in the output, this is
7698a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 			*only* required by NFEXP_O_DEFAULT.
7708a44513648da0c5f5551f96b329cf56b66f5b303pkanwar *
7718a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * On error, -1 is returned and errno is set appropiately. Otherwise,
7728a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * 0 is returned.
7738a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
7748a44513648da0c5f5551f96b329cf56b66f5b303pkanwarint nfexp_snprintf(char *buf,
7758a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		  unsigned int size,
7768a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		  const struct nf_expect *exp,
7778a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		  unsigned int msg_type,
7788a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		  unsigned int out_type,
7798a44513648da0c5f5551f96b329cf56b66f5b303pkanwar		  unsigned int flags)
7808a44513648da0c5f5551f96b329cf56b66f5b303pkanwar{
7818a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(buf != NULL);
7828a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(size > 0);
7838a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	assert(exp != NULL);
7848a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
7858a44513648da0c5f5551f96b329cf56b66f5b303pkanwar	return __snprintf_expect(buf, size, exp, msg_type, out_type, flags);
7868a44513648da0c5f5551f96b329cf56b66f5b303pkanwar}
7878a44513648da0c5f5551f96b329cf56b66f5b303pkanwar
7888a44513648da0c5f5551f96b329cf56b66f5b303pkanwar/**
7898a44513648da0c5f5551f96b329cf56b66f5b303pkanwar * @}
7908a44513648da0c5f5551f96b329cf56b66f5b303pkanwar */
791